Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Manishearth opened this issue Sep 27, 2017 · 17 comments
Labels
css-fonts-4 Current Work

Comments

@Manishearth
Copy link
Member

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). For example, in

<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:

<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 calcs). 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

@litherum
Copy link
Contributor

I don't think we should be specifying exactly how these work. The user preferences of letting some fonts behave slightly differently is a user/browser choice, and shouldn't be necessarily limited to the facilities the CSS spec spells out. Competitive advantage isn't necessarily required to fit within the framework of standardization. Perhaps the spec could hint that this sort of processing is possible, but it shouldn't prescribe exactly how to best suit your user's preferences.

@Manishearth
Copy link
Member Author

I think the inheritance behavior is sufficiently complex and mostly common between browsers that it should be mentioned somewhere, even as non-normative text.

It could also be specced as "if you intend to support having different base sizes for different languages/fonts, here is how to do it".

Bear in mind that whilst the configurability on a per-language basis varies based on browser, all browsers seem to do the "different generic font families have different font sizes" (I think)

In particular because most browsers seem to have similar behavior here it doesn't really make sense to shove it under the rug since that doesn't help future implementors (like Servo, which had lots of problems with just figuring this out). If it's something people probably need to implement because everyone does it, it probably should be there in the spec (at least as non normative text).

@dbaron
Copy link
Member

dbaron commented Jan 10, 2018

I think #1711 (comment) applies here as well; pages depend on lots of stuff related to font sizing, and there are a small number of known axes where user agents can vary things. The spec shouldn't pretend that they can vary others. It should be defined.

If somebody comes up with a new way they can be varied in the future that's web compatible, we can change the spec.

@css-meeting-bot
Copy link
Member

The Working Group just discussed [css-fonts] Handle language/family dependent cascading of keyword font-size values.

The full IRC log of that discussion <dael> Topic: [css-fonts] Handle language/family dependent cascading of keyword font-size values
<dael> github: https://github.com//issues/1835
<dael> Chris: Is myles on?
<dael> Chris: I did see comments from dbaron which were helpful. Is he on?
<dael> dbaron: I'm here.
<dael> astearns: No myles. Let's see what we can get through. We can ping him with resolutions.
<Chris> https://github.com//issues/1835
<Rossen_> Chris: you're quiet again
<dael> Chris: First one is issue 1835 which is lang and family dependant cascading. Spec is vague. Comment that for web compat UA have converged somewhat and should spec say something? myles says no to let browsers compete. dbaron said there is web compat and spec shouldn't pretend it could be anything
<dael> Chris: Sounds reasonable, but it means you need actual spec wording. Poss list of values. I'm not sure what each browser does.
<dael> dbaron: I feel like it's awk to agree without myles.
<dael> astearns: If we're unclear on what browsers do we need data.
<dael> astearns: Perhaps the data will tell us if it's possible to desc or not.
<dael> Chris: That's reasonable.
<dael> dbaron: I think ?? did a bunch of that while impl in stylo/servo. I don't know how well he rememebers since it was a while ago.
<dael> astearns: his comment was browsers seem to have similar behavior
<dael> Chris: Based on testing or a feeling/
<dael> dbaron: I think he wrote a bunch of test cases. Don't know if they're in a standard format
<astearns> s/??/Manishearth/
<dael> Chris: Would be useful to see
<dael> dbaron: I don't know if he still has it.
<dael> Chris: Absolutely. Anything would be very helpful. Will you ask him? If you say he doesn't have anything then okay, but it's worth checking.
<dael> dbaron: I can ask him in the GH issue.
<dael> Chris: Yes, okay. It's unfortunate we don't have Myles. My goal is round up the DoC so we can finish CR.

@dbaron
Copy link
Member

dbaron commented Jan 10, 2018

@Manishearth curious if you have testcases that you were using to test the behavior here across engines? The group seemed interested in seeing them if they're still around.

@Manishearth
Copy link
Member Author

I don't have them anymore, but my testcases were of the form:

  • Table of font family vs font size value
  • Various cascading tests, basically where I have a bunch of nested elements and language/family changes in some of them (there is also usage of em units and larger/smaller). Some of these are in the blog post.

@Manishearth
Copy link
Member Author

the cascading test is:

<div style="font-size: medium; font-family: sans-serif;"> <!-- base size 16 -->
    font size is 16px
    <div style="font-family: monospace"> <!-- base size 13 -->
        font size is ??
    </div>
