Un badge placé dans une carte, elle-même placée dans une liste, peut afficher un texte étrangement plus grand ou plus petit que prévu si chaque niveau utilise em pour sa taille de police : chaque valeur se multiplie par celle du niveau au-dessus, et l'effet s'accumule sans qu'aucune règle ne semble fautive isolément.
rem a été introduite précisément pour éviter cet effet cumulatif, en donnant à toute la page une seule référence commune plutôt qu'une chaîne de références imbriquées.
Définition
em se calcule par rapport à la taille de police de l'élément lui-même quand il sert à autre chose que font-size, ou par rapport à celle du parent quand il sert justement à définir font-size. rem, l'abréviation de « root em », se calcule toujours par rapport à la taille de police de l'élément racine du document, généralement html, quelle que soit la profondeur d'imbrication.
html {
font-size: 16px; /* la référence unique de rem */
}
.carte {
padding: 1.5rem; /* toujours 24px, peu importe où la carte se trouve */
}L'effet cumulatif de em
Quand plusieurs niveaux imbriqués fixent chacun leur font-size en em, chaque valeur se multiplie par celle du parent, et non par la taille de police de la racine.
.liste {
font-size: 1.2em; /* x1.2 par rapport à son parent */
}
.liste .liste {
font-size: 1.2em; /* x1.2 par rapport à .liste, donc x1.44 au total */
}
.liste .liste .liste {
font-size: 1.2em; /* x1.2 encore, soit x1.728 au total */
}Trois niveaux de listes imbriquées, chacun tout à fait raisonnable pris isolément, produisent un texte presque deux fois plus grand que prévu au troisième niveau.
font-size elle-même, em se calcule par rapport au parent, puisque la taille de l'élément n'est pas encore connue. Sur toute autre propriété comme padding ou width, em se calcule par rapport à la taille de police déjà déterminée de l'élément lui-même, pas de son parent.rem : une seule référence, jamais d'accumulation
rem ignore complètement la profondeur d'imbrication : que l'élément soit directement sous body ou enfoui sous dix niveaux de div, 2rem vaut toujours deux fois la taille de police définie sur la racine. C'est ce qui en fait le choix par défaut recommandé pour la line-height et les échelles de font-size d'un projet.
Où em garde son intérêt
em reste pertinent quand un espacement doit rester proportionnel à la taille de police du composant qui le porte, et non à celle de toute la page. Un bouton dont le padding est écrit en em garde des proportions cohérentes si sa propre variante « grande taille » se contente d'augmenter son font-size, sans qu'il faille recalculer le padding séparément. Notre formation HTML et CSS construit ce type de composant bouton à plusieurs tailles, pour voir concrètement à quel moment em prend le relais de rem.
.bouton {
font-size: 1rem;
padding: 0.6em 1.2em; /* suit la taille du bouton, pas celle de la page */
}
.bouton--grand {
font-size: 1.25rem; /* le padding grandit automatiquement avec lui */
}Questions fréquentes
padding en em change-t-il de taille alors que je n'ai rien modifié dessus ?Parce qu'un ancêtre a changé sa propre taille de police, et que em reste relatif à la taille de police effective de l'élément qui le porte. Le padding suit alors ce changement indirect, sans qu'aucune règle sur le padding lui-même n'ait bougé.
rem est-il toujours préférable à em ?Non, pour la typographie et les espacements globaux, oui presque toujours. Mais pour un espacement qui doit rester proportionnel à un composant précis, comme un bouton ou un badge, em évite justement de recalculer chaque variante de taille à la main.
rem comme em suivent tous les deux ce réglage, puisqu'ils remontent finalement à la taille de police par défaut du navigateur. Un site construit en px pour son texte ignore en revanche ce réglage d'accessibilité.