La Cascade

Rechercher

Contrôler l'affichage du texte

par Will Boyd, 8 mai 2022, css, html, article original paru le 2 mai 2022 dans Codersblock

Comment gérer le retour à la ligne ou les césures ? Il y a beaucoup plus de façons qu'on ne le pense, et plein d'astuces possibles.


Nous allons voir différentes façons de contrôler (ou pas) le flux du texte sur une page Web. CSS nous offre de nombreux outils pour assurer ce flux — retour à la ligne, coupure de mots — mais nous verrons également plusieurs astuces utilisant HTML et les caractères spéciaux.

Protection de la mise en page

Normalement, le texte retourne à la ligne dès que l'opportunité se présente, c'est-à-dire aux endroits où l'on s'attend à ce que le texte s'interrompe naturellement, entre les mots ou après un trait d'union. Mais on a parfois affaire à de longues portions de texte qui ne présentent pas de possibilités de retour à la ligne, comme des mots très longs ou des URL. Cela peut entraîner toutes sortes de problèmes de mise en page. Par exemple, le texte peut déborder de son conteneur ou forcer le conteneur à devenir trop large et pousser des éléments hors de leur place.

Un bon codage défensif consiste à anticiper les problèmes liés à l'absence de rupture explicite du texte, et CSS nous fournit quelques outils à cet effet.

Faire en sorte que le texte retourne à la ligne

En plaçant overflow-wrap : break-word sur un élément, le texte pourra être interrompu au milieu du mot si nécessaire. L'algorithme essaiera d'abord de garder un mot intact en le déplaçant à la ligne suivante, mais il coupera le mot s'il n'y a toujours pas assez de place.

voir overflow-wrap: break-word de Will Boyd dans CodePen

Il y a également overflow-wrap : anywhere, qui coupe les mots de la même manière. La différence réside dans la façon dont il affecte le calcul de la taille du contenu minimal de l'élément sur lequel il se trouve. L'effet est assez évident quand on fixe la largeur à min-content :

.top {
  width: min-content;
  overflow-wrap: break-word;
}

.bottom {
  width: min-content;
  overflow-wrap: anywhere;
}
voir overflow-wrap + min-content de Will Boyd dans CodePen

Le premier élément avec overflow-wrap : break-word calcule le contenu minimal comme si aucun mot n'était coupé, de sorte que sa largeur devient la largeur du mot le plus long. L'élément du bas avec overflow-wrap : anywhere calcule le contenu minimal avec toutes les coupures qu'il peut créer. Vu qu'une coupure peut se produire n'importe où, le contenu minimal correspond à la largeur d'un seul caractère.

N'oubliez pas que ce comportement ne se produit que lorsque min-content est impliqué. Si nous avions donné une valeur fixe à la largeur, nous verrions le même résultat de coupure de mots dans les deux cas de figure.

Couper les mots sans pitié

Une autre option pour créer une césure est word-break: break-all. Celle-ci n'essaiera même pas de garder les mots entiers — elle les coupera immédiatement. Voici ce que ça donne :

voir word-break: break-all de Will Boyd dans CodePen

Remarquez comment le mot long n'est pas déplacé à la ligne suivante, comme il l'aurait été en utilisant overflow. Remarquez aussi comment "words" est coupé, même s'il aurait pu être placé sur la ligne suivante.

word-break : break-all n'a aucun problème à couper les mots, mais il reste toujours prudent avec la ponctuation. Par exemple, il évitera de commencer une ligne avec le point de la fin d'une phrase. Si vous voulez une rupture vraiment impitoyable, même avec la ponctuation, utilisez line-break : anywhere.

Vous avez vu comment word-break : break-all déplace le "k" vers le bas pour éviter de commencer la deuxième ligne avec "." ? Mais line-break : anywhere , lui, s'en moque.

Ponctuation excessive

Voyons comment les propriétés CSS que nous avons abordées jusqu'à présent traitent les signes de ponctuation excessivement longs.

voir Ponctuation excessive de Will Boyd dans CodePen

