The unicode-range
property in CSS is used by the @font-face
to define the characters that are supported by the font face.
@font-face {
font-family: 'MyWebFont'; /* Define the custom font name */
src: url('myfont.woff2') format('woff2'),
url('myfont.woff') format('woff'); /* Define where the font can be downloaded */
unicode-range: U+00-FF; /* Define the available characters */
}
In other words, @font-face
will refer to the property and determine whether or not it should download and use the font based on whether the characters or range of characters match those in the HTML document.
Font Face: Hey HTML, do any of the following characters match what is on the page?
HTML: Yep, a bunch of them do.
Font-Face: Great, here is a font file you should download to display those characters.
The important semantic distinction we should call out here is that unicode-range
determines what characters a font can be used for, rather than what characters a font is available to use. In other words, if we declare a unicode-range
on @font-face
and the characters that have loaded in an HTML document match that range, then the font will download and be put to use.
You can imagine the performance benefits that open up with this property. For example, we can load a custom font only if it accommodates specific characters rather than always loading the font in all situations.
There’s even a way to combine two @font-face
sets on the on the same font-face
property declaration, thanks to a handy trick shared by Jake Archibald. The idea is that one @font-face
set overrides the other based on the matched unicode-range
, optimizing performance, or simply enhancing the typography on a page.
Values
Any unicode character code or range is an acceptable unicode-range
value. You will notice that unicode points are preceded by a U+
followed by up to six characters that make up the character code. Points or ranges that do not follow this format are considered invalid and will cause the property to be ignored.
- Single Character (e.g.
U+26
) - Character Range (e.g.
U+0025-00FF
) - Wildcard Range (e.g.
U+4??
)
The Wildcard Range is the tricky one of the bunch. Each ?
represents a wildcard where any value will match. You’d think that means you can wildcard the whole thing with something like this:
@font-face {
font-family: 'MyWebFont';
src: url('myfont.woff2') format('woff2'),
url('myfont.woff') format('woff');
unicode-range: U+??????; /* This does not work! */
}
However, this will not work. The reason is that leading with ?
implies a character code that leads with 0
, meaning that up to five question mark characters can be used despite unicodes accepting up to six total characters.
@font-face {
font-family: 'MyWebFont';
src: url('myfont.woff2') format('woff2'),
url('myfont.woff') format('woff');
unicode-range: U+?????; /* This works and is equivalent to U+0????? */
}
There are a ton of unicode options out there. Basic Latin (0020—007F
) is probably the most common range for English sites, but unicode-table.com provides a comprehensive listing of all available ranges with codes for specific characters.
Browser Support
This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.
Desktop
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
36 | 44 | 11 | 17 | 10 |
Mobile / Tablet
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
123 | 124 | 123 | 10.0-10.2 |
Further Reading
- CSS Fonts Module Level 3 Specification
- Unicode Table: A resource to reference unicode character sets and codes.
- Using @font-face: CSS-Tricks post covering how
@font-face
works with different techniques and working examples. - What’s the deal with declaring font properties on @font-face?: CSS-Tricks post that is related as far as how matched values in font properties can be used to determine whether a custom font is downloaded and used by the browser.