Implement Custom Fonts with CSS @font-face and font-display

Article By Rawat Digamber on
CSS @font-face will be explored in detail in this article. In order to use custom fonts on your web page, we can use the CSS @rule named @font-face. If you have font files hosted in the same server, you can use @font-face to provide a path to the font file.

As per the rule, the font files have to be in the same server. Well, this rule has been in use for a while now. But we are going to focus on the new property named font-display, which opens new doors.

Fundamental usage of @font-face in CSS

First and foremost, you should define all @font-face at-rules in the main CSS file. The rule is supposed to have src properties and font-family in the basic form. Let’s take a look an example below:

@font-face {
  font-family: 'Open Sans';
  src: url('/assets/fonts/open-sans.woff2') format('woff2'), 
  url('/assets/fonts/open-sans.woff') format('woff');
}

The font-family value will be the font name you will be using on the page:

h1 {
  font-family: 'Open Sans';
}

As for the src values, we go with 2 values. The first value is meant for the font in modern woff2 format. However, it is not supported across all browsers. Therefore, we provide a fallback value in woff format so that it works everywhere without any issues.

This should be enough. However, you can go for more number of fallbacks if necessary:

@font-face {
   font-family: 'Open Sans';
   src: url(/assets/fonts/open-sans.woff2) format('woff2'), 
   url(/assets/fonts/open-sans.woff) format('woff'), 
   url(/assets/fonts/open-sans.ttf) format('truetype');
}

@Font Face Local version

In case if you are using a font is really popular, there might be a local version of it on their device. In that case, you can give a local value first:

@font-face {
   font-family: 'Open Sans';
   src: local("Open Sans"), 
   url(/assets/fonts/open-sans.woff2) format('woff2'), 
   url(/assets/fonts/open-sans.woff) format('woff');
}

Understanding Style Linking of @font-face

As we have already mentioned, you start with defining the font path and name. Besides this, you can also define certain properties. Those properties include font-stretch, font-weight, font-variant, font-style etc. This can be incredibly helpful if you intend to use different variations of the font on the web page:

@font-face {
     font-family: 'Open Sans';
     src: local("Open Sans"), 
     url(/assets/fonts/open-sans.woff2) format('woff2'), 
     url(/assets/fonts/open-sans.woff) format('woff');
}

@font-face {
     font-family: 'Open Sans';
     src: url(/assets/fonts/open-sans.woff2) format('woff2'), 
     url(/assets/fonts/open-sans.woff) format('woff');
     font-weight: 300;
     font-style: italic;
}

Well, we are going to elaborate the same with an example below. For instance, you can use a regular version of the font for p elements whereas you can use a Light Italic version of the font for h1 elements.

h1, p {
     font-family: 'Open Sans', sans-serif;
}

h1 {
     font-weight: 300;
     font-style: italic;
}

CSS font-display

As we all know, @font-face is not a new thing. However, font-display is entirely new. This gives you better control as far as font loading is concerned.

When you use custom fonts, you might experience a FOIT (flash of invisible text) or a FOUT (flash of unstyled text) when you load the page for the first time. In the case of specific browsers, they will show the text right away even before the custom font is loaded. Moreover, they revert to the custom font once it is fully loaded. This is what leads to FOUT. Also, in the case of other browsers, the text will be hidden until the custom font is loaded. And if the font fails to load within a stipulated time frame, then they will opt for the fallback font.

If you wish to deal with FOUT effectively, then we recommend using a tool like Font Style Matcher. This will be quite useful in finding a fallback font which is quite similar to the custom font. In this case, the font change will not look like a drastic change.

Thanks to font-display, we are in a position to control font loading as per our wishes:

 @font-face {
     font-family: 'Open Sans';
     src: url(/assets/fonts/open-sans.woff2) format('woff2'), 
     url(/assets/fonts/open-sans.woff) format('woff');
     font-display: swap;
     font-weight: 300;
     font-style: italic;
}

Font-display in CSS is equipped to take one of the following 5 values:

PropertyDetail
auto:Here it will exhibit the default behavior, which might not be the same for all browsers.
block:Here, in this case, the text will be hidden for a limited period. Also, it will be reverted to custom font when it is made available. This option comes with an infinite swap period.
font-display:optional is what used for titles here. The user will be greeted with a fallback option on the first visit. Moreover, when you visit more pages, you will be greeted by the custom font. Let’s have a look below:
swap:Here text will not be hidden. Moreover, it will be reverted to the custom font once it is made available. Once again, it provides infinite swap period.
fallback:Here, in this case, the text will be hidden for a limited period (also named block period). It comes with limited swap period. The custom font has to appear within the swap period. Else, it will not be loaded.
optional:It is the new option. Well, it provides an excellent solution to the loading problems we have been facing. Here, in this case, you only get a 100ms block period for the custom font to load. If it fails to load within this time frame, the fallback font will be used. The custom font will not be loaded at all. However, downloading and caching will be happening behind the scenes. Alternatively, in other words, the custom font will be loaded in the subsequent page loads as it will be convenient to access it from the cache.
@font-face {
     font-family: 'Open Sans';
     src: url(/assets/fonts/open-sans.woff2) format('woff2'), url(/assets/fonts/open-sans.woff) format('woff');
     font-display: optional;
}

h1 {
     font-family: 'Open Sans', "Aerial", 'Helvetica', sans-serif;
     font-style: italic;
     font-weight: 300;
}

It only has one drawback – support for font-display is not that great.

Feel free to contact me, If you are looking for a freelance web and mobile app developer in India, with the following skills: Angular JS, Angular 2+, Node JS, Firebase, MongoDB, Ionic Framework and WordPress.

I also offer remote contracting services to clients across the globe.

Get Started