</div>

<div style="font-size: medium; font-family: sans-serif;"> <!-- base size 16 -->
    font size is 16px
    <div style="font-size: 0.9em"> <!-- could also be font-size: 50%-->
        font size is 14.4px (16 * 0.9)
        <div style="font-family: monospace"> <!-- base size 13 -->
            font size is 11.7px! (13 * 0.9)
        </div>
    </div>
</div>

I don't have the source, but the table of font size stuff looked like this: https://manishearth.github.io/images/post/font-size-table.png

@FremyCompany
Copy link
Contributor

FWIW, I just checked in Edge, we do not have any such behavior. HTML and CSS enum sizes are mapped to one specific value regardless of the font-face.

https://wptest.center/#/il0q86

this can be exported to a webplatform test with just the click of a button

@FremyCompany
Copy link
Contributor

FremyCompany commented Jan 10, 2018

However, can someone take a look at this and tell me why this behavior is not applied in that case?

https://wptest.center/#/1e3os1

If specifying monospace as a fallback font is not even enough to trigger it, can we get rid of that behavior? It seems extremely unlikely authors actually hit this case if it only applies to pure "monospace". Or did I miss something?

@astearns astearns removed the Agenda+ label Jan 10, 2018
@Manishearth
Copy link
Member Author

Yeah, it only applies if you set a single generic font. I don't know why this is the case; @dbaron might have ideas.

@FremyCompany
Copy link
Contributor

@Manishearth If this is the case, I don't think we (Edge) desire to add that level of complexity in our engine for what looks like a very uncommon (and surprising) case. If other vendors are open to the idea of removing that case and match us, I'd argue that seems to be better for the web in general.

I just tried to find any bug mentioning "size" and "monospace" and did not yield a single instance of this issue so, as far as I know, this has never been reported to us (or eventually has been, but has never been understood).

@svgeesus
Copy link
Contributor

@Manishearth @FremyCompany I'm getting the sense from this that UAs can choose to have different behavior (ugh) but also that this coveres a very small and simple use case (specifying monospace, only) and that there is an opportunity to simplify the spec (and simplify the Servo implementation too). Can we do that?

@FremyCompany if we agree, I will put your first testcase into WPT. Otherwise, it is undefined and not spec-mandated so I can't.

@Manishearth
Copy link
Member Author

It's not just monospace, it's for lang-dependent font sizes too. I think that's used more commonly especially for more complex scripts. IE doesn't expose the lang-dependent font size prefs so it doesn't need to rest of the machinery to have it continue working well.

@FremyCompany
Copy link
Contributor

FremyCompany commented Jan 31, 2018

I think the specification already marks the behavior discussed here as optional:

The user agent may fine-tune these values for different fonts

As a result, no further change is required to make Edge compliant here. I think we are more talking about uniformizing behavior here than about making changes to the spec.


I see absolutely no value in applying a weird font-size setting for "monospace" (a rare value) and not "Consolas, monospace" (a much more common case). I discussed this with a few web developers to see if they were aware of this behavior, none was, and some wouldn't even believe me this was true in some browsers (aka the font-size would inherit a different value when you changed the font-family of a descendant). The spec doesn't say you have to do so btw, but I understand why you would if you decide to support different font sizes for each language script.

But whether or not you would need to keep supporting the existing code to allow changing the font-size for some language scripts, applying the same effect by default for just "monospace" is confusing and I would urge other implementers to think about removing that "feature" in that case.


I would also be truly curious to see how many people changed their default font-size, let alone changed it language script by language script. From our experience with Windows Phone, where we had been instructed to tie the default font size to the system zoom level, this resulted in a lot of websites being broken and unusable.

In fact we do not even have an option to change your default font size in Edge at all, as far as I can see. The recommended way to zoom a website is to use layout scaling which preserves every size ratio and plays well into the responsive nature of websites.

@svgeesus
Copy link
Contributor

svgeesus commented Mar 8, 2018

For fonts 3, closing as deferred to next level. We can of course still discuss this for possible change in fonts 4.

@FremyCompany
Copy link
Contributor

Here is a webplatform testcase covering Chrome/Firefox behavior here:
https://wptest.center/#/mrri00

@Manishearth
Copy link
Member Author

(Now that Edge is moving to Blink, I wonder if it's worth revisiting this)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-fonts-4 Current Work
Projects
None yet
Development

No branches or pull requests

8 participants