w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.49k stars 662 forks source link

[css-fonts] Proposal to expose font metrics #4780

Open chriskirknielsen opened 4 years ago

chriskirknielsen commented 4 years ago

Introduction

It would be useful to expose metrics from the font that is being used by the browser.

These values would be normalised across all fonts, and not defined as an additional metadata in font files. This would insure backward compatibility with all fonts.

Use cases

Syntax

I'd like to propose a syntax similar to custom properties or environment variables that would be familiar to most authors:

font(--x-height)
font(--ascender)
font(--descender)
font(--cap-height)
/* etc. */

The double hyphen syntax could be a quoted value instead, such as font("x-height"), but maybe that should be kept for custom ident in font files.

Questions

These metrics are available with tools like Font Inspector, but are they passed along to the browser when it loads in the font? If not, I realise this proposal would not be feasible.

Limitations

I can imagine that the rise of variable fonts also means a single font can have multiple x-heights based on the different parameters, and I am not sure if this should be handled by browsers or authors.

One argument for it to be handled by browsers is that authors cannot predict a font that failed to load (unless using something like Font Face Observer to apply styles conditionally…).

Thanks for your time reading this. Please let me know if this has already been discussed, or if there is any interest in this.

SelenIT commented 4 years ago

The x-height is already exposed as the ex unit, the similar unit for the cap height (cap) has been proposed for the CSS Values and Units Level 4 (though, according to MDN, no browser has implemented it yet). AFAIK, there were numerous attempts to use other metrics as well, but the problem is that they are not reliable enough, especially across different platforms (many issues were well explained in this talk: https://twitter.com/fantasai/status/985809843545030656).

chriskirknielsen commented 4 years ago

@SelenIT I was aware of the ex unit but didn't know the cap unit was making progress… interesting! Thank you for sharing that link. While I didn't expect to be anywhere near the first to ask for this, I didn't think the situation would be this… dire. I do hope we make progress in the coming years to address this, there are so many fun things to do with typography. :)

Crissov commented 4 years ago

Also note #838 for stroke widths.

litherum commented 4 years ago
font(--x-height)

Which font does this refer to?

chriskirknielsen commented 4 years ago

Also note #838 for stroke widths.

@Crissov I could see that being quite useful as well!

font(--x-height)

Which font does this refer to?

@litherum It would target the currently-used font. I imagine that would be the best way to go about it.

Say you had a rule for paragraphs such as font-family: Source Sans Pro, Arial;, the former font loaded from Google Fonts. If the font successfully loaded, the exposed metrics would be for Source Sans Pro, but if it failed and the browser fell back to Arial, the metrics for Arial would be exposed instead.

This way, if you were providing calculations for some alignment, you would always have values that are consistent with the font, and not hardcoded based on the best-case scenario.

litherum commented 4 years ago

font-family: Source Sans Pro, Arial;

What about an element where none of the characters in it are supported by Source Sans Pro, but are supported by Arial? In such an element, you probably let want the metrics to come from Arial, since that’s what all the text is rendered with.

chriskirknielsen commented 4 years ago

font-family: Source Sans Pro, Arial;

What about an element where none of the characters in it are supported by Source Sans Pro, but are supported by Arial? In such an element, you probably let want the metrics to come from Arial, since that’s what all the text is rendered with.

This is a great question, as it poses: if the furthest fallback font is an emoji font for example, it might have vastly different sizing compared to, say, a wide fantasy-type font.

I would assume most authors would pick sensible fallbacks to keep this issue at a minimal. Additionally, this would probably gracefully degrade, but this would require testing, as I am only assuming. Not to mention CJK writing systems could trigger quite different edge cases.

faceless2 commented 4 years ago

We've already answered this question with other metrics, e.g. capheight, xheight - we use the first available font. I imagine that would apply here too. Clearly that means the values returned for generic fonts like "serif" will be pretty arbitrary, as they are for x-height. But I suspect that's not the use case the OP had in mind.

I like this proposal. Combined with https://github.com/w3c/csswg-drafts/issues/4792, I think it would give authors who are prepared to get their hands dirty with calc() the kind of fine grained control they want over text-layout quite quickly. There are lots of proposals to improve inline layout currently in progress, but almost all are going to rely on these metrics being available. So why not expose them?