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

Suggestion: Implement font-display #358

Closed
superpoincare opened this issue Aug 19, 2016 · 101 comments
Closed

Suggestion: Implement font-display #358

superpoincare opened this issue Aug 19, 2016 · 101 comments
Assignees

Comments

@superpoincare
Copy link

font-display is getting some attention, although still experimental in many browsers.

https://css-tricks.com/font-display-masses/

Chrome/Canary, Opera and Firefox have it although it is disabled by default. Hope it comes out soon.

This leaves Google Fonts to implement it. Since it should be included with the @font-face declaration, Google Fonts can allow passing of a parameter such as "&display=swap" in the URL which creates css files with a declaration:

font-display: swap;

in the css file.

Are developers of Google Fonts thinking about it?

@davelab6 davelab6 added this to the Questions about Google Fonts service (API) milestone Sep 27, 2016
@joaoramos
Copy link

Is there any progress on this topic?

@davelab6
Copy link
Member

davelab6 commented Jun 18, 2017 via email

@zachleat
Copy link

It's a descriptor that goes into the @font-face block.

@davelab6
Copy link
Member

Aha, got it! :) Thanks!!

@thlinard
Copy link
Contributor

thlinard commented Jun 19, 2017

@zachleat
Copy link

Now that Chrome 60 is stable, the priority for this should be bumped up! It’d be an awesome addition.

@zachleat
Copy link

zachleat commented Aug 1, 2017

This would still be really great to have but @font-feature-values may be another option?

https://twitter.com/zachleat/status/892372316092608512
https://www.w3.org/TR/css-fonts-4/#font-display-font-feature-values

Doesn’t look like this is available anywhere yet though, so there is obviously going to be browser support mismatches between font-display and @font-feature-values so let’s keep pushing for this issue 😀

@davelab6
Copy link
Member

davelab6 commented Aug 2, 2017

Indeed I see on the twitter more and more interest :) https://twitter.com/jeff_archibald/status/892861206939095040

@sladen
Copy link
Contributor

sladen commented Aug 3, 2017

W3C specification:

High-level overview: new multi-browser CSS key/value pair that needs to go into each CSS snippet generated and delivered by Google Fonts:

    font-display: {auto,block,swap,fallback,optional};

When a remotely-served font is taking too long to load (or will never be loaded), this helps the browser know what to do with the textual content it is waiting to rendering. By adding font-display: swap; the browser is directed to use a local already-available system font so that the user can see/read their text quickly.

Article and jsbin demo on developers.google.com:

@webholics
Copy link

The question is whether it is save to just copy the font-face declaration which google generates for now and add the font-display on our own. At the end my question is how often a URL like https://fonts.gstatic.com/s/roboto/v16/sTdaA6j0Psb920Vjv-mrzH-_kf6ByYO6CLYdB4HQE-Y.woff2 changes?

@superpoincare
Copy link
Author

@webholics

It's not just a question of how often the font URL changes.

Google fonts's css file is different for different browsers. Even the same version of Chrome in Windows and Mac will receive different css files.

So if you are suggesting that one can generate a css file simply by copy-pasting the font-face declarations into your own css file doesn't work for everyone.

So it is useful to have font-display generated in the css by the Google Fonts server itself.

@davelab6 davelab6 changed the title Feature request: Implement font-display Suggestion: Implement font-display Sep 22, 2017
@Androbin
Copy link

@vijayaraghavanramanan
Just asking, why don't we use a static URL + redirect?
What are the technical considerations on this?

@superpoincare
Copy link
Author

@Androbin

What do you have in mind here?

Since since the font, weights, style etc are passed in the query string in the URL, so I thought it's natural to pass "font-display" in the URL.

@Androbin
Copy link

Androbin commented Sep 24, 2017

@vijayaraghavanramanan
Of course, I would prefer query strings as the solution.

I was just curious about why we don't redirect from some static URL to https://fonts.gstatic.com/s/roboto/v16/sTdaA6j0Psb920Vjv-mrzH-_kf6ByYO6CLYdB4HQE-Y.woff2 and the like.

I know, this becomes irrelevant with query strings. But until then, it would have been reasonable to be able to define something like:

@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  src: local('Open Sans Regular'), local('OpenSans-Regular'),
       url(https://fonts.gstatic.com/s/opensans/v14/<some-static-path>.woff2) format('woff2');
}

What are the technical considerations on serving different content on static paths for single font files instead of putting different paths inside https://fonts.googleapis.com/css?family=Open+Sans?

@superpoincare
Copy link
Author

