css-font-rendering icon indicating copy to clipboard operation
css-font-rendering copied to clipboard

If applied to a selector, what's the behaviour?

Open jakearchibald opened this issue 11 years ago • 9 comments

.whatever {
  font-rendering: mandatory 60s;
}

.whatever .foo {
  font-family: foo;
}

.whatever .bar {
  font-family: bar;
}

.whatever .blah {
  font-family: sans-serif;
}

Assuming:

  • foo & bar are defined in @font-face rules
  • foo takes 5 seconds to load
  • bar takes 10 seconds to load
  • (I'm also assuming the font-rendering in .whatever has precedence over rules in @font-face)

When does the text in .foo render? As in, does it also wait for bar as font-rendering is set on a parent that uses both fonts? What about the text in .blah?

jakearchibald avatar Nov 11 '14 18:11 jakearchibald

Also:

.whatever {
  font-rendering: mandatory 60s;
  font-family: foo, bar;
}

Assuming foo has a unicode range that covers all rendered text (and bar has a larger range), does foo get 60s to load, and if that fails bar now gets 60s? Or 60s for foo then render default, then load bar as if it were font-rendering: swap 0s?

jakearchibald avatar Nov 11 '14 19:11 jakearchibald

For the first case: not claiming to be a CSS expert but my take is that foo renders at 5s, bar renders at 10s, blah renders immediately since it's using a "readily" available system font.

For the second case, here is my take:

  • foo gets 60s to load, bar gets 60s to load, you get 60s to load, and you and you and you, you all get 60s to load ;)
  • Blink's (and I imagine FF's) timeout is on a per font-family basis so I think Oprah Winfrey would approve.

cc/ @tabatkins

KenjiBaheux avatar Nov 13 '14 06:11 KenjiBaheux

Makes sense to me! There isn't a way to say "render no text here until all the fonts have downloaded", but maybe we don't need that.

jakearchibald avatar Nov 13 '14 13:11 jakearchibald

There isn't a way to say "render no text here until all the fonts have downloaded", but maybe we don't need that.

It seems like a reasonable use case. I think we can change the model and allow for that. Intuitively, it would be similar to getting a bunch of font promises and waiting until all of them satisfy the condition, and if any one fails to complete within specified timeout, then entire set fails.

  • mandatory 10s + font A and B: hold rendering until A and B are available, or before 10s timer expires. If either fails to complete within that time, then revert to fallback.
  • swap 10s + font A and B: render with fallback and swap both A and B once both have finished complete. If timer expires before all of them are available, stay with fallback.

If you don't want A and B to depend on each other, then move the font-rendering declaration further down the selector tree... WDYT?

igrigorik avatar Nov 13 '14 23:11 igrigorik

Yeah, that works. There are nuances around cases where B isn't needed, but don't think it gets in the way.

jakearchibald avatar Nov 14 '14 16:11 jakearchibald

Thinking about this some more... there may be some odd edge cases around this sort of pattern. For example, say I have parent selector that triggers a font fetch and the timer is running.. then, I trigger a display property on another child selector that now needs another font -- does the outer timer stay the same, get reset, etc? These are solvable cases, but seems like implementation might get a bit hairy...

It would probably be much simpler to stay with "each font is on its own" semantics, and if you need grouping, then use Font Loading API. Worth thinking about the use cases vs complexity...

igrigorik avatar Nov 14 '14 17:11 igrigorik

I would prefer that the CSS approach stays simple (font loading API should be the better choice for more advanced use cases).

KenjiBaheux avatar Nov 17 '14 01:11 KenjiBaheux

:+1: for simple.

igrigorik avatar Dec 08 '14 17:12 igrigorik

The way I just defined it in http://tabatkins.github.io/specs/css-font-rendering/ is that each font face comes with a timer that starts when the UA first attempts to use it. Whether a given element using the font considers itself blocked, swappable, or stuck depends on its individual 'font-rendering' values, compared against the font's timer. The 'font-rendering' descriptor in the @font-face itself just provides a default for any element that doesn't manually specify things.

For more complicated things, definitely just use the Font Loading API.

tabatkins avatar Mar 20 '15 23:03 tabatkins