tl;dr: Google's font CDN isn't serving the fonts in their fullness. Download the zip they offer and host the fonts yourself.
Google's font CDN doesn't seem to be providing the full character range of some fonts. For example, Google's @import
is:
@import url('https://fonts.googleapis.com/css2?family=Fira+Code&display=swap');
Looking at the CSS inside:
/* cyrillic-ext */
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/firacode/v14/uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sJV37Nv7g.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/firacode/v14/uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sJVT7Nv7g.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* more chunks like this omitted */
So the font is broken up into several files and they use unicode-range
to map glyphs to specific files.
These are all the ranges they provide in that file:
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
unicode-range: U+1F00-1FFF;
unicode-range: U+0370-03FF;
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
The range for the box drawing characters is U+2500-257F
which doesn't show up in the above list.
I tried adding them in but, as far as I can tell, the served files do not include that range.
However, you can download the original font files from Google (as a zip of .ttf files). Converting one of those font files into a data url and using it does render the glyphs correctly:
pre {
font-family: 'Fira Code stripped';
}
@font-face {
font-family: 'Fira Code stripped';
src: url('data:application/octet-stream;base64,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');
}
<pre>
╭────────────────────────────────────────────╮
│............................................│
│--------------------------------------------│
│ │
╰────────────────────────────────────────────╯
</pre>
NOTE: In order to fit this example into an answer, I've stripped the font down to just the 9 characters needed to render the sample and converted it to woff2. External testing with the full ttf file produces the same results.
I conclude that Google simply isn't serving the complete font via their CDN.