superpoincare commented Sep 24, 2017

@Androbin

What Google Fonts does is that it creates different css files for different browsers.

The server sees the browser/version/OS and sends the right css file.

Even for a single version of Chrome in Windows/Mac OS, the font files (woff2/woff/ttf/svg/eot) are different.

Try to look at the css files in different browsers to check.

So that's why it's not appropriate to link the woff2/woff files directly.

And for that reason, the website using Google Fonts can't control "font-display" and Google may have to introduce it from their side.

@Androbin
Copy link

@vijayaraghavanramanan
That's not my point. I understand that the file content served to different clients may be different. But just like https://fonts.googleapis.com/css?family=Open+Sans refers to different font files, it would be possible to serve the respective font files dynamically on the same static URL.

@superpoincare
Copy link
Author

@Androbin

There are 847 fonts right now. Each has different weights, language, styles etc. One can even request multiple fonts like 2, 3 or maybe even 10 in the same request.

So I guess having static css files might not be optimal. Because there can be millions of different combinations.

Just guessing. Does that sound right?

@Androbin
Copy link

Androbin commented Sep 25, 2017

@vijayaraghavanramanan
Please don't get me wrong, I don't talk about static CSS files, I do talk about static URL to address the fonts. Just like the URL https://fonts.googleapis.com/css?family=Open+Sans is non-generic and static but does serve different content for different clients, it would have been useful to be able to have static URL for the fonts like https://fonts.gstatic.com/s/opensans/v14/<some-static-path> that would then serve fonts like the one currently available via https://fonts.gstatic.com/s/roboto/v16/sTdaA6j0Psb920Vjv-mrzH-_kf6ByYO6CLYdB4HQE-Y.woff2

@superpoincare
Copy link
Author

@Androbin

Apologies I didn't get the points you raised right.

Font files can be multiple. So how a single request serve multiple files?

@Androbin
Copy link

@vijayaraghavanramanan
https://fonts.googleapis.com/css?family=Open+Sans [1]
https://fonts.gstatic.com/s/roboto/v16/sTdaA6j0Psb920Vjv-mrzH-_kf6ByYO6CLYdB4HQE-Y.woff2 [2]
https://fonts.gstatic.com/s/opensans/v14 [3]
The URL [1] dynamically generates CSS that refers to [2] and the like. What if we had [1] look something like

@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  src: local('Open Sans Regular'), local('OpenSans-Regular'),
       url(https://fonts.gstatic.com/s/opensans/v14) format('woff2');
}

and have [3] dynamically resolve to the font file needed (like e.g. [2]). This would move the responsibility from [1] resolving as needed to [3] resolving as needed and give developers more freedom in using CSS because the ugly URL like [2] would have been moved even more away from them.

@superpoincare
Copy link
Author

@Androbin

Understand better now.

But how will you address the fact that one needs options for weights, styles and languages:

For example, I use the link for my site:

https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i&amp;subset=greek,greek-ext,latin-ext

which generates a css file with 28 font-face rules.

your [3] will just give the woff2 file for weight 400 and style normal, latin.

Nor is it desirable to request every weight and style etc. The browser looks at a page and decides which fonts to download.

So I think what Google does now is good. One quibble is that there are two servers. Ideally should have been just one - both for the css and the font files.

Another way is Typekit, where you have an account and make a kit.

@Androbin
Copy link

@vijayaraghavanramanan
This wasn't meant as a replacement of the auto-generated CSS files, rather I mean't it might make things a bit easier in terms of e.g. the cache-ability of the CSS files as well as giving slightly more control to developers over working with the font files.

I think the query string solution is great in terms of being able to customize the font behaviour more. But in addition to this change, I might be practical to canonicalize the URL used to retrieve the respective font files.

This shouldn't be hard to implement but might de-complicate things over the long run with caching being just one example.

The real question really is: What would be used?

  • Dynamic Serving + Vary Header
  • 301 Redirect + Vary Header
  • 302 Redirect + Vary Header

Any of these options should meet come in handy in terms of e.g. cache-ability but other technical aspects might have to be considered as well.

@superpoincare
Copy link
Author

I might be practical to canonicalize the URL used to retrieve the respective font files.

@Androbin

It's not easy.

The latest browsers get multiple woff2 files depending on the unicode range. So the recent versions of Chrome have separate files for latin, latin-ext, greek, greek-ext. Which the browser downloads depending on whether the page needs it or not.

Older browsers or Edge receive just one font file for a weight and a style.

So there's no one font file really.

@Androbin
Copy link

Androbin commented Sep 27, 2017

