First of all I have no idea how TTF files are organized so I might have some of my terminology wrong here.
I have a stylesheet with a @font-face
that references a single TTF file that has multiple faces in it. In the Windows font viewer it looks like this if I cycle through "next" (sorry, GIF got messy, picked bad encoding parameters, didn't feel like redoing it, but you get the drift):
The file has a .ttf extension although I'm not sure what the relationship is to OpenType (it says "OpenType" in that window).
Anyways, I reference it like this in the stylesheet:
@font-face {
font-family: TestFont;
src: url(...) format('truetype');
}
:root {
font-family: TestFont;
}
So, the font name in the file is "Bahnschrift", and the face I want to use is "Bahnschrift Condensed". The above almost works except it uses the base "Bahnschrift" font.
My question is: How do I specify that I want to use the "condensed" variant instead?.
Here's a fiddle. I wanted to embed the font as a data URI just for this post, but it was too large to post here (about 500kB encoded) so it's here instead: https://jsfiddle.net/qugoeam5/
Ok, I mostly figured it out. I've got a fundamental solution, I just don't have the browser compatibility nailed down.
So what I called "variants" are actually called "instances". Essentially, they're just named presets (stored in the file) that specify values for a collection of OpenType axes.
The Windows 10 built in font inspector can be used to inspect the axis/value sets for a given instance, presuming the font is installed on the system and is a variable font:
Open Font Settings
Search for and select the font under "Available Fonts"
In the next windows that opens, scroll all the way down and click "Variable Font Properties".
Here you can select the instance then go through each axis to see its tag and value:
So for the "Condensed" instance, weight (wght) is 400 and width (wdth) is 75.
As for the CSS, compatibility is currently spotty. CSS3 doesn't have a way to select a named instance. It also doesn't officially have support for setting axis values. CSS4, though, is standardizing support for both (font-named-instance and font-variation-settings).
Now, I don't know the history here, but I think font-variation-settings
(set individual axis values) was maybe intended for CSS3 at some point, then deferred to CSS4? Or something. In any case, it seems that:
So the general solution here is to individually set the axis values that correspond to the named instance you want (at least until font-named-instance
rolls around).
The good news is, there are more widely supported high-level equivalents for certain axes; and in this case I got lucky: For this font only weight and width are set, which can be set by font-weight
and font-stretch
. Still, font-stretch
support is also a bit inconsistent right now (depending on whether or not you use the named form vs. the % form).
Anyways, I can't speak for compatibility, but there are a number of options here.
font-weight: 400
font-weight: normal
font-variation-settings: "wght" 400;
font-stretch: 75%
font-stretch: condensed
font-variation-settings: "wdth" 75;
font-variation-settings
, if you set more than one they all have to be set at once:
font-variation-settings: "wght" 400, "wdth" 75;
Settings in the face definition:
@font-face {
font-family: "TestFont";
src: ...;
[ one of the width settings ];
[ one of the stretch settings ];
}
:root {
font-family: "TestFont";
}
Or, outside of the @ rule:
@font-face {
font-family: "TestFont";
src: ...;
}
:root {
font-family: "TestFont";
[ one of the width settings ];
[ one of the stretch settings ];
}
So, putting all that together, an example of one option (compatibility notwithstanding) is:
@font-face {
font-family: 'TestFont';
src: ...;
font-weight: normal;
font-stretch: condensed;
}
:root {
font-family: 'TestFont', sans-serif;
}
Now, I haven't really tested on lots of browsers yet, but here are the combinations of the above that at least appear to work on Chrome 90.0.4430.93 (Windows 10, 64-bit). YMMV:
@font-face{} |
:root{} |
div{} |
|
---|---|---|---|
[W1] font-weight:400 |
YES | YES | YES |
[W2] font-weight:normal |
YES | YES | YES |
[W3] font-variation-settings:"wght" 400 |
no | YES | YES |
[S1] font-stretch:75% |
YES | no | no |
[S2] font-stretch:condensed |
YES | no | no |
[S3] font-variation-settings:"wdth" 75 |
no | YES | YES |
[WS3] font-variation-settings:"wght" 400,"wdth" 75 |
no | YES | YES |
Which means that, at least for Chrome:
If you want to put both in @font-face
, you have to use [W1/2] + [S1/2], e.g.:
@font-face {
font-family: "TestFont";
src: ...;
font-weight: normal;
font-stretch: condensed;
}
:root {
font-family: "TestFont", sans-serif;
}
But if you want to put both in :root
or another element, you can use any form for the weight but you have to use font-variation-settings
for the width (valid combos would be [W1+S3], [W2+S3], or [WS3]), e.g.:
@font-face {
font-family: "TestFont";
src: ...;
}
:root {
font-family: "TestFont", sans-serif;
font-weight: normal;
font-variation-settings: 'wdth' 75;
}
I have no idea what the behavior is on other browsers; I haven't done any more tests, mostly because this post was kind of exhausting, and took like 100x longer to type than it did for me to actually figure all this out, lol.
Hope that gets somebody pointed in the right direction. Once CSS4 hits the streets, this will all theoretically be a lot simpler.