Cascading Style Sheets (CSS) Working Group Teleconference

03 March 2021


alisonmaher, argyle, astearns, chris, dholbert, dlibby, fantasai, heycam, jfkthame, leaverou, miriam, Morgan, myles, plinss, Rossen_, sanketj, smfr, TabAtkins, tantek, TYLin, una, zoe

Meeting minutes

advance-override details

<Rossen_> github: https://github.com/w3c/csswg-drafts/issues/5983

<myles> fantasai: We decided we wanted to add an advance-override descriptor to the @font-face rule, but we didnt' define what it actually does other htan to say it takes a percentage that's resovled agains the advance itself

<myles> fantasai: A couple of points that would need to be resolved: 1. How are we increasing or decreasing the advance width? The size of the glyph in bohth axes together? Just x axis? Space around each glyph? left side? right side, start end, end end?

<myles> fantasai: There's been some discussion in the issue about what it should apply to and how it should apply, but no conclusions.

<myles> fantasai: I think the first thing we'd have to decide is how we increase the size of the glyphs

<myles> fantasai: to do text layout

myles: Shouldn't distort the outlines

chris: We're changing the advance, not the bounding box of the glyph. Not changing the outline

chris: just changing the amount you need to move forward

<myles> chris: We're changing the advance, not the bounding box of the glyphs, n or teh geometry. We're changing the amount you need to move forward before painting the next glyphs. Changing spacing in the text advance direction

chris: very clearly not changing any glyph geometry

<myles> chris: There's also a size override, but there's separate

chris: There is a proposal to have a scale factor, but that's separate

myles: I think that the exact way that space is added, I think that's not a super important decision, so doing whatever makes sense is easiest. For us that would be applying to the right side always

Rossen_: Is that affected by directionality?

myles: No, always on the right side

chris: Why?

myles: it's just easier to implement. Base-level API renders text LTR

chris: So you're saying you do bidi reordering in the backing store and then apply space after that?

Rossen_: So proposal is to keep it uniform on one side

jfkthame: I would not like to specify that space is only applied on one side

jfkthame: if that's easiest to apply, maybe allow it

jfkthame: but I don't think that's the best behavior

jfkthame: browser should be able to apply equally across both sides of glyph

jfkthame: which is superior

<chris> I'm a bit concerned about margins not lining up, with space at the margins

chris: could add space not at margins

myles: bleeds into my point. naive implementation is to just multiply the number in the font file

myles: but that applies before shaping

myles: when you apply shaping, have to match what's in the font file.

myles: Correct implementation of this needs to apply this after shaping

myles: which is a more complicated implementation

myles: doing something like what chris said is not hard, because you're already at the level of knowing that information

Rossen_: So sounds like we're aligning on adding space on both sides?

Rossen_: any other opinions? or resolve?

myles: If you do it on both sides, then alignment won't look good on either side

jfkthame: We're putting the space equally makes for a less-bad result than you will get than if it's all on one side

jfkthame: in practice, I don't think this is a feature that should be used for a large adjustment

jfkthame: it's for fine-tuning the metrics of a fallback font to match another font

jfkthame: so the adjustment is going to be a small fraction of a glyph width. Not too bad.

myles: I suggest leaving it undefined

<chris> we should put that wording from jfkthame into the spec - fine adjustments, not major ones. fine tuning

myles: Major point is that it makes text more/less compact

myles: Might be worth getting impl experience

jfkthame: Wrt trimming space at line boundaries, I'd be opposed.

jfkthame: This is effectively about modifying the metrics of the font

jfkthame: if you modify metrics of a glyph, should be everywhere that glyph occurs, not different based on position in the line

<astearns> AFAIK this feature is NOT about making things look good, it’s merely about reducing layout shift once a font loads

fantasai: Slight tangent, but

fantasai: This feature has a lot of badness to it

fantasai: First, as we've been discussing, it distorts alignment

fantasai: Second, it breaks complex and cursive writing systems

fantasai: Third, because it introduces uneven amounts of spacing between pairs of characters, it distorts the rhythm of the text and hence impacts readability in a negative way