@vijayaraghavanramanan
Yeah, I did realize that there are many font files, not one, but they could be redirected to dynamically from single URL the same way that the CSS files uses to .compile the paths.

Current: Static URL -> Dynamic CSS -> Dynamic Font Paths (-> No Redirects)
Suggestion: Static URL -> Static CSS -> Static Font Paths -> Dynamic Redirects -> Dynamic Font Paths

@superpoincare
Copy link
Author

superpoincare commented Sep 27, 2017

@Androbin

Don't know enough to know about redirecting to multiple files, but not the most efficient, I'd imagine.

The way unicode-range works in css font-face rules is that the browser downloads only the fonts necessary. So I don't know how redirecting to multiples can help.

@Androbin
Copy link

@vijayaraghavanramanan
The CSS files would keep the same format but the URL it uses to point to the font files would be static. It doesn't matter if these would serve the font files directly or if they redirect to another URL. All of this can be done by looking at what files the client needs and then using the URL to figure out which unicode-range was requested.

https://fonts.googleapis.com/css?family=Open+Sans [1]
https://fonts.gstatic.com/s/opensans/v14/u-WUoqrET9fUeobQW7jkRRJtnKITppOI_IvcXXDNrsc.woff2 [2]
https://fonts.gstatic.com/s/opensans/v14/cJZKeOuBrn4kERxqtaUH3VtXRa8TVwTICgirnJhmVJw.woff2 [3]
https://fonts.gstatic.com/opensans/latin-ext.woff2 [4]
https://fonts.gstatic.com/opensans/latin.woff2 [5]

[2] would become [4]
[3] would become [5]
[1] would look something like

/* latin-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  src: local('Open Sans Regular'), local('OpenSans-Regular'), url(https://fonts.gstatic.com/opensans/latin-ext.woff2) format('woff2');
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  src: local('Open Sans Regular'), local('OpenSans-Regular'), url(https://fonts.gstatic.com/opensans/latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
}

and the information, that [1] currently uses to determine the respective URL [2] and [3], could then be used to let [4] and [5] serve to font files.

The only thing that would change is that the URL pointing to the individual font files would contain just the information about the font family and the range and would then serve the font file needed using the information sent by the browser otherwise used to compile the CSS file.

@heath3
Copy link

heath3 commented Sep 28, 2017

We currently have the ability to pass through font weights in the request query string (e.g. Roboto:400,700) which adds additional @font-face rules to the response as well as much more complex (to me anyway) functionality like the text parameter which returns a font file containing only a select number of characters. As such this does not seem like too big a task and would be a great 'quick win' for performance

Could the query string functionality not just be amended slightly so we can pass through our font-display preference in the query string too?

e.g. https://fonts.googleapis.com/css?family=Roboto|Merriweather&font-display=swap

OR

To enable different font-display values for each font requested e.g. https://fonts.googleapis.com/css?family=Roboto:font-display-swap|Merriweather:font-display-fallback.

Personally I'd be happy with either solution.

@addyosmani
Copy link

Dropping the font- prefix for consistency (and terseness) sounds reasonable. I believe the plan of record is to make this change before support ships.

@rsheeter
Copy link
Collaborator

Happy to confirm this is coming soon to a Google Fonts near you using the query param display

@superpoincare
Copy link
Author

Working!
image

@coffeeandpixels
Copy link

I think the parameter should be named display because the font- prefix is redundant and the other parameter is called family (and not font-family) as well. So:

https://fonts.googleapis.com/css?family=Roboto&display=swap

So, is that how I use the feature now? 😃

@addyosmani
Copy link

Yup. This will be the final syntax and should be safe to deploy. Per Nathan on the team, the rollout with the display query param is still going live, but should be wrapped up for all regions in the coming days.

@nathan-williams
Copy link
Member

Rollout complete!

@superpoincare
Copy link
Author

Addy,

Any update on @font-feature-values?

But there's a use case for @font-feature-values if someone prefers font-display: block: declare it inline and preload the css instead of loading it the normal way. This has FOIT but still allows the browser to start rendering the page without the google-fonts-css blocking render.

@rsheeter
Copy link
Collaborator

For @font-feature-values please follow w3c/csswg-drafts#2973.

@Androbin
Copy link

Androbin commented Sep 30, 2019

According to https://bugs.chromium.org/p/chromium/issues/detail?id=777846#c10, support for font-feature-values was removed from Chrome.

@superpoincare
Copy link
Author

@Androbin

The feature has been available since a few months now.

That update seems to suggest that font-display via font-feature-values won't fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests