[csswg-drafts] [css-fonts] Handle language/family dependent cascading of keyword font-size values

Manishearth has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-fonts] Handle language/family dependent cascading of keyword font-size values ==
https://drafts.csswg.org/css-fonts-3/#font-size-prop


In the case of absolute keywords like `medium` and `large`, the spec leaves a lot of freedom up to the user agent.

In practice, most user agents seem to implement roughly the same tables for these. Additionally, the "base" value of font-size (i.e. the value of `medium`) often depends on font-family and language (Firefox and Chrome let you configure this at a per-language level).

This gets interesting when font-size is inherited (I've written about this in the "Keyword values" section of [this blog post](https://manishearth.github.io/blog/2017/08/10/font-size-an-unexpectedly-complex-css-property)). For example, in

```html
<div style="font-size: medium"> <!-- 16px -->
   <div style="font-family: monospace"> <!-- 13px -->
   </div>
</div>
```

the font-size of the inner div is _not_ the same font-size of the outer div, it is whatever the font-size is for `medium` in a `monospace` font. In Firefox, Chrome, Safari, and Servo (not checked other browsers), this applies to `em`/`%` units as well:

```html
<div style="font-size: medium"> <!-- 16px -->
   <div style="font-size: 2em"> <!-- 32px -->
     <div style="font-family: monospace"> <!-- 13*2 = 26px -->
     </div>
   </div>
</div>
```

the font-size of the inner div becomes "2 times the font-size of `medium` in a `monospace` font".

The way Firefox does this is that whenever the lang/family changes it recomputes the "base size" as if the language and family are the ones on the current node for the whole ancestor tree.

Servo (and thus Stylo, the new styling system in Firefox) handles this differently; it considers the computed value of font-size to have an optional "keyword info" along with the size, where the "keyword info" exists if the font-size was derived from a keyword, and it contains the keyword in question as well as a factor and pixel offset (in the case of `calc`s). When the font-family/lang changes, we recompute a keyword-derived font-size by taking the font-size for that keyword in the current family/lang, multiplying the factor, and adding the offset.

I'm not sure what Chrome/Safari do, it seems likely that they does the same thing as Servo but without the offset (it doesn't deal with this in the case of calcs, falling back to simple inheritance)

We should investigate this behavior across browsers and probably spec it.

The easiest way to do this would probably to spec the computed value as having the extra bits that the Servo impl uses, since that leads to the cleanest behavior (it inherits normally, except in the case of a family/lang change, and em/%/calc units just need to accumulate their effects onto the keyword info if it exists.

Alternatively, we could spec it more closely to the way the firefox implementation works ("When the language or family change, compute font-size as if the language/family have always been this in all ancestor elements") though I suspect this will encourage an inefficient implementation.

cc @dbaron 

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/1835 using your GitHub account

Received on Wednesday, 27 September 2017 02:47:13 UTC