fantasai: None of these problems apply if the font is scaled in both axes instead of adding space between characters

fantasai: And I think it would be harmful if we ship this feature without also shipping a scaling-factor descriptor that could be used in any cases where that would be usable in place of advance-override

jfkthame: Strongly agree with that.

<Zakim> TabAtkins, you wanted to remind that we're trying to better solve a case where people are *already* doing letter-spacing

TabAtkins: Keep in mind, the goal is not to define a new typographic feature for text. It's to replace existing hacks that people use to reduce layout shift when fonts load

TabAtkins: if we can reduce layout shift, even if it looks bad, still successful

TabAtkins: Want it to look good and make it work across writing systems

TabAtkins: but if not ideal, that's fine, because that's not the point

TabAtkins: should be for fonts that not there for very long, will be replaced by the real font later

TabAtkins: Want a solution that works across scripts and works OK, better than current hacks

xiaochengh: Regarding scaling / font-size override

xiaochengh: we have prototyped in Chrome, and found it tricky to nicely specify

xiaochengh: This might affect ascent-override etc.

xiaochengh: they have a %, which font-size do these resolve against? resolve against the font-size property value of the element or used font size?

xiaochengh: Either way going to surprise some users

xiaochengh: since our main focus is to reduce layout shift, wouldn't want to introduce a blocking issue on top of advance override

<TabAtkins> fantasai: To reply to TAb, I udnerstand this is for reducing layout shift

<TabAtkins> fantasai: But there's different way to do that, and I think in many cases scaling outlines without affecting resolution of length units would also have that affect

<TabAtkins> fantasai: wrt using it as a fallback, what happens if the other font doesn't load

<TabAtkins> fantasai: This isn't "onlya pplies in a fallback font"

<TabAtkins> fantasai: People on slow connections, etc are stuck with a font that's not just non-ideal but also has weird spacing

<TabAtkins> fantasai: And this doesn't work for complex or cursive script as specified today.

<TabAtkins> fantasai: You can handle those scripts if you scale, not if you intro space.

TabAtkins: if your fallback font plus scaling advance looks terrible, you chose a bad fallback font

TabAtkins: we don't need to protect author from that. They should tweak it to be closer.

TabAtkins: If it is, it's a bad page.

<jfkthame> instead of `font-size-override`, suggest something like `glyph-scale-factor`, then it's clearer that it doesn't affect anything else

myles: What is the exit criteria for this discussion? We've talked about several issues here.

TabAtkins: Trying to figure out how to fix this for awhile

TabAtkins: keep getting objections that it's not ideal

TabAtkins: but nobody is helping making a better solution

TabAtkins: we did exploration with scaling, it doesn't lookg good

TabAtkins: maybe we need to scale on some scripts

TabAtkins: but essentially just letter-spacing works well

fantasai: letter-spacing applies evenly

fantasai: and if it's supposed to apply for temporary font, should shut off if you're not loading another font and sticking with this one

TabAtkins: but then you have a layout shift

fantasai: If downloading is turned off, then no layout shift

myles: rogue character with accent in the middle of a paragraph causes ...

Rossen_: Proposed path forward... not hearing a clear consensus around a) where the adjustment should take place or b) should we even have that

Rossen_: I think we resolve in backwards order

<TabAtkins> summary of myles: also useful if you have a fallback used for certain characters, which has an oddly different character size - this lets you adjust the fallback characters to feel better

Rossen_: First question, should we still pursue this?

<chris> OK so close this discussin with "needs proposal"?

fantasai: I can live with having this plus a scaling factor, but not having just this one, because if only have a broken option that's not good enough

myles: I think we should have both, changing scaling factor makes a lot of sense

TabAtkins: Not hearing any objections to what we're doing here, other than fantasai's point.

Rossen_: so no objection to continuing on this

Rossen_: So specific proposal here, fantasai mentioned adding scaling factor and then we have to decide where space is added

Rossen_: My proposal is to take back to the issue and iron it out there

