L'interligne se mesure,
il ne s'estime pas
Le convertisseur ouvre les fichiers de police, mesure l'encre réelle de chaque glyphe employé, et refuse tout interligne sous lequel les accents percuteraient la ligne du dessus.
L'accent qui percute la ligne du dessus
Sur un titre de deux lignes, l'accent du é peut heurter la lettre de la ligne supérieure. À l'œil, on corrige au jugé.
Le jugé se trompe — et il se trompe différemment dans chaque langue.
Offrez-vous
le déclic.
↑
l'accent du « é » percute le « z » de la ligne du dessus
Constaté sur ce site. Le jeton interligne_titres valait 0.94 pour un minimum mesuré de 1.235 : 0.295 em de chevauchement, soit 14 px sur un titre de 48 px.
Pourquoi CSS ne protège pas de cela
CSS 2.2 définit le mécanisme : « L = line-height − AD. Half the leading is added above A and the other half below D. »
Quand line-height est inférieur à la hauteur du contenu, L devient négatif : le demi-interligne est négatif et les zones de contenu de deux lignes consécutives se chevauchent.
Rien dans CSS ne rogne l'encre. Les glyphes débordent, simplement.
On mesure l'encre, pas les métriques déclarées
Une police déclare plusieurs hauteurs. Aucune ne borne l'encre réelle.
Seule la boîte englobante, glyphe par glyphe, dit la vérité.
| Métrique | Ce qu'elle est vraiment | Utilisable ? |
|---|---|---|
| sTypoAscender | métrique d'interlignage — une convention de mise en page | non |
| usWinAscent | métrique de rognage ; la spécification n'emploie que du conditionnel | non |
| head.yMax | décrit l'instance par défaut — faux dès qu'on change la graisse d'une police variable | non |
| bbox par glyphe | l'encre réellement posée | oui |
Le calcul, en une phrase
Deux lignes consécutives sont séparées de line-height em. La ligne du dessus descend jusqu'à yMin, celle du dessous monte jusqu'à yMax. Le contact est exact quand line-height = yMax − yMin. En deçà : chevauchement.
from fontTools.pens.boundsPen import BoundsPen
bp = BoundsPen(police.getGlyphSet())
police.getGlyphSet()[nom_du_glyphe].draw(bp)
_, yMin, _, yMax = bp.bounds
etendue_em = (yMax - yMin) / unitsPerEm
interligne_minimal = etendue_em + marge_optiqueOn mesure sur le jeu de caractères réellement affiché : élargir à toute la police ferait bondir le minimum à cause de glyphes jamais employés.
Les capitales accentuées exigent PLUS d'interligne
C'est le résultat le plus contre-intuitif de cette page, et il contredit une règle de métier répandue.
« Les capitales n'ont pas de descendantes, donc on peut resserrer » est faux dès qu'il y a des accents — donc faux en français et en allemand.
| Jeu de caractères | Étendue d'encre | Interligne minimal | Glyphes extrêmes |
|---|---|---|---|
| Français | 1.215 em | 1.235 | À / g |
| Allemand | 1.135 em | 1.155 | Ä / g |
| Anglais | 1.020 em | 1.040 | f / g |
Deux causes, mesurées sur Jost :
- l'accent capital est posé plus haut que l'accent bas de casse —
Émonte à 960/1000,éà 730 ; - la cédille du
Çdescend à −221 sous la ligne de base, ce qui annule l'argument « pas de descendantes ».
Bas de casse accentué : 1,020 em. Capitales accentuées : 1,206 em.
Ce que disent les guides, et ce qu'ils ne disent pas
Les recommandations publiées encadrent le texte courant :
- WCAG 2.1, SC 1.4.12 — « Line height (line spacing) to at least 1.5 times the font size ». Normatif, mais il vise les blocs de texte, pas les titres.
- Material Design 3 — display 1,12 · headline 1,25 · body 1,50.
- Butterick — 120 à 145 % pour le texte courant.
Aucune source publiée ne donne de valeur chiffrée pour les langues à diacritiques. C'est précisément le vide que la mesure comble : le 1.1 typique des titres display provoque la collision en français.
Deux contrôles, parce qu'un seul ne suffit pas
Le jeton est vérifié — mais une valeur écrite en dur dans la feuille de style contournerait le jeton.
Le moteur inspecte donc aussi le CSS produit.
TYP-001 sur le jeton
Le jeton interligne_titres vaut aujourd'hui 1.24, pour un minimum mesuré de 1.235.
Sous ce minimum, la compilation s'arrête, et le message donne le chevauchement en pixels ainsi que les deux glyphes responsables.
TYP-001 sur le CSS produit
Ce second contrôle n'est pas une redondance : il a trouvé un défaut réel que le premier ne pouvait pas voir.
.titre--accent { line-height: 1.06 } était écrit en dur dans la feuille — et c'était précisément la règle qui portait le titre fautif. Corriger le jeton n'aurait rien changé.
TYP-002 sur les fichiers
Si le dossier des polices est vide ou un fichier illisible, l'interligne minimal ne peut pas être mesuré et la règle @font-face ne peut pas être engendrée : le site se rendrait avec la police de repli, à des métriques différentes.
Le même code refuse aussi un préchargement qui désigne un fichier absent — défaut constaté, qui produisait un 404 sur chaque page.
Une police variable, deux fichiers
Le site sert 2 fichiers pour 42.8 Ko, contre 171,5 Ko auparavant.
Jost est une police Google, auto-hébergée — jamais appelée depuis les serveurs de Google.
| Fichier | Rôle |
|---|---|
| jost-latin-ext.woff2 | chargé à la demande — glyphes rares |
| jost-latin.woff2 | préchargé — français et allemand courants |
Le défaut corrigé. Huit fichiers annoncés en graisses 200/300/400/500 étaient en réalité deux fichiers copiés quatre fois — empreintes MD5 identiques, tous en graisse 400.
Le navigateur téléchargeait 171 Ko pour obtenir 43 Ko de contenu réel, et synthétisait les graisses 300 et 600 demandées par le CSS : un faux gras qui déforme les lettres. Une police variable fournit les vraies graisses de 100 à 900.
Pourquoi auto-héberger plutôt qu'appeler Google Fonts
Un appel à fonts.googleapis.com ajoute une résolution DNS et une connexion TLS vers un tiers avant le premier octet de texte.
Il expose aussi l'adresse IP du visiteur à un tiers — ce qu'un tribunal allemand a jugé contraire au RGPD en 2022.
Auto-hébergée, la police part du même domaine, sur la connexion déjà ouverte.
Les icônes : aucune bibliothèque
Audit des 39 pages produites : 0 icône SVG, 0 image d'icône, 0 bibliothèque externe. Les seuls pictogrammes sont 6 emoji de drapeau, rendus par le système d'exploitation.
Material Symbols pèserait environ 150 Ko pour remplacer zéro icône existante : un coût net sans contrepartie.
Si une icône devient nécessaire : SVG inline dans le composant — aucune requête, hérite de la couleur du texte, nette à toute résolution. Une police d'icônes ne se justifie qu'à partir de plusieurs dizaines de symboles.