Using specific face for @font-face in TTF file containing multiple faces

(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 embedded the font as a data URI for this post: https://jsfiddle.net/qugoeam5/

I think you have to use the proper font family name of the variant.

Searching for the font I found that Bahnschrift Font is a semibold condensed typeface that includes these varians in the font family:

Bahnschrift Book Italic
Bahnschrift Medium Italic
Bahnschrift SemiBold Italic
Bahnschrift Bold Italic
Bahnschrift ExtraBold Italic
Bahnschrift Heavy Italic
Bahnschrift Ultra Italic
Bahnschrift Regular

Quoted https://boldfonts.com/bahnschrift-font/

The proper variant name can’t be tested in your Jsfiddle as it seems to use another font family. :wink:

Thanks! Actually, I just figured it out a few minutes ago and came back to post.

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:

  1. Open Font Settings

  2. Search for and select the font under “Available Fonts”

  3. In the next windows that opens, scroll all the way down and click “Variable Font Properties”.

  4. 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:

  • There is support for it in Edge, Firefox, and Chrome, but lack of support in IE and Safari. Among other.
  • There seems to be more support for it when it’s used outside of @ rules. I couldn’t find any information about why, I just observed it.

So the general solution here is to individually set the axis values that correspond to the named instance you want.

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.

  • Compatibility aside, these are all equivalent for the weight:
    • [W1] font-weight: 400
    • [W2] font-weight: normal
    • [W3] font-variation-settings: "wght" 400;
  • And these are all equivalent for the width:
    • [S1] font-stretch: 75%
    • [S2] font-stretch: condensed
    • [S3] font-variation-settings: "wdth" 75;
  • Note: For font-variation-settings, if you set more than one they all have to be set at once:
    • [WS3] font-variation-settings: "wght" 400, "wdth" 75;
  • Again ignoring compatibility, those can be placed either in an @ rule (to define the default), or elsewhere (to override the default), so both of these are also equivalent:
    • 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]        yes         yes         yes
   [W2]        yes         yes         yes
   [W3]         no         yes         yes

   [S1]        yes          no          no
   [S2]        yes          no          no
   [S3]         no         yes         yes

   [WS3]        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.

3 Likes

Thanks for the feedback!

Thanks for the MS link. That was new, I guess “instances” isn’t a CSS term. Yet?

More info about the css font-variant property:
https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant

More on browser compatibility:
https://caniuse.com/?search=variant

PS

The font family specified in @font-face is arbitrary (except it can’t be a CSS keyword, iirc) and user-defined, and not connected to the family name defined in the linked file, which is ignored. :slight_smile:

1 Like

Thanks again for details. I have so much to learn, new stuff every day

1 Like