overflow-wrap : break-word et line-break : anywhere sont capables de contenir les choses, mais il y a ensuite word-break : break-all qui est de nouveau bizarre avec la ponctuation — cette fois-ci, le résultat est un texte qui déborde.

C'est une chose à garder à l'esprit. Si vous ne voulez absolument pas que le texte déborde, sachez que word-break : break-all n'empêchera pas la ponctuation de dépasser.

Spécifier où les mots peuvent être coupés

Pour plus de contrôle, vous pouvez insérer manuellement des possibilités de coupure de mots dans votre texte avec <wbr>. Vous pouvez également utiliser un "espace de largeur nulle", fourni par l'entité HTML &ZeroWidthSpace; (oui, il faut des majuscules comme vous le voyez !).

Voyons ces éléments en action avec une longue URL qui ne serait normalement pas retournée à la ligne, en insérant des césures entre les segments.

  <!-- normal -->
  <p>https://subdomain.somewhere.co.uk</p>

  <!-- <wbr> -->
  <p>https://subdomain<wbr>.somewhere<wbr>.co<wbr>.uk</p>

  <!-- &ZeroWidthSpace; -->
  <p>https://subdomain&ZeroWidthSpace;.somewhere&ZeroWidthSpace;.co&ZeroWidthSpace;.uk</p>

Trait d'union automatique

Vous pouvez demander au navigateur de couper les mots avec un trait d'union lorsque nécessaire en utilisant l'option hyphens: auto. Les règles de césure sont déterminées par la langue. Vous devez donc indiquer au navigateur la langue à utiliser. Pour ce faire, vous devez spécifier l'attribut lang dans le HTML, soit directement dans l'élément concerné, soit dans la balise <html>.

<p lang="en">This is just a bit of arbitrary text to show hyphenation in action.</p>
  p {
    -webkit-hyphens: auto; /* pour Safari */
    hyphens: auto;
  }
voir hyphens: auto de Will Boyd dans CodePen

Trait d'union manuel

Vous pouvez également prendre les choses en main et insérer un "tiret doux" manuellement avec l'entité HTML &shy;. Il ne sera pas visible, à moins que le navigateur ne décide de l'insérer, auquel cas un trait d'union apparaîtra. Remarquez dans la démo suivante que nous utilisons deux fois l'entité &shy; mais qu'elle n'apparaît qu'une seule fois, là où le texte doit effectivement retourner à la ligne.

<p lang="en">Magic? Abraca&shy;dabra? Abraca&shy;dabra!</p>
voir Trait d'union doux de Will Boyd dans CodePen

hyphens doit être réglé sur auto ou manual pour que &shy; s'affiche correctement. Par commodité, la valeur par défaut est hyphens : manual, ce qui devrait vous permettre de vous passer de tout CSS supplémentaire (à moins que quelque chose quelque part n'ait déclaré hyphens : none pour une raison quelconque).

Empêcher le texte de revenir à la ligne

Changeons de sujet. Il peut arriver que vous ne souhaitiez pas que le texte retourne librement à la ligne, afin de mieux contrôler la façon dont votre contenu est présenté. Il existe quelques outils pour vous aider.

Le premier est white-space : nowrap. Placez-le sur un élément pour empêcher son texte de revenir à la ligne naturellement.

voir white-space: nowrap de Will Boyd dans CodePen

Préformater le texte

Il existe également la fonction white-space : pre, qui permet d'afficher un retour à la ligne du texte tel que vous l'avez saisi dans votre HTML. Prenez garde toutefois, car il conservera également les espaces de votre HTML, donc faites attention à votre formatage. Vous pouvez également utiliser une balise <pre> pour obtenir les mêmes résultats (elle comporte un white-space : pre par défaut).

<!-- le formatage de ce HTML a pour conséquence un espace blanc supplémentaire -->
<p>
  What's worse, ignorance or apathy?
  I don't know and I don't care.
</p>

<!-- un formatage plus serré qui "embrasse" le texte -->
<p>What's worse, ignorance or apathy?
I don't know and I don't care.</p>

<!-- comme ci-dessus, mais avec <pre> -->
<pre>What's worse, ignorance or apathy?
I don't know and I don't care.</pre>
p {
  white-space: pre;
}

