Jss: font-face fallback order

Created on 5 Sep 2018  路  22Comments  路  Source: cssinjs/jss

Example:

'@font-face': {
    fontFamily: '"icon-fonts"',
    src: `url(/assets/fonts/icon-fonts.eot)`,
    fallbacks: [
      { src: `url(/assets/fonts/icon-fonts.eot?#iefix) format(embedded-opentype)` },
      { src: `url(/assets/fonts/icon-fonts.ttf) format(truetype)` },
      { src: `url(/assets/fonts/icon-fonts.svg#icon-fonts) format(svg)` },
      { src: `url(/assets/fonts/icon-fonts.woff) format(woff)` },
      { src: `url(/assets/fonts/icon-fonts.woff2) format(woff2)` },
    ],
    fontWeight: 'normal',
    fontStyle: 'normal',
}

Expected:

@font-face {
  font-family: "icon-fonts";
  src: url(/assets/fonts/icon-fonts.eot);  
  src: url(/assets/fonts/icon-fonts.eot?#iefix) format(embedded-opentype),
     url(/assets/fonts/icon-fonts.ttf) format(truetype),
     url(/assets/fonts/icon-fonts.svg#icon-fonts) format(svg),
     url(/assets/fonts/icon-fonts.woff) format(woff),
     url(/assets/fonts/icon-fonts.woff2) format(woff2);
  font-weight: normal;
  font-style: normal;
}

Received:

@font-face {
  src: url(/assets/fonts/icon-fonts.eot?#iefix) format(embedded-opentype);
  src: url(/assets/fonts/icon-fonts.ttf) format(truetype);
  src: url(/assets/fonts/icon-fonts.svg#icon-fonts) format(svg);
  src: url(/assets/fonts/icon-fonts.woff) format(woff);
  src: url(/assets/fonts/icon-fonts.woff2) format(woff2);
  font-family: "icon-fonts";
  src: url(/assets/fonts/icon-fonts.eot);
  font-weight: normal;
  font-style: normal;
}

due to fallback goes first, browser does not load fonts properly

docs question

All 22 comments

I think you need to reverse the order of what you consider to be a fallback. CSS will fall back to a previously defined property if the next one fails.

a {
  color: fallback;
  color: unsupported
}

So fallback properties should always be defined first.

Second point: you want a src property with multiple values, comma separated. This is also supported:

{
  '@font-face': {
      fontFamily: '"icon-fonts"',
      src: `url(/assets/fonts/icon-fonts.eot)`,
      fallbacks: {
        src: [
          `url(/assets/fonts/icon-fonts.eot?#iefix) format(embedded-opentype)`, 
          `url(/assets/fonts/icon-fonts.ttf) format(truetype)`, 
          `url(/assets/fonts/icon-fonts.svg#icon-fonts) format(svg)`,
          `url(/assets/fonts/icon-fonts.woff) format(woff)`,
          `url(/assets/fonts/icon-fonts.woff2) format(woff2)`
          ] 
      },
      fontWeight: 'normal',
      fontStyle: 'normal',
  }

}

@kof In your case fallback renders first and browser doesn't load fonts properly. But once I put /assets/fonts/icon-fonts.eot in fallbacks and rest of fonts in src browser loads woff2 font.

Is this actually resolved/not an issue? On both v9 and v10-alpha.16 supplying fallbacks as shown in the docs produces invalid CSS. I also tried the method shown above and had the same result (one produces a single src for fallbacks while the other produces many, but both are invalid as the fallbacks appear before the font-family and initial src):

@font-face {
  src: url(font-icons.eot?#iefix) format(embedded-opentype), url(font-icons.woff) format(woff), url(font-icons.ttf) format(truetype), url(font-icons.svg#lumi-font-icons) format(svg);
  font-family: font-icons;
  src: url(font-icons.eot);
  font-weight: 400;
  font-style: normal;
}

@spicydonuts I just swapped values of src and fallbacks instead of speaking with silence

Wouldn't that still be invalid? (assuming you mean swapping the src values in my example output) I'm not sure what you mean by "speaking with silence".

We consider the API works as described, fallbacks in CSS are supposed to be rendered first.

I'm still not sure I understand. Are you saying this is the correct way to define these for IE support?

@font-face {
  src: url(font-icons.woff) format(woff);
  font-family: font-icons;
  src: url(font-icons.woff2);
}

the one that you consider to be fallback comes first in css

So the main src defined in JSS is meant to be the last font in the list and fallbacks resembles the common pattern of grouping the available src's but isn't really meant to be the same thing, and the docs just don't reflect this yet?

Can you point me to the place in the docs that is confusing?

The last example in this section on font face: https://cssinjs.org/jss-syntax?v=v10.0.0-alpha.16#font-face

I am guessing here: the fact that in JSS fallbacks key can be placed in any order, but the fallback properties always land before the actual property once it's compiled to CSS, is what makes this confusing?

Which seems to line up with how font face is usually explained (a src entry for eot and a list of others, but that seems like an arbitrary development unless it was a necessary IE hack at some point): https://www.w3docs.com/learn-css/font-face.html

The way you've explained it here makes sense, once I dropped the way I was expecting to see it. I think it's just old conventions floating around in projects and examples combined with that particular example in the docs not matching the actual JSS output.

How can we make it better or more clear?

For the code as-is probably just updating the example output to match the real output (and probably updating both so the woff2 is last):

@font-face {
  src: url(webfont.eot?#iefix) format(embedded-opentype);
  src: url(webfont.woff2) format(woff2);
  font-family: 'MyWebFont';
  src: url('webfont.eot');
}

Another approach could be to remove fallbacks entirely and just allow src to be an array:

const styles = {
  '@font-face': {
    fontFamily: 'MyWebFont',
    src: [
      'url(webfont.eot)',
      'url(webfont.eot?#iefix) format(embedded-opentype)',
      'url(webfont.woff2) format(woff2)'
    ]
  }
}
@font-face {
  font-family: 'MyWebFont';
  src: url('webfont.eot'),
    url(webfont.eot?#iefix) format(embedded-opentype),
    url(webfont.woff2) format(woff2);
}

(or an array of { src: ... } to output the same thing as separate src properties)

Array syntax is already used for complex values, that's why we have fallbacks syntax in the first place, it was intentional. Let's try fixing the examples

@kof Could you help me please understand what is the right way to implement @font-face with fallbacks? Right now the following approach works for me

'@font-face': {
    fontFamily: '\'Socicon\'',
    src: [
      `url('${eotFont}')`,
      `url('${eotFont}?#iefix') format('embedded-opentype')`,
      `url('${ttfFont}') format('truetype')`,
      `url('${woffFont}') format('woff')`,
      `url('${woff2Font}') format('woff2')`,
      `url('${svgFont}') format('svg')`,
    ],
    fontWeight: 'normal',
    fontStyle: 'normal',
  }

feel free to try on https://cssinjs.org/repl mb that helps, fallbacks are documented, you need to provide a very specific question

@kof So, here is a real-life example: https://codesandbox.io/s/6n0k5npqpk. Once you comment line 14, it will start work. Does it make any sense for you?

@kof could you check the example above please?

Based on this awesome article about font loading I prefer to use these fonts:

1. woff2
2. woff
3. ttf

Or in some cases that IE is not important, just use woff2 only. so now I prefer to write my @font-face just like below:

import yekanRegularWoff2 from '../app/assets/font/iranyekanwebregular.woff2';
import yekanRegularWoff from '../app/assets/font/iranyekanwebregular.woff';
import yekanRegularTtf from '../app/assets/font/iranyekanwebregular.ttf';
import yekanRegularEot from '../app/assets/font/iranyekanwebregular.eot'; // just for sure



'@font-face': [
  {
    fontFamily: 'IRANYekan',
    fontStyle: 'normal',
    fontWeight: 400,
    src: `url(${yekanRegularWoff2}) format('woff2')`,
    fallbacks: {
      src: [
        `url(${yekanRegularWoff})`,
        `url(${yekanRegularTtf}) format('truetype')`,
        `url(${yekanRegularEot})`, // just for sure
        `url(${yekanRegularEot??#iefix) format('embedded-opentype')`, // just for sure
      ],
    },
  },
]
Was this page helpful?
0 / 5 - 0 ratings

Related issues

brianmhunt picture brianmhunt  路  5Comments

oliviertassinari picture oliviertassinari  路  4Comments

HenriBeck picture HenriBeck  路  4Comments

synchronos-t picture synchronos-t  路  4Comments

Telokis picture Telokis  路  3Comments