w3c / csswg-drafts

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

[css-values] Proposal: `sp` and `rsp` space glyph units #10534

Open jbasoo opened 3 months ago

jbasoo commented 3 months ago

Background

There is currently no reliable way of knowing the advance measure of a space glyph. It can be estimated using ch unit, however this is not very precise and will change depending on whichever font from the stack is being rendered. An sp unit would improve ergonomics and could potentially open up new design possibilities, as outlined in the "Use Cases" section. Given that glyph metric units already exist (ex, ch), perhaps some of the technical details for this proposal have already been implemented.

Proposal

Add sp and rsp units which represent the advance measure of the space (U+0020) glyph. It may be desirable to follow the same logic as the ch unit spec, including fallbacks where it is impossible or impractical to determine the measure of the space glyph.

Use Cases

Initial exploration of these uses can be found on Codepen.

Questions & Concerns

Crissov commented 3 months ago

Especially but not only within justified alignment, the actual width of inter-word spaces is flexible. That seems to make sp less usable than ch.

jbasoo commented 2 months ago

Especially but not only within justified alignment, the actual width of inter-word spaces is flexible. That seems to make sp less usable than ch.

@Crissov Good to know, how is the width calculated? Is the U+0020 character fully flexible in each instance or do browsers sometimes choose different space characters?

jfkthame commented 2 months ago

I don't think justification would be relevant here; an sp unit would simply be based on the default advance of the space character of the first available font. It would be unaffected by things like kerning, letter-spacing, justification, contextual alternate glyphs, etc.

Whether a new unit is actually useful enough to justify its existence is unclear to me... in most cases, it seems like ch is equally usable, and I think examples such as

Accurately increase word spacing word-spacing: 1sp; Accurately remove word spacing word-spacing: -1sp;

might be better addressed by allowing word-spacing to accept percentage values, which would resolve against the default word spacing.

jfkthame commented 2 months ago

Regarding

While adding space glyph advance measure unit could be helpful, does this open the door to requests for units for other glyphs? If so, should an additional function to return the advance measure of any glyph be explored?

I'd be pretty hesitant to start down this road. We'd have to either decide what fallback value to use if the requested character isn't supported by the first available font (and if we're using fallbacks, the point of measuring specific characters may be largely defeated), or else deal with the issue that every character might resolve to a different font resource, depending on character coverage/unicode-range usage. Yes, the browser already has to deal with this when rendering text, but I don't think all that complexity should be pushed down into the definition of a CSS unit.

(We already have to deal with this for two specific characters to support the ch and ic units, which are defined in terms of "the font used to render it" rather than "the first available font". But let's not open this up to the entire Unicode space of a million codepoints just to resolve CSS units. If a page really wants to measure arbitrary characters, there are ways it can do so through JS.)

jfkthame commented 2 months ago

Related issue with some earlier discussion: #3232.

nicksherman commented 2 months ago

should an additional function to return the advance measure of any glyph be explored?

A potential problem here is that the CSS text is only referencing abstract characters, not specific glyphs (there is no way to directly reference specific glyphs in CSS, you only access them indirectly through combinations of characters, fonts, font features, etc). While in many cases it is a simple relationship where only 1 glyph represents 1 character, that is definitely not always true.

But if you did make a space unit for any arbitrary character based on the current font and text shaping situation (as with the ch unit), and you’re going to allow for more complex mapping, why stop at one character and not allow multi-character text strings?

jbasoo commented 2 months ago

@jfkthame Thanks for the previous discussion reference. Percentage-based word-spacing sounds like a nice way to solve that particular use case.

The word/letter-spacing examples came up as I was exploring other potential use cases, however the initial scenario that prompted the proposal was usage of 0.Xch as a rough space measure for gap in flex/grid contexts when placing an icon next to text, such as on a button or in a tag list. It occurred to me that if the font rendered is not what the author expects then an estimated ch value would probably be a bit off. Like you said about the ch and ic units, the value should be defined in terms of "the font used to render it." Considering network speeds and user preferences affect the rendered font, authoring a ch estimate according to one font but the user potentially seeing another carries some risk.

Personally I only use JS as a last resort when it comes to layout, as it can be fragile, so I just use an approximate ch at the moment.

jbasoo commented 2 months ago

While in many cases it is a simple relationship where only 1 glyph represents 1 character, that is definitely not always true.

@nicksherman That certainly would make things more difficult. Does ch already take the entire text shaping situation into account?

why stop at one character and not allow multi-character text strings?

That's the slippery slope I thought might happen. The ch unit prompted me to think that a space unit might be possible, then people might want units for other characters at which point a generic function would be more desirable, and then multi-character strings could be called for. It could open up some interesting possibilities but there's not much call for it and probably not the easiest to implement.