enable `size-adjust` metric calculation
danielroe opened this issue · comments
Currently we can use metrics to adjust vertical height accurately. There's still a horizontal mismatch though, even if slight, and we can likely solve this by applying the right metrics to size-adjust
.
I think you can improve the horizontal mismatch, but not solve it.
Looking at the "On Font Width..." section at the bottom of this notes on calculating font metric overrides document, because the width of each character contributes a different amount to the width of the line, the size-adjust
width adjustment can only be calculated accurately if you know the specific set of characters it will apply to.
In this example, you can see how size-adjust can make the fallback font match up exactly for the configured text value, "abcdefghijklmnopqrstuvwxyz":
But for different text content, that size adjustment will no longer match so perfectly:
That is correct. As the document says:
Quantifying width has many potential variations: for example, weighting by character frequency, weighing some characters more heavily (e.g. narrow/wide characters like “i,j,m,w”), taking the average width of all glyphs (i.e. not just “abc...z”), etc. Some of these “fancier” approaches might not generalize well across languages.
Nevertheless, it offers a real improvement 😉
As far as I understand Next 13 just implemented this too 😄 https://twitter.com/Una/status/1584967596847542272
Wish it was not coupled to Next and a separate project though
This is fundamentally an awesome idea. My bet is that in the long run, what fontaine and Next are doing becomes native browser functionality in some way
FYI - For anyone who cares about the CLS core web vital on mobile, size-adjust
does not work on Chrome for Android. A bug for it is filed in the link below.
https://bugs.chromium.org/p/chromium/issues/detail?id=1370818
I use Malte Ubl's tool here to get my size-adjust calculations: https://www.industrialempathy.com/perfect-ish-font-fallback/. Source code here: https://www.industrialempathy.com/perfect-ish-font-fallback/font.js (NOTE: not open source, likely copyrighted).
I admittedly don't follow the logic for resizeText
, but it works wonderfully. I wonder if there's a way to use the existing font metrics from capsize
to compute something similar. Example: Fira Sans with a fallback of Arial generates this code:
/* Make a custom fallback font based on the local Arial */
@font-face {
font-family: "Fira Sans-fallback";
size-adjust: 102.59%;
src: local("Arial");
}
Metrics:
"arial": {
"familyName": "Arial",
"category": "sans-serif",
"capHeight": 1467,
"ascent": 1854,
"descent": -434,
"lineGap": 67,
"unitsPerEm": 2048,
"xHeight": 1062,
"xWidthAvg": 904
},
"firaSans": {
"familyName": "Fira Sans",
"category": "sans-serif",
"capHeight": 689,
"ascent": 935,
"descent": -265,
"lineGap": 0,
"unitsPerEm": 1000,
"xHeight": 527,
"xWidthAvg": 458
},
The size-adjust descriptor behaves in a similar fashion to the font-size-adjust property. It calculates an adjustment per font by matching ex heights.
But it's unclear what "matching ex heights" means in terms of the computations.
BTW, @danielroe, I started using size-adjust
recently on Chrome for Android and it now works. BTW, Android does not have many common web fonts, so the comparison from one custom font to a fallback font will only work if the fallback font is Roboto
or Noto Serif
implemented in #181!