Le problème de l'alignement vertical en CSS est enfin résolu : text-box-trim et margin-block

Le problème de l'alignement vertical en CSS est enfin résolu : text-box-trim et margin-block

lschvn7 min de lecture

Ouvrez un bouton dans l'inspecteur de votre navigateur. Ajoutez du padding. Le texte semble centré. Ajoutez davantage de padding, ou changez de police. Soudain, il est décalé de 4 pixels. Ce n'est pas un bug dans votre CSS. C'est une inadéquation fondamentale entre la manière dont les navigateurs mesurent le texte et celle dont les êtres humains le perçoivent.

Le problème: L'interlignage

Pour comprendre pourquoi le texte ne scentre jamais tout à fait, il faut comprendre ce que les navigateurs mesurent réellement. Chaque police possède un ensemble de métriques : la hauteur des capitales (la hauteur des lettres majuscules), la ligne de base (sur laquelle reposent les lettres), l'ascendante (distance entre la ligne de base et le sommet des lettres hautes) et la descendante (distance sous la ligne de base). Ces métriques définissent le carré em, la zone invisible qui contient chaque glyphe.

Mais il y a un piège. Lorsque vous définissez line-height: 1.5 sur un texte de 16px, le navigateur alloue 24px d'espace vertical. Le texte visuel réel, les lettres elles-mêmes, n'occupent qu'environ 11px dans le centre vertical de cette zone de 24px. L'espace restant s'appelle l'interlignage : un padding invisible distribué au-dessus de la hauteur des capitales et sous la ligne de base.

Les navigateurs alignent le texte sur cette zone de line-height, et non sur les lettres visuelles. Voilà pourquoi le texte d'un bouton semble toujours se trouver dans la moitié inférieure de son conteneur, même avec display: flex; align-items: center. La zone de line-height s'étend plus haut au-dessus de la hauteur des capitales qu'elle ne descend sous la ligne de base, de sorte que le centre visuel des lettres se situe bien en dessous du centre géométrique de l'espace alloué.

Cette inadéquation affecte chaque conteneur de texte étroit : boutons, badges, éléments de navigation, champs de saisie. Vous pouvez ajouter tout le padding souhaité, tant que vous n'adressez pas l'interlignage, le texte ne sera jamais vraiment centré.

Solution 1: text-box-trim

La spécification CSS Text Level 4 introduit text-box-trim, une propriété qui permet de supprimer directement l'interlignage du texte en ligne. La propriété accepte trois valeurs : trim-start supprime l'espace au-dessus du texte, trim-end supprime l'espace en dessous, et trim-both supprime les deux.

Pour contrôler précisément quelle partie de la métrique de la police est rogée, associez-la avec text-box-edge. Cette propriété accepte des valeurs comme cap, alphabetic, ex et text, chacune représentant une mesure différente dans le carré em de la police.

Pour l'ajustement vertical le plus étroit, utilisez text-box-edge: cap alphabetic combiné avec text-box-trim: trim-both. Cela indique au navigateur de rogner depuis la hauteur des capitales jusqu'à la ligne de base alphabétique, supprimant tout l'interlignage au-dessus et en dessous des lettres visibles.

.button-text {
  text-box-edge: cap alphabetic;
  text-box-trim: trim-both;
}

La compatibilité avec les navigateurs est actuellement limitée aux versions les plus récentes. Cela fait de text-box-trim une amélioration progressive idéale : vous l'appliquez pour les navigateurs qui la supportent tout en maintenant un fallback pour les autres.

Solution 2: margin-block

Si vous avez besoin de code fonctionnel aujourd'hui, margin-block avec des unités relatives à la police délivre le même résultat avec une excellente compatibilité navigateurs. La technique utilise deux unités CSS moins connues : cap, qui équivaut à la hauteur des capitales de la police actuelle, et lh, qui équivaut à la valeur calculée de line-height.

La formule est élégante :

.button-text {
  margin-block: calc(0.5cap - 0.5lh);
}

Cela produit une marge négative qui compense la zone de line-height par rapport à la hauteur des capitales. La moitié de la hauteur des capitales moins la moitié du line-height donne exactement la distance nécessaire pour tirer le texte visuel vers le centre de son espace alloué. Comme cap et lh s'échelonnent tous deux avec la police, cela fonctionne correctement quelle que soit la taille ou la famille de police.

Pour une police de 16px avec line-height: 1.5 (24px), le calcul produit environ -4px. Cette marge négative soulève le texte visuel vers le centre géométrique. Le résultat est le même ajustement précis et serré que celui fourni par text-box-trim, mais disponible dans chaque navigateur moderne dès aujourd'hui.

Motif d'amélioration progressive

L'approche judicieuse combine les deux techniques : commencez par margin-block comme base, puis enrichissez avec text-box-trim là où c'est supporté. La clé consiste à utiliser @supports pour détecter le support de text-box-trim et annuler le margin-block à l'intérieur de ce bloc.

.button-text {
  /* Base : fonctionne partout */
  margin-block: calc(0.5cap - 0.5lh);
}

/* Amélioration : utiliser text-box-trim lorsqu'il est disponible */
@supports (text-box-trim: trim-both) {
  .button-text {
    text-box-edge: cap alphabetic;
    text-box-trim: trim-both;
    margin-block: 0;
  }
}

Ce motif garantit que chaque navigateur obtient un alignement textuel correct. Les navigateurs plus anciens obtiennent la solution margin-block. Les navigateurs à la pointe obtiennent l'approche native text-box-trim. Aucun navigateur n'obtient un double ajustement ni une mise en page cassée.

Cas d'utilisation réels

