W3C home > Mailing lists > Public > www-style@w3.org > June 2015

[CSSWG] Minutes New York F2F 2015-05-20 Part V: Font Loading

From: Dael Jackson <daelcss@gmail.com>
Date: Sat, 20 Jun 2015 08:43:43 -0400
Message-ID: <CADhPm3ttPkdK4i5Pjm9HiX_AFb+408uqPeu7r-uGHoCuzmTaOQ@mail.gmail.com>
To: www-style@w3.org
Font Loading

  - RESOLVED: font-loading control is only an @font-face descriptor,
              not a property
  - RESOLVED: accept font-display-thing-whatever-loading property
              with four values to be renamed later: block | swap |
              fallback | optional
              - block shows blank, swaps in fallback at 3s, swaps in
                  real font whenever it loads
              - swap shows fallback, swaps in real font whenever it
             - fallback shows fallback, swaps in real font if it
                  loads before 3s
              - optional shows real font if it loads from cache
                  (very short timeout), otherwise shows fallback;
                  optional allows UA to not continue loading the
                  font for the next time

====== FULL MINUTES BELOW ======

  Scribe: fantasai

Font Loading

  TabAtkins: Basic idea is that a font, once you request it, goes
             through two periods.
  TabAtkins: One is the "blank" period from 0s, which is when you
             don't show anything,
  TabAtkins: then the "swap period", which is when you show the font
             once it's loaded,
  TabAtkins: and lastly the "screw it" period, which is when you no
             longer try to show the font, even if it's loaded.

  TabAtkins: Question was, do you re-layout at the end of the blank
  TabAtkins: Yes.
  fantasai: No.
  fantasai: You lay out the blank page with the fallback font
            metrics. If the real font hasn't loaded yet, the swap
            period is also using the fallback font, so no layout
            change (just visibility of the font change).
  fantasai: Re-layout happens when the real font gets used.

  ChrisL: What's the value of having the blank period?
  TabAtkins: 2 use cases. One is not good, but ppl do it anyway.
  TabAtkins: Using icon fonts. Good icon fonts are implemented with
             ligatures, so no problem with using a fallback font.
             But bad icon fonts, using pictures assigned to arbitrary
             letters, those ones shouldn't show anything,
  TabAtkins: because otherwise show random letters.
  TabAtkins: The other use case is where the particular font is
             important, and it's better to show nothing for a little
             bit, rather than showing anything.
  ChrisL: That second case is very rare. SVG had people arguing that
          way, and 10 years later it's still not significant.
  Florian: I think it's the default because of icon fonts.
  <BradK> Like with a Klingon font?
  iank: There's also a case where you know it's going to load in a
        reasonable amount of time, so you don't want to show
        anything in the meantime.
  plinss: wrt icon fonts, that's the case of you never want to
          fallback ever.
  TabAtkins: Not sure about that.

  ChrisL: Why not have a 'none' generic font family? You can put
          font-family: Icon Font, none; ?
  TabAtkins: I kinda disagree because if the icon never shows up, at
             least there's a visible something and you can learn
             "p" means "log out" or whatever.
  ChrisL: Couldn't you learn about a magic blank space?

  TabAtkins: If you limit the blank phase for a small amount of
             time, the user is assessing the page, but hasn't begun
             really interacting with it yet.
  iank: This is what we did in ?, just showing the basic structure
        even before we show the content has a huge user benefit.
  iank: Facebook does this, for example.
  TabAtkins: You get a much better perceived load time.

  TabAtkins: Keywords are in question.
  TabAtkins: Under my proposal we have block, swap, optional.
  TabAtkins: Block sets the thresholds at 3s and infinity -- you
             really want that font --
  TabAtkins: after 3s show fallback rather than blank, but always
             swap in font once it loads.
  TabAtkins: Swap sets the thresholds at 0s and 3s -- you show the
             fallback font immediately, and don't swap the real font
             if it shows up after 3s.
  TabAtkins: Assume user has started interacting with page, so it
             shouldn't re-layout.
  TabAtkins: Optional sets the thresholds at 0s and epsilon.
  TabAtkins: Basically only show the real font if it's locally
             available (or loaded lightning fast).
  TabAtkins: John's proposal had some other keywords.
  TabAtkins: Fallback sets the thresholds at 0s and infinity -- use
             the fallback, swap in the real font at any point in
  ChrisL: Why epsilon?
  TabAtkins: Because if you use zero, you'll immediately fall into
             "screw it" and never show the font. It still takes
             *some* amount of time to check the cache.
  TabAtkins: Optional is "Nice font if you have it, not a big deal
             if it doesn't show"
  TabAtkins: ? mentioned that you could simply not download the font.
  TabAtkins: Mobiles are most likely to fail epsilon,
  TabAtkins: continually,
  TabAtkins: so never show the font.
  TabAtkins: So might be useful to have it mean "loading the font is
  plinss: For "screw it" phase, might want to also say "abort the

  [TabAtkins adds a column for the four values titled "download",
      with checkmarks on blank, swap, fallback, and abort/cancel for

  ChrisL: So, which of those should you use in the case where you
          have a font for a language which you expect the fallback
          font not to have any glyphs?
  TabAtkins: I think you'd use 'block'.
  TabAtkins: Unicode "can't find the glyph" blocks aren't
             particularly useful, so showing blank is fine, possibly
  TabAtkins: and then you're treating it as a required font.
  TabAtkins: So these are block = "super-needed", fallback = "pretty
             needed", swap = "kinda needed", optional = "meh".
  ChrisL: Essential, important, preferable, and meh.
  leaverou: I think we have consensus on "meh".

  Florian: We have two more rows on this table. Not necessarily
           desirable, but discussed.
  Florian: Safari had an infinite blank period.
  Florian: Safari sets thresholds at infinity, infinity, yes
  Florian: John had another slightly less bad proposal which was...
  Florian: Which had very long but not infinite timeout on blank.
  TabAtkins: jdaggett's 'blank' keyword is my 'block' keyword.

  [TabAtkins completes the table with jdaggett's variant of Safari's

      Column 1: Name of Value
      Column 2: Timeout for showing fallback instead of blank
      Column 3: Timeout for no longer accepting the real font as a
      Column 4: Whether or not to complete the download (if the
                download has timed out)

      block | 3s | infinity | yes
      fallback | 0s | infinity | yes
      swap | 0s | 3s | yes
      optional | 0s | epsilons | abort
      Apple | infinite | lol | yes
      really-blank | ~60s | infinite | yes

  fantasai: I think swap should be called 'fallback'.
  fantasai: For fallback, if we want to keep it, that should be
            called 'swap', because you can swap forever.
  Florian: 'optional' is a good name.

  TabAtkins: Our proposed name... we proposed font-display.
  TabAtkins: That seems to go along with Chris's names.
  Florian: jdaggett had font-display-loading (or
  TabAtkins: Auto is whatever default you feel like.
  fantasai: Could just put your preference in the UA stylesheet.
  TabAtkins: Auto allows more sophisticated heuristics.
  fantasai: OK, that's fair.
  fantasai: So, swap and fallback should swap names.
  fantasai: I think 'block' is not a great name.
  [discussion that ChrisL's naming captures use cases better]
  [fantasai points out that understanding what the values do is
   <andrey-bbg> I like fallback

  Florian: We should definitely have swap & fallback in the first
  Florian: Block I guess we need, too.
  Florian: Optional could defer.
  ChrisL: Don't see the benefit.

  leaverou: Are we only going to have keywords, not timeouts?
  leaverou: What about other countries?
  TabAtkins: 3s in this discussion is just "a reasonable time"
  Florian: If you're making a mobile browser for crappy networks,
           you can set it to 10sec.
  leaverou: But if you're shipping for desktop browsers, will ship
            the same hard-coded default everywhere.
  [discussion of setting this as a UA pref]

  plinss: I have a fundamental moral objection to this entire thing
          because it's taking what is fundamentally a user
          preference and putting it in the hands of the author.
  plinss: I'm cool as long as the UA is allowed to ignore the
          author's rules on behalf of the user.
  plinss: Want to make sure it's clear in the spec that this is a
  TabAtkins: font-hinting! :D
  plinss: Even if we give authors the actual timeouts, the UA could
          decide to multiply all timeouts by 10.

  TabAtkins: I kinda prefer the intentional keywords (ChrisL's list)
  TabAtkins: Rather than the behavioral ones.
  TabAtkins: And e.g. not block, not treat as mandatory.
  TabAtkins: Hierarchy of levels allows you to do some amount of
  Florian: Make everything 'should'.
  TabAtkins: Would rather be 'must', with exception for exceptional
             network conditions.
  Florian: And you can limit the scope of the exception.
  fantasai: I think we should have a note about networks speeds and
            the timeout.

  [Discussion of ChrisL's keywords]
  [Should avoid 'important' because of !important]
  [ChrisL's keywords = essential, important, preferable, optional]

  Florian: Wrt property vs descriptor.
  Florian: smfr didn't want a property [ because keeping track of
           whether a particular element can use a loaded font or not
           is unpleasant ]
  Florian: Only having a descriptor does not limit the use cases. If
           needed you can create two different fonts via @font-face,
           use as you want.

  RESOLVED: font-loading control is only an @font-face descriptor,
            not a property

  ChrisL: Swapping out font in some elements not in others is really
  fantasai: Possible but annoying via descriptor.
  plinss: There are use cases for it.
  plinss: E.g. navigation you want to never be blank, but other
          parts allow to be blank for awhile.
  <Bert> (Some people name their fonts by their function, such as
         "body font", "button font", etc, so it's easy to have
         different policies for each, even if they are actually the
         same font face.)

  fantasai: We're missing smfr, who might be arguing for blank.
  fantasai: But Safari could do that via auto.
  Florian: This isn't something we want authors to opt into.
  Florian: So, do we want to resolve on the first four values,
           modulo bikeshedding?
  fantasai: Yeah, block is not a great name.
  fantasai: I kinda prefer the functional names to the importance
  fantasai: I would want to know if you are going to swap the font
            at any point in the future vs. within a timeout.
  TabAtkins: UA could do anything.
  ?: Only for exceptional cases.
  Florian: Timeout varies, but behavior unlikely to.

  Proposed resolution: have 4 values for font-loading-display-
           whatever: block-essential | fallback-important | swap-
           preferable | optional
  [Waiting for jdaggett and heycame to dial in and catch up before
  <jdaggett> explanation of values?
  <jdaggett> block-essential == sort of like safari now?
  <fantasai> no

  [Time is spent to find the table from earlier in the minutes]

  <Florian> jdaggett: In terms of your proposal, we're taking blank-
            fallback and fallback, rejecting blank, and adding
            optional and swap from Tab's proposal,
  <Florian> jdaggett: and want to bikeshed everything.
  TabAtkins: Every keyword controls how long you blank for, how long
             you swap for, and then you're stuck in permanent
  TabAtkins: block-essential does 3s blank, and swaps in until
  TabAtkins: swap-important does fallback immediately, swaps until
  TabAtkins: fallback-preferable does fallback immediately, swaps
             only up to 3s.
  TabAtkins: optional falls back immediately, swaps if it shows up
             fast, and could be ditched if it doesn't load quickly.

  [jdaggett expresses concerns wrt epsilon]
  TabAtkins: You give it enough time to at least load from cache.
  TabAtkins: But if you're in an exceptionally slow network, or
             otherwise resource-constrained, you can say "screw it"
             and not load the font.
  TabAtkins: This sets up 4 preference levels for how important the
             font is to the page.
  TabAtkins: From "you need to display this font, otherwise
             everything is terrible" down to "it'd be nice, but it's
             okay if not."
  jdaggett: Optional will always display the fallback.
  TabAtkins: No, it has an effect. If the font has not yet loaded,
             optional is basically guaranteed to show the fallback.
  TabAtkins: If the font has downloaded and is in the cache, then
             you'll use it successfully.
  TabAtkins: On devices too slow to load from cache in a reasonable
             amount of time, it won't be used.
  jdaggett: People who are demanding optional are asking for a
            no-reflow solution.
  <jdaggett> The people who are asking for optional are looking for
             a "no reflow" use of fonts
  TabAtkins: That's very nearly what you get. The only exception is
             if you start trying to render text, but the font comes
             in, then you re-render.
  <jdaggett> i.e. either the font is *immediately* available or it's
  <dbaron> Yeah, if the people who want 'optional' actually want "no
           reflow", then they're not going to get it with this
  <fantasai> yeah
  <dbaron> Is that the main use case?
  jdaggett: dbaron's point is my question
  jdaggett: [...]
  * scribe needs to move closer to speaker

  dbaron: Do people who want optional because they want no reflow,
          because want to avoid performance cost of reflow?
  [several ppl say no]
  Florian: No, I want it for... It's a font, if you have it, would
           be nice.
  Florian: In my mind epsilon is ~ 100ms.
  Florian: I'm not looking for entirely no reflow at all,
  Florian: looking for, if there is a reflow, it should happen so
           early in the page that the user hasn't started reading.
  Florian: Which is not what would happen with swap.
  Florian: After 3 seconds or so, user might have started reading,
           then text moves around.
  Florian: If font is sufficiently unimportant, as soon as user has
           started reading I no longer want to disturb the content.
  Florian: 100ms or so, nobody has got far with reading. But if you
           have the font available, I'd prefer that.
  Florian: If you reflow a little bit, I won't mind.
  TabAtkins: You probably won't notice the reflow during that
             portion of the load time.
  plinss: If the UA has eye-tracking, can even tell whether the user
          is reading or not :)
  jdaggett: What Florian's describing... I'm not really sure.

  jdaggett: If it helps what Google people are looking for,
  jdaggett: I think they're looking for no flash ever.
  TabAtkins: I don't think that's what they were looking for, but if
             it would help I can ask them about it when I get back
             to work.
  jdaggett: Discussion with Google people would be nice if not in
            various Google forums.
  TabAtkins: It generally was, mostly in github for original
  <jdaggett> It would help if the discussion by Google people was in
             public forums like www-style and not within github
             issues for example.

  fantasai: Interesting thing that was discussed for optional was,
            with limited network, just not even bother trying to
            load the font.
  Florian: Also low memory.
  fantasai: And bandwidth constraint.
  heycam: ...
  heycam: In terms of bandwidth constraint...
  heycam: Aren't you going to do the same kind of loading?
  heycam: I'm not sure how optional helps with bandwidth constrained
  heycam: Aren't you just going to do the same loading?
  fantasai: We had discussed making 'optional' make the loading
            optional entirely.
  fantasai: So a device that knew it was constrained could opt to
            not download the font.
  jdaggett: I'm not sure if optional is being imagined in this
  jdaggett: On a certain device you have an idea of your max
  jdaggett: you can guess whether going to make it within a certain
            timeout value,
  jdaggett: there's sort of a multiple-page ...
  jdaggett: How are you imagining the font ever gets down to the UA
            unless you've got something that says "here's when a
            load happens"?
  jdaggett: This gets into resource hints.
  TabAtkins: When the font is marked optional?
  jdaggett: If it's marked optional, how is it ever getting
  jdaggett: UA knows it can't download within the timeout, so
            wouldn't bother downloading.
  jdaggett: Would need some language, something like a resource hint.
  TabAtkins: Yes.

  TabAtkins: Point is, optional is the least necessary font.
  TabAtkins: If UA determines that it will never be able to pull
             down reasonably, fine.
  TabAtkins: If doesn't have it yet, but bandwidth is fine, then
             could continue downloading even though not using it.
  jdaggett: Then need a normative definition of whether loading
            follows through,
  jdaggett: or treated as something that can be ignored.
  fantasai: He wants the last column in the table normatively.
  TabAtkins: Yes, that would be in the normative definition.
  (last column is whether to download or not)
  jdaggett: Need to say whether fetch continually or fetch never
  TabAtkins: It might continue or might never happen, depending on

  plinss: I'm questioning how this interacts with service workers.
  jdaggett: If different UAs are making different decisions,
  jdaggett: optional will be either never use this font or use in a
            blue moon.
  TabAtkins: Yes.
  TabAtkins: If font was important, you'd use a higher-preference
  TabAtkins: You can just use sans-serif, it's fine.
  fantasai: Might want "continue through and download the font" as a
            separate switch from the timeout?
  TabAtkins: If the font is at all important, so continue

  plinss: ... service workers could abort the load, or fetch for
          next time.
  TabAtkins: Would have to talk to other engineers, but this might
             have useful conceptual overlap with client hints.
  TabAtkins: Could say that optional request is tagged with a
             particular client hint.
  plinss: In general, we want to try to explain these behaviors in
          terms of other API.
  fantasai: I suppose might want a user preference to choose not to
            download preferable or optional fonts, but download
            essential ones.
  jdaggett: Don't think I can follow the description.
  TabAtkins: Proposal is just your proposal, minus blank, plus my
             swap and optional keywords values.
  plinss: John, we were very close to accepting this proposal with
          strong consensus in the room. Held off because wanted to
          give you a chance to object.
  plinss: Suggest, if it's okay with jdaggett, that we resolve to
          accept this, let TabAtkins write it up as spec prose, and
          you can suggest improvements, and we will revisit
  <Florian> +1 to plinss
  jdaggett: I don't know what the proposal is, can't hear anything
            to what TabAtkins says.
  jdaggett: I'm fine with Tab writing it up, resolving to move
            forward can't tell one way or another.

  RESOLVED: accept font-display-thing-whatever-loading property with
            four values to be renamed later: block | swap | fallback
            | optional
            - block shows blank, swaps in fallback at 3s, swaps in
                real font whenever it loads
            - swap shows fallback, swaps in real font whenever it
            - fallback shows fallback, swaps in real font if it
                loads before 3s
            - optional shows real font if it loads from cache (very
                short timeout), otherwise shows fallback; optional
                allows UA to not continue loading the font for the
                next time

  <BradK> What about a descriptor that says what the average
          character width and extent is, so that reflow will be
          minimal when the font does load?
  <ChrisL> bradk, we tried that with css2 (not 2.1) and dropped in
           for css3
  <ChrisL> bradk - see
  <BradK> ChrisL: dropped because to complex? I was think of a
          single width (average of all characters), and assuming an
          ascender and descender's effect on height, if any.
  <ChrisL> bradk - even the more complex one was not enough to
           prevent reflow. and that was before opentype features
           meant that reflow was even less predictable just from
           individual widths
  <ChrisL> ... a single average width will not be enough to avoid
  <BradK> ChrisL: didn't mean to synthesize, just as a hint for
          reserving space. But OK, I see your next comment there
  <jdaggett> bradk: better way is to use font-size-adjust since this
             will push the fallback font to be close to the
             downloaded one
  <BradK> jdaggett: yes, I'd like something like font-size-adjust
          for widths, so that when I have a very condensed font, the
          fallback don't won't be huge looking.
Received on Saturday, 20 June 2015 12:44:12 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 22:52:15 UTC