Fonts are essential to CSS and all web designers know how to set the size, weight and the style of fonts. In the past, a fixed number of font properties were available. Variable fonts change this by adding gliding scales between normal and bold. Or between italic and normal. Or between any axis the font designer chooses to expose. The many choices can be bewildering, but this guide will help.
Variable fonts are supported by common browsers, and by recent builds of Prince. Prince also has has a nifty feature to peek into variable font files to see which variations are available.
Documents showcased in this guide also work in common browsers. To try, click on the html
link on the right.
Web designers commonly use CSS properties to make text bold, or italic. You don't need variable fonts for this:
htmlstrong { font-weight: bold } em { font-style: italic }
Variable fonts extend the established CSS font model through new axes
. Font designers can add new axes to the font files they create, and CSS style sheets can change the appearance of fonts by addressing these axes.
For example, slanted text can be achieved today by setting font-style: italic
. With variable fonts, style sheets can gain more fine-grained control by setting the angle of slanting, in degrees. There is no new CSS property for this, instead we use the generic font-variation-settings
property to set a value on the slnt
axis.
html.slnt0 { font-variation-settings: 'slnt' 0 } .slnt5 { font-variation-settings: 'slnt' -5 } .slnt10 { font-variation-settings: 'slnt' -10 } .slnt15 { font-variation-settings: 'slnt' -15 }
The 'slnt' axis is named by the font designer. All axes (which is the plural of axis
) have a four-letter name. Some fonts follow a convention of using lowercase names for axis that can also be addressed by a common CSS property. This is our next example.
The font-variation-settings
property used in the previous example is the main interface between CSS and the axes in variable fonts. However, some axes can be mapped to traditional CSS properties which are extended with new values. For example, the font slant can also be set with the font-style
property:
html.style0 { font-style: oblique 0deg } .style5 { font-style: oblique 5deg } .style10 { font-style: oblique 10deg } .style15 { font-style: oblique 15deg }
Note how CSS uses positive values for clockwise slanting, while values were negative in the previous example.
You can do some truly hairy stuff with variable fonts. The CoronaFaceImpact font will grow on you:
html.weekone { font-variation-settings: 'hscl' 0, 'hdrs' 0, 'fmsk' 0 } .weektwo { font-variation-settings: 'hscl' 0, 'hdrs' 50, 'fmsk' 0 } .weekthree { font-variation-settings: 'hscl' 0, 'hdrs' 100, 'fmsk' 0 }
Note how the font-variation-settings
property takes a comma-separated list of axis names and values. This makes it very powerful, but also vulnerable; you cannot change a setting in a descendant element without repeating the comma-separated list.
To use variable fonts in your own documents, we recommend downloading fonts to your own computer. You can find variable fonts from sites like Google fonts and V-fonts.
This example will show you how to download and use the Recursive
font from Google fonts:
Recursive
Get font
Download
A zip-file will now be downloaded to your computer. Unzip the file in a directory of your choice. The zip file contains the variable font, but also static font files that are stored in a sub-directory. These static fonts can be deleted.
You are now left with one TTF file. To use this font in Prince, you must generate an index file with a @font-face
declaration. Prince will happily peek inside the font file and generate the index file:
$ prince --scanfonts *ttf > index.css
The file index.css
now contains a @font-face declaration, as well as a list of the axes:
/* Recursive */ /* Variation Axes: MONO: 0..1 (default: 0) # Monospace CASL: 0..1 (default: 0) # Casual CRSV: 0..1 (default: 0.500000) # Cursive font-variation-settings: 'CRSV' 0.500000, 'slnt' 0, 'wght' 300, 'CASL' 0, 'MONO' 0; */ @font-face { font-family: "Recursive"; font-weight: 300 1000; font-style: oblique 0deg 15deg; font-stretch: normal; src: url("Recursive-VariableFont_CASL,CRSV,MONO,slnt,wght.ttf") }
The line starting with font-variation-settings
is important – it lists all axes found in the font. For the Recursive font, there are five: 'CRSV', 'slnt', 'wght', 'CASL', 'MONO'. The two lowercase axes are mapped to font-style
and font-weight
, respectively.
It is possible to use variable fonts hosted by others. However, some sites are sensitive to the User-Agent
HTTP header when a font is requested. This is the case for Google fonts. Consider this example:
<html> <style> @import url('https://fonts.googleapis.com/css2?family=Recursive:slnt,wght,CASL,CRSV@-15..0,300..1000,0..1,0..1'); p { font: 30pt Recursive } .slnt0 { font-variation-settings: 'slnt' 0 } .slnt5 { font-variation-settings: 'slnt' -5 } .slnt10 { font-variation-settings: 'slnt' -10 } .slnt15 { font-variation-settings: 'slnt' -15 } </style> <body> <p><span class=slnt0>'slnt' 0</span> <p><span class=slnt5>'slnt' -5</span> <p><span class=slnt10>'slnt' -10</span> <p><span class=slnt15>'slnt' -15</span> </body> </html>
In order for Prince to find the variable fonts, you must use the user-agent
command-line option:
prince --user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:121.0) Gecko/20100101 Firefox/121.0" sample.html
We hope Google Fonts will be updated so that Prince is supplied with variable fonts without having to masquerade as a browser.