Texte de bouton : Appliquez margin-block: calc(0.5cap - 0.5lh) à l'élément texte du bouton tandis que le bouton lui-même utilise display: inline-flex; align-items: center. Cela vous donne un texte de bouton parfaitement centré qui tient lorsque vous changez de police ou ajustez le padding.

Badges et pilules : Les conteneurs à padding serré révèlent l'inadéquation instantanément. Ajoutez margin-block au texte du badge et regardez l'étiquette s'aligner au centre géométrique, même avec un padding asymétrique.

Titres hero : Le texte d'affichage de grande taille rend même de minuscules inadéquations évidentes. margin-block sur un titre de 72px avec line-height: 1.1 délivre l'alignement au pixel près que les designs premium exigent.

Icône + texte : Lors de l'appairage d'une icône avec du texte en utilisant display: flex; align-items: center, ajouter margin-block à l'élément texte garantit que l'icône et les lettres partagent la même ligne de base visuelle, même lorsque leurs métriques internes diffèrent.

Le texte a toujours été légèrement décalé au centre en CSS, non pas à cause de bugs, mais à cause de la manière dont les navigateurs mesurent l'espace. Avec margin-block disponible aujourd'hui et text-box-trim arrivant bientôt, cette époque est finalement révolue.

Questions fréquentes

Articles connexes

Plus de couverture avec des sujets et tags en commun.

Rolldown 1.1.4 Désactive `experimental.lazyBarrel` par Défaut, un Mois Après que 1.1.0 l'Ait Activé
javascript

Rolldown 1.1.4 Désactive `experimental.lazyBarrel` par Défaut, un Mois Après que 1.1.0 l'Ait Activé

Rolldown [v1.1.4](https://github.com/rolldown/rolldown/releases/tag/v1.1.4), publié le 2026-07-01T14:02:02Z, embarque un changement de fonctionnalité et 19 corrections de bogues. Le changement de fonctionnalité est une annulation partielle du [bascule par défaut de la v1.1.0](https://github.com/rolldown/rolldown/releases/tag/v1.1.0) du 2026-06-03: `experimental.lazyBarrel` est à nouveau désactivé par défaut, après quatre semaines de signalements de correction sur le comportement par défaut. La release durcit aussi le chemin du mode dev en forçant `lazyBarrel` à off dès que `experimental.devMode` est défini (PR [#10060](https://github.com/rolldown/rolldown/pull/10060)), en plus du forçage existant à off pour `treeshake`. L'annulation de la bascule par défaut (PR [#10071](https://github.com/rolldown/rolldown/pull/10071)) et le fix du mode dev s'authentifient chacun en une ligne: « disable `experimental.lazyBarrel` by default » et « fix(dev): disable lazy barrel in dev mode », et le suivi de la cause racine est la nouvelle [issue #10085](https://github.com/rolldown/rolldown/issues/10085) « Tracking strictExecutionOrder correctness and architecture issues », ouverte le lendemain de la release. La release fait suite à [Rolldown v1.1.3](https://github.com/rolldown/rolldown/releases/tag/v1.1.3) (2026-06-24) et est la première release depuis 1.1.0 à toucher la surface de configuration lazyBarrel.
Prettier 3.9 refond cinq parseurs : micromark pour Markdown, yaml v2, GraphQL.js v17, un parseur Flow en Rust et Angular
javascript

Prettier 3.9 refond cinq parseurs : micromark pour Markdown, yaml v2, GraphQL.js v17, un parseur Flow en Rust et Angular

Prettier 3.9.0, publié le 27 juin 2026 (prettier/prettier, billet de Fisker Cheung), est une release centrée sur les parseurs qui fait passer Markdown de remark-parse v8 à micromark v4 (meilleure conformité CommonMark et GFM et une série de bugs de parsing de longue date corrigés), YAML à yaml v2, GraphQL à GraphQL.js v17 (arguments de fragment et directives sur les définitions de directive), Flow au nouveau parseur oxidized basé sur Rust de l'équipe Flow (environ 37 % plus rapide sur les fixtures Flow valides de Prettier et 43 % plus rapide sur flow_parser.js en benchmarks parser-only locaux) et Angular. Le formateur JavaScript et TypeScript est aussi retravaillé, en particulier en mode --no-semi où les commentaires autour de break et continue sont maintenant stables entre plusieurs passages (un fix d'idempotence), plus la suppression des parenthèses redondantes dans les return, l'alignement des interpolations de template embarquées et l'inlining des expressions de négation logique. La release retire la syntaxe legacy import ... assert {} (Babel 8 a supprimé le plugin de parseur ; migrez vers with), corrige une option --cache-strategy content silencieusement cassée et empêche les fichiers EditorConfig au-dessus des worktrees Git de s'infiltrer. L'équipe rappelle d'épingler la version exacte dans package.json car les changements de formatage vont produire des diffs.
Playwright v1.61.0 : passkeys WebAuthn, vraie API WebStorage et modes vidéo à la trace pour le test runner
javascript

Playwright v1.61.0 : passkeys WebAuthn, vraie API WebStorage et modes vidéo à la trace pour le test runner

Playwright v1.61.0 (15 juin 2026) livre un authentificateur virtuel pour les cérémonies WebAuthn/passkey, une API de première classe page.localStorage / page.sessionStorage, les détails de sécurité réseau sur les APIResponse, et aligne l'enregistrement vidéo du test runner sur l'enregistrement de trace. Canaux navigateur : Chromium 149, Firefox 151, WebKit 26.5.

Commentaires

Connexion Connectez-vous pour participer à la conversation.

Pas encore de commentaires. Soyez le premier à partager vos pensées.