fantasai: suggest to take a resolution on a) adding a scale-factor descriptor that only affects the glyph outline b) add space on both sides, maybe *allow* (MAY) UAs to do one side only if it's an implementation problem c) apply it to all glyphs in all writing systems, d) warn about how that can break things in certain writing systems / if too much space is added

Consider clarifying Highlight system color, and maybe adding a new system color for control background

<Rossen_> github: https://github.com/w3c/csswg-drafts/issues/6008

chris: emilio raised it

chris: I'm reluctant to add a new system color

Commas in color-mix()

<Rossen_> github: https://github.com/w3c/csswg-drafts/issues/6066

leaverou: Since we have rule that ? reptition should use commas but not other things

leaverou: we removed commas from color-mix because not a list

leaverou: but it doesn't read very nicely, and not clear which color the percentage belongs to

leaverou: so thinking to add the colors back

leaverou: since we can't keep going back and forth about it, UAs are implementing

leaverou: Wanted to resolve this once and for all

leaverou: I also agree it's more readable with commas

leaverou: I think it should have a comma to separate metadata from list of colors

<una> to also agree (we need commas)

leaverou: clarify whether about the first color or the function as a whole

leaverou: Seem to have consensus on adding them back

leaverou: Also, do we still have 'in' for color space?

leaverou: Seems like only have color space in the beginning

<Zakim> TabAtkins, you wanted to agree

TabAtkins: Agree with leaverou

TabAtkins: we're not attached to using commas everywhere like JS is

TabAtkins: only use it in some places

TabAtkins: It works reasonably here

TabAtkins: and helps with readability

TabAtkins: and we should also have the metadata in a single thought at the beginning, separated by comma

TabAtkins: consistent with gradients and shapes

TabAtkins: so +1 to what leaverou suggested

una: I agree that commas are needed here

una: much like gradients

<miriam> +1 need commas

una: I also want to add, I don't think we need in keyword if we have this syntax

una: I think we are reaching consensus in the issue, and +1 to proposal

<aja> fwiw, emilio landed on nightly, used commas, & % applied to 2nd color, "in srgb" at start or end. willing to change

leaverou: I would argue for 'in' keyword

leaverou: it reads better, and also lets us expand the syntax later to add more options

leaverou: So, makes it more readable and makes syntax less ambiguous, so argue to keep it

Rossen_: Seems like we have consensus around adding commas, any objections?

<chris> great, emilio already implemented what we are about to resolve <3

Resolution: Add back commas

Rossen_: Next one is do we want to have the 'in' keyword

una: I would like to object to it

<aja> chris, except for which color the percentage applies to

<TabAtkins> Also object, we don't use these sorts of intro keywords except absolutely necessary for disambiguation.

una: Reasoning, I don't think it's necessary and we don't have a construct of 'in' elsewhere in CSS, so introduces new concept not seen anywhere else and I don't think it adds clarity

<astearns> we have 'at' elsewhere

una: Don't want to add new syntax to CSS

<TabAtkins> Colorspace keywords are plenty clear and won't block our extensibility in the future.

Rossen_: OK, I suggest we open a separate issue for this

<TabAtkins> astearns, yeah, that's for disambiguation

<TabAtkins> because there are two positions

leaverou: Using prepositions for metadata in functions is common in gradients as well, which is where I got the inspiration. But agree with separate issue.

TabAtkins: I'm happy to argue that gradients are special

More clarity around the percentage in color-mix()

<Rossen_> github: https://github.com/w3c/csswg-drafts/issues/6064

<TabAtkins> gradients use "to" because it disambiguates whether the gradient comes *from* that direction or goes *to* that direction (and we flipped back and forth during dev, so there's no obvious answer).

miriam: In the middle space, single percentage value, and spec was conflicted on what that refers to

miriam: is it percentage color, or distance to second color

miriam: or percentage of second color

miriam: spec disagreed with itself

<TabAtkins> gradients use "at" to separate the <position> from the possibly-preceding <length>{1,2}

miriam: with commas, would be nice to do percentage in either color

<leaverou> note: the spec has since been fixed and does not disagree with itself anymore :)

