Retour aux articles

Mettre en place un bouton voir plus/moins sur les paragraphe

La propriété line-clamp en CSS peut nous permettre de limiter et contrôler facilement le nombre de lignes de texte affichées dans un élément HTML. C’est pratique, mais pour aller au bout de la problématique, il aurait fallu que cela nous permette enfin de mettre en place un mécanisme ‘voir plus/moins’ sans trop de complication.

Pour faire ça en 2023, line-clamp nous simplifie bien la tâche par rapport à ce qui se faisait avant, mais on aura encore besoin de Javascript.

Solution purement CSS, sans dépliement

Si vous n’avez pas besoin de l’action ‘voir plus’, mais que vous voulez simplement contrôler le nombre de lignes visibles dans vos paragraphes avec une solution purement CSS, il n’y aura pas besoin d’aller très loin :

p.max-lines{
    --max_lines : 3;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: var(--max_lines);
    line-clamp: var(--max_lines);
    -webkit-box-orient: vertical;
}
<!-- Un paragraphe avec seulement 2 lines visibles -->
<p class="max-lines" style="--max_lines:2;" >
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Ab, cupiditate ullam sunt, eos ratione ipsa
    velit
    quaerat ad facere voluptate pariatur dolores. Incidunt adipisci, quibusdam est consequuntur accusantium
    ipsam commodi animi inventore harum officia sapiente dolore doloremque minima quos recusandae sunt
    labore
    illo vero quis dolorum ex deleniti? Explicabo, obcaecati?
</p>

Remarque : Il serait possible de trouver des solutions purement CSS pour déplier ce paragraphe, mais aucune, aujourd’hui, ne permettrai d’obtenir l’implémentation que nous souhaitons ici.

Mise en place du bouton voir plus/moins

Le CSS

Le bouton sera un élément a. Pour que celui-ci soit positionné relativement au paragraphe ( qu’il soit déplié ou non ) il faut le mettre en place à l’intérieur de celui-ci, en position absolute. Il faut également passer le paragraphe en position relative. Voici le CSS dont nous auront besoin :

p.max-lines{
    --max_lines : 3;
    position: relative;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: var(--max_lines);
    line-clamp: var(--max_lines);
    -webkit-box-orient: vertical;
}
p.max-lines>a.toggle{
    background-color: var(--body_background);
    position: absolute;
    bottom: 0;
    right: 0;
    line-height: inherit;
    padding: 0 10px;
    cursor: pointer;
}
p.max-lines>a.toggle b{
    color: var(--col_primary);
}

Le paragraphe sera ‘déplié’ en lui ajoutant la classe CSS max-lines-visible. On fait également en sorte que le bouton se réajuste bien à la fin du paragraphe en changement son attribut ‘position’.

p.max-lines.max-lines-visible{
    display: initial;
    overflow: initial;
}
p.max-lines.max-lines-visible>a.toggle{
    position: relative;
}

C’est tout ce que l’on pourra obtenir en CSS. Il faut maintenant passer au Javascript.

Mise en place du Javascript

La problématique principale est : le bouton voir plus/moins ne doit pas apparaitre si le paragraphe ne ‘déborde’ pas, c’est à dire si il a moins de lignes que son nombre maximum de lignes.

Pour évaluer cela, nous allons comparer la hauteur visible du paragraphe avec la hauteur de son contenu théoriquement scrollable. si il y a débordement, on met en place le bouton. Voici le Javascript :

const viewMoreText = '[...] <b>See more</b></a>';
const viewLessText = '<b>See less</b></a>';

document.querySelectorAll('p.max-lines').forEach( paragraph => {
    
    // On vérifie si le paragraphe 'déborder'

    var paragraphIsOverflowing = paragraph.clientHeight < paragraph.scrollHeight ? true : false;
    if( !paragraphIsOverflowing ) return;

    // si il déborde, on lui construit un lien voir plus/moins

    var theToggleLink = document.createElement('A');
    theToggleLink.classList.add( 'toggle' );
    theToggleLink.innerHTML = viewMoreText;

    // mécanisme lorsque l'on clique sur le bouton

    theToggleLink.onclick = () =>{
        if( paragraph.classList.contains( 'max-lines-visible' ) )
        {
            paragraph.classList.remove( 'max-lines-visible' );
            theToggleLink.innerHTML = viewMoreText;
            return;
        }
        paragraph.classList.add( 'max-lines-visible' );
        theToggleLink.innerHTML = viewLessText;
    }

    // On ajoute le bouton dans le paragraphe

    paragraph.append( theToggleLink );

});

Et voila ! Il n’y a plus qu’à utiliser la classe CSS max-lines sur tous les paragraphe que l’on souhaite pouvoir déplié dans notre projet.