pre {
  /* <pre> sets font-family: monospace, but we can undo that */
  font-family: inherit;
}
voir Texte préformaté de Will Boyd dans CodePen

Un retour à la ligne dans un insécable ?

Pour les sauts de ligne, vous pouvez utiliser <br> à l'intérieur d'un élément avec white-space: nowrap ou white-space: pre. Le texte retournera à la ligne.

Mais que se passe-t-il si vous utilisez <wbr> dans un tel élément ? C'est une question piège… parce que les navigateurs ne sont pas d'accord ! Chrome/Edge reconnaîtra le <wbr> et retournera à la ligne potentiellement, mais pas Firefox/Safari.

En ce qui concerne l'espace de largeur nulle &ZeroWidthSpace;, les navigateurs sont cohérents. Aucun ne renverra à la ligne avec white-space: nowrap ou white-space: pre.

<p>Darth Vader: Nooooooooooooo<br>oooo!</p>

<p>Darth Vader: Nooooooooooooo<wbr>oooo!</p>

<p>Darth Vader: Nooooooooooooo&ZeroWidthSpace;oooo!</p>

Espaces insécables

Parfois, vous souhaiterez peut-être que le texte retourne librement à la ligne, sauf à des endroits très spécifiques. Bonne nouvelle ! Il existe quelques entités HTML spécialisées qui vous permettent de faire exactement cela.

Un "espace insécable" (&nbsp;) est souvent utilisé pour conserver un espace entre les mots, mais n'autorise pas de saut de ligne entre eux (ils forment alors un tout insécable).

<p>Something I've noticed is designers don't seem to like orphans.</p>

<p>Something I've noticed is designers don't seem to like&nbsp;orphans.</p>
voir Espaces insécables de Will Boyd dans CodePen

👉🏽 NdT : un exemple courant (et recommandé) d'utilisation de l'espace insécable est l'espace précédant un signe de ponctuation, par exemple un point d'exclamation ! ou le suivant, par exemple : — un tiret cadratin. Nous ne contrôlons pas la largeur des écrans de nos utilisateurs, l'espace insécable évite les signes de ponctuation orphelins en début ou en fin de ligne.

Jointures de mots et traits d'union insécables

Un texte peut retourner naturellement à la ligne même sans espaces, par exemple après un trait d'union à l'intérieur d'un mot. Pour empêcher le retour à la ligne, vous pouvez utiliser &NoBreak; (sensible à la casse !) qui agit comme un "agrégateur de mots". Pour les traits d'union en particulier, vous pouvez obtenir un "trait d'union insécable" avec &#8209; (il n'a pas de joli nom d'entité HTML).

  <p>Turn right here to get on I-85.</p>

  <p>Turn right here to get on I-&NoBreak;85.</p>

  <p>Turn right here to get on I&#8209;85.</p>

Texte CJC et mots de rupture

Le texte CJC (chinois/japonais/coréen) se comporte à certains égards différemment du texte non CJC. Certaines propriétés et valeurs CSS peuvent être utilisées pour un contrôle supplémentaire du retour à la ligne du texte CJC spécifiquement.

Le comportement par défaut du navigateur permet de couper des mots dans le texte CJC. Cela signifie que word-break: normal (par défaut) et word-break: break-all vous donneront les mêmes résultats. Cependant, vous pouvez utiliser word-break: keep-all pour empêcher le texte CJC de revenir à la ligne au milieu des mots (le texte non CJC ne sera pas affecté).

Voici un exemple en coréen. Notez comment le mot "자랑스럽게" se coupe ou ne se coupe pas.

voir CJK Text + word-break de Will Boyd dans CodePen

Attention toutefois, le chinois et le japonais n'utilisent pas d'espaces entre les mots comme le fait le coréen, donc word-break: keep-all peut facilement provoquer un long débordement de texte s'il n'est pas géré autrement.

Texte CJC et règles de saut de ligne

Nous avons parlé de line-break: anywhere tout à l'heure avec du texte non CJC et du fait qu'il n'a aucun problème à couper à la ponctuation. Il en va de même avec le texte CJC.

