I hope you read that title out loud in your best Seinfeld impression.
A recent question in our forums made me aware that there are more properties that can be added to @font-face
than the usual font-family
and src
suspects. What are the point of those? Why would you want to declare other font declarations there?
I’m used to writing @font-face
essentially like this:
@font-face {
font-family: "My Custom Font";
src: url("path/to-font-file.woff2");
}
But the spec does indeed include more descriptors:
@font-face {
font-family: <family-name>;
src: <url>;
unicode-range: <urange>;
font-variant: normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ];
font-feature-settings: normal | <feature-tag-value>;
font-stretch: normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded;
font-weight: normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
font-style: normal | italic | oblique;
}
You’ll see this plenty when looking at @font-face code generated by font services.
They are the gatekeepers!
That’s an analogy you can use to think about @font-face declaration blocks. The font will be downloaded and used, if it passes the gatekeepers.
The font-family is the obvious one. You’re declaring a new font-family to use, so any element that wants to use this font needs to have a matching one.
@font-face {
/* Gatekeeper: font-family on another element must match this to be used. */
font-family: 'Open Sans';
src: url(my-font.woff2) format('woff2');
}
body {
/* Match! */
font-family: 'Open Sans';
}
h1, h2 {
/* No match */
font-family: 'Different Font';
}
They are (mostly) all gatekeepers
With exception to font-variant
and font-feature-settings
, all of the properties can be used as filters that instruct the browser to download and use the font files when the values match.
@font-face {
/* Only download and use if element matches this font-family */
font-family: 'My Font';
/* Only download and use if element matches this font-style */
font-style: italic;
/* Only download and use if element matches this font-weight */
font-weight: 700;
src: url(my-bold-and-italic-font.woff2) format('woff2');
/* Only download and use if these characters are used */
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
}
Something like Apstract Class …
Interesting, I knew about
font-weight
&font-style
, but notunicode-range
. Glad to learn of it. Time to optimize!Cheers Geoff. Helped me out!
Man. I’ve never thought of it like that. So it only downloads when matched? I’m going to have to play with that. Thanks!
Looks like this will free some bandwidth !
My Comment here. I’m cool cuz i only uze terminal fonts all da taim
I never saw it from this perspective before and certainly didn’t know that it affected font loading. Great to know, thank you.
I use the font attributes a lot, so I was surprised that you didn’t mention the more obvious aspect: It simply allows you to access different
font-weight
s andfont-style
s of the same font using the samefont-family
declaration (which is the way I assume fonts are intended to be used in CSS).So instead of having to replace the entire font-stack in the “font-family” property of my CSS, I can just change the
font-weight
tobold
and keep using the samefont-family
. It also helps avoiding lots of cryptic font names such as “MyFontBld” and “MyFontBldCnIt”.That’s kinda what I thought, too. However, in testing that out, it appears that the browser is unable to style a font that doesn’t have the properly styled glyphs. So, for example, you can set
font-style: italic;
on@font-face
, but that will not cascade down to the element if the font file is missing italic characters: http://codepen.io/team/css-tricks/pen/YqVeErSame is true with system files, even with the proper styles: http://codepen.io/team/css-tricks/pen/wGdyNN
@Geoff, the way I understand it is that when inside a
@font-face
declaration,font-weight
andfont-style
don’t set any page styles; rather, they associate a font file with a specific style. Essentially it says “this is the Normal weight, Regular font. This is the Normal weight, Italic font. This is the Bold weight, Regular font”, etc.So whenever an element – say, an
<em>
– calls for a specific display type, the browser says “oh, you want Italic? OK, this is the file I should use for that”.Your first example works when I add the line
font-style: italic
to theh1
’s declaration – because the element is now asking for a bold, italic font, it displays the proper font file: http://codepen.io/smcginnis/pen/eZGZvP?editors=1100 (sorry for the color change, btw, the red was hurting my eyes).In your second example, the name Arial is not associated with any font file, so the
@font-face
block isn’t actually doing anything. Within the@font-face
block, thefont-family
property behaves differently than within a selector block; here, rather than setting the font, it merely says “when this font name is requested, look here for the font file”. If you add the linesrc: local("Arial");
*, it will work for any child element that asks to be Italic. http://codepen.io/smcginnis/pen/EKwKoz?editors=1100Rereading the article, it seems that you probably know this already, and perhaps you just weren’t sure what Nils was saying. But I thought it was worth commenting anyway, in case anyone else needs the information.
* I actually changed it to Georgia in my fork, so that you can see that even though the
h1
is rendered with Arial, which it asks for, theem
inside it is rendered with the actual font file that the@font-face
block tells it to use for Arial 700 Italic. I also had to remove the CSS Reset from both forks, since it was messing up the default weight and style for the elements.Yep, we’re totally on the same page, dude. :)
For better coding and for better reading, I think giving same font-name with different font-style and font-weight works better.
So,
I said coding considering CSS as coding. I feel like coding…