miriam: so if you put in first color refers to weight of that color, second is weight of second color

miriam: would have to decide what to do if 2 percentages are specified

miriam: SASS functions confusing as well, never clear to me which the percent refers to

chris: My understanding was % is % of that color, and all examples (there were more examples before)

chris: there was just one sentence that was off, and Adam fixed ti

chris: Seems clear it's a % of that color, not along a blend between the two colors

chris: the color that it's next to

leaverou: mixing paints, makes sense % of first color

chris: ... that's confusign

chris: if % don't add up, scale to add to 100%

chris: does that make sense?

miriam: So % goes with a color between the commas, that makes sense to me

miriam: so % can be applied to either color, and can put it in one or both

leaverou: Should allow for ...

leaverou: and scale accordingly

chris: Have that in HWB, if too high scale it back

TabAtkins: I think whichever syntax we go with, should be consistent between color-mix() and cross-fade()


TabAtkins: cross-fade() matches up with what miriam suggests

TabAtkins: can add % with any of the images

TabAtkins: whichever one, if omitted, it's just 100% - [sum]

TabAtkins: if don't add up to 100%, we fill in the remainder with a transparent image

TabAtkins: idk if we want to do with colors

<chris> prefer a rebalance like HWB

leaverou: 3-way mixes are confusing, too many ways to do it

TabAtkins: I agree with reasoning for not doing 3-color mixes, but adding in transparency doesn't suffer from same confusion issues

TabAtkins: not strong on either, but greater consistency with cross-fade() would be good

<TabAtkins> chris, note that HWB does *not* rebalance for <100% sum

<TabAtkins> there it takes the remainder from the pure hue

<TabAtkins> >100% causing rescaling is uncontroversial and common between all the functions, yes

Rossen_: Can someone summarize the proposed resolution?

leaverou: Before we summarize, one last point

<TabAtkins> Proposed new grammar: color-mix(<metadata>, <color-option>#{2}), where <color-option> = <color> && <percentage>?

leaverou: if we handle percentages < 100% by mixing with transparent, it has special interpolation handling so we don't want to do that

TabAtkins: Ignoring the < 100% sum and take it to the issue, think we can resolve on the rest

<argyle> `color-mix(in lch red 80%, blue)` also `color-mix(in lch, red, blue 80%)`

<argyle> `color-mix(in lch, red 80%, blue)` also `color-mix(in lch, red, blue 80%)`

TabAtkins: proposal above

TabAtkins: if above 100%, rescale to add to 100%

<TabAtkins> if below 100%, figure out in issue

Rossen_: any objections?

Resolution: color-mix(<metadata>, <color-option>#{2}), where <color-option> = <color> && <percentage>?

[css-color-5] How should negative percentages behave in color-mix()?

chris: Sam Weinig who is implementing pointed out that can't do negative percentages

chris: una said why don't we clip it 0-100%

chris: nobody wants this

chris: I can define it

fantasai: Can you make it invalid?

TabAtkins: invalid matches behavior in other mixing functions

TabAtkins: we intend for it to be meaningless, so should be invalid

Resolution: negative percentages are invalid in color-mix()

<argyle> sounds like calc() would get scary?

<Rossen_> ack

<Zakim> chris, you wanted to discuss the negative percentages


Rossen_: OK, end of meeting, we'll take the rest next week

<Rossen_> :)

Summary of resolutions

  1. Add back commas
  2. color-mix(<metadata>, <color-option>#{2}), where <color-option> = <color> && <percentage>?
  3. negative percentages are invalid in color-mix()
Minutes manually created (not a transcript), formatted by scribe.perl version 127 (Wed Dec 30 17:39:58 2020 UTC).


Succeeded: s/exist/exit/

Succeeded: s/exit/exit criteria/

Succeeded: s/end/in

Succeeded: s/[????]/we don't want to do that/

Succeeded: s/flip/clip/

Succeeded: s/?/Sam Weinig/

Maybe present: xiaochengh