Voici un exemple en japonais. Notez comment "。" est ou n'est pas autorisé à commencer une ligne.

voir CJK Text + line-break de Will Boyd dans CodePen

Il existe d'autres valeurs pour line-break qui affectent la façon dont le texte CJC retourne à la ligne : loose, normal et strict. Ces valeurs indiquent au navigateur les règles à utiliser pour décider où insérer des sauts de ligne. Le W3C décrit plusieurs règles et il est également possible pour les navigateurs d'ajouter leurs propres règles.

À mentionner : Débordement d'élément

La propriété CSS overflow n'est pas spécifique au texte, mais est souvent utilisée pour s'assurer que le texte ne s'affiche pas en dehors d'un élément dont la largeur ou la hauteur est délimitée.

.top {
  white-space: nowrap;
  overflow: auto;
}

.bottom {
  white-space: nowrap;
  overflow: hidden;
}
voir Element Overflow de Will Boyd dans CodePen

Comme vous pouvez le voir, une valeur auto permet de faire défiler le contenu (auto n'affiche les barres de défilement qu'en cas de besoin, scroll les affiche toujours). Une valeur de hidden coupe simplement le contenu et en reste là.

overflow est en fait un raccourci pour définir à la fois overflow-x et overflow-y, respectivement pour le débordement horizontal et vertical. N'hésitez pas à utiliser ce qui vous convient le mieux.

Nous pouvons compléter overflow: hidden en ajoutant text-overflow: ellipsis. Le texte sera toujours coupé, mais nous aurons de jolis points de suspension à titre indicatif.

p {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
voir text-overflow: ellipsis de Will Boyd dans CodePen

Astuce bonus : saut de ligne en pseudo-élément

Vous pouvez forcer un saut de ligne avant et/ou après un élément ìnline, tout en le gardant comme élément inline`, avec une astuce de pseudo-élément.

Tout d'abord, définissez le content d'un pseudo-élément ::before ou ::after sur '\A', ce qui vous donnera le caractère de nouvelle ligne. Ensuite, définissez white-space: pre pour vous assurer que le caractère de nouvelle ligne est respecté.

<p>Things that go <span>bump</span> in the night.</p>
span {
  background-color: #000;
}

span::before, span::after {
  content: '\A';
  white-space: pre;
}
voir Pseudo-Element Line Breaks de Will Boyd dans CodePen

Nous aurions pu simplement mettre display: block sur le <span> pour obtenir les mêmes retours à la ligne, mais il ne serait plus inline. Le background-color permet de voir facilement qu'avec cette méthode, nous avons toujours un élément inline.

Notes bonus

  • Il existe une ancienne propriété CSS nommée word-wrap. Elle n'est pas standard et les navigateurs la traitent désormais comme un alias pour overflow-wrap.
  • La propriété CSS white-space a d'autres valeurs que nous n'avons pas couvertes : pre-wrap, pre-line et break-spaces. Contrairement à celles que nous avons couvertes, celles-ci n'empêchent pas le retour à la ligne du texte.
  • La spécification CSS Text Module Level 4 décrit une propriété CSS text-wrap qui semble intéressante, mais au moment de la rédaction, aucun navigateur ne l'implémente.

Il est temps de conclure

Il y a tellement de choses à dire à propos du texte fluide sur une page Web. La plupart du temps, vous n'avez pas vraiment besoin d'y penser, car les navigateurs le gèrent pour vous. Si vous avez besoin de plus de contrôle, il est bon de savoir que vous avez beaucoup d'options.

Écrire cet article a définitivement été un puits sans fond pour moi car je trouvais à chaque fois plus de choses à raconter. J'espère que je vous en ai montré assez pour que votre texte se coupe et s'écoule comme vous le souhaitez.

Merci d'avoir lu !

Voir la liste des articles de Will Boyd traduits dans La Cascade.
Article original paru le 2 mai 2022 dans Codersblock
Traduit avec l'aimable autorisation de Codersblock et de Will Boyd.
Copyright Codersblock © 2022