Utiliser calc pour déterminer la hauteur de ligne optimale
Où l'on parle de la hauteur des lignes, de l'unité ex et de l'utilisation des mathématiques en CSS.
Le texte qui suit est paru dans le site de Kitty Giraudel, qui écrit : "voici un billet invité de Jesús Ricarte, développeur frontend et traducteur bénévole pour A List Apart en espagnol. Je suis très heureux qu'il nous parle aujourd'hui de la hauteur des lignes et de l'utilisation des mathématiques en CSS !"
❦
Nous pouvons appliquer n'importe quelle unité CSS à la hauteur de ligne (line-height
), cependant une valeur sans unité de 1.5
est la façon la plus recommandée de gérer cette hauteur. Pour commencer, voici une image explicative sur la façon dont la hauteur de ligne est appliquée par le navigateur :
Comme vous pouvez le constater, chaque hauteur de ligne est répartie dans différentes zones :
- Une "zone de contenu", dont la hauteur serait égale à 1.
- Une "zone d'espace", qui serait l'espace restant, réparti de manière égale en haut et en bas de la ligne. (NdT: le leading ou espacement de ligne ou interlignage.
Nous pourrions donc l'exprimer comme suit : lineHeight = leading / 2 + content + leading / 2
ou :
line-height: calc(0.25 + 1 + 0.25);
Cette approche présente toutefois un inconvénient en termes de maintenance : comme vous pouvez le constater dans la démo suivante, elle fixe une hauteur de ligne trop importante dans les grandes tailles de police. Afin d'établir une lisibilité optimale, nous devons l'ajuster manuellement à chaque incrément de font-size
, jusqu'à 1.1
pour les très grandes tailles de police.
À la recherche d'une formule
Pour y voir plus clair, jetons un coup d'œil à nos chiffres de démonstration, sur un tableau de comparaison (les valeurs de hauteur de ligne calculées sont en pixels pour une meilleure compréhension) :
line-height: 1.5 | line-height: 1.1 | |
---|---|---|
font-size: 10px | 15px | |
font-size: 50px | 55px |
Pour obtenir une hauteur de ligne optimale, nous devrons être aussi proches que possible de la valeur 1.5
(15px
), sur les petites tailles de police, mais plus proches de 1.1
(55px
) sur les grandes.
Attendez... 11px
est déjà assez proche de 15px
. Nous sommes à quelques pixels près.
Donc, au lieu de commencer sur une valeur de 1.5
, pourquoi ne pas inverser les choses ? Nous pourrions commencer à partir de 1.1
, en ajoutant juste les quelques pixels dont nous avons besoin, ce qui ne fera presque aucune différence visuelle dans les grandes tailles de police, seulement dans les petites.
Quelque chose comme :
line-height: calc(2px + 1.1 + 2px);
Révision de notre tableau de comparaison des hauteurs de ligne calculées :
LH 1.5 | LH (2px + 1.1 + 2px) | LH 1.1 | |
---|---|---|---|
font-size: 10px | 15px | 15px | |
font-size: 50px | 59px | 55px |
Voilà qui est mieux ! Nous avons réussi dans les petites tailles de police et nous en sommes assez proches dans les grandes.
Malheureusement, line-height : calc(2px + 1.1 + 2px)
n'est pas un CSS valide, puisque les valeurs avec unité et sans unité ne peuvent pas être mélangées. Pourrions-nous utiliser n'importe quelle unité relative qui est calculée à environ 1.1
?
Genre : l'unité ex
est calculée à la hauteur d'x de la police actuelle (la hauteur de la lettre minuscule "x"), donc nous trouvons simplement la correspondance parfaite pour notre formule.
En fait, toute unité relative (em
, rem
...) peut être utilisée, mais puisque nous calculons la hauteur de ligne, il est logique d'utiliser une unité de hauteur.
Comme chaque police de caractères a sa propre valeur ex
, nous devons encore affiner nos valeurs px
& ex
. Quoi qu'il en soit, considérez ceci comme un bon point de départ :
line-height: calc(2px + 2ex + 2px);
Comme vous pouvez le voir dans la démo suivante, il définit une très belle hauteur de ligne, dans un large éventail de caractères différents :
C'est du CSS valide. De plus, l'unité ex
a une très bonne compatibilité navigateur. Hourra !
Éléments descendants
Si vous appliquez la formule sur un élément parent, et que la taille de la police est modifiée sur un élément descendant, la hauteur de ligne ne sera pas affectée sur le descendant, puisqu'elle a été calculée sur la base de la taille de la police du parent :
.parent {
font-size: 20px;
line-height: calc(2px + 2ex + 2px);
/* calculé: 2px + (2 * 20px) + 2px = 44px */
}
.parent .descendant {
font-size: 40px;
/* désiré: 2px + (2 * 40px) + 2px = 84px */
/* calculé: 2px + (2 * 20px) + 2px = 44px (comme .parent) */
}
Cela peut être résolu en appliquant la formule à tous les descendants, avec le sélecteur universel :
.parent * {
line-height: calc(2px + 2ex + 2px);
}
De la typographie responsive
Notre formule est également utile pour la typographie responsive. L'utilisation d'unités relatives au viewport (vw
, vh
, vmin
, vmax
) entraîne un manque de contrôle fin, de sorte que nous ne pouvons pas modifier la hauteur de ligne à chaque changement de taille de police.
Ce problème a également été abordé par la technique des verrous CSS, qui utilise une arithmétique relativement complexe pour établir une hauteur de ligne minimale et maximale. NdT : Depuis la publication, en 2016, de l'article de Florens Verschelde en lien ci-dessus, CSS a gagné une nouvelle capacité qui remplace une grande partie de l'astuce de cet article : la fonction clamp()
.
La Cascade utilise :
body {
line-height: calc(1em + 0.5rem);
}