zachleat’s Ugly Mug

Zach Leatherman

Font Aliasing, or How to Rename a Font in CSS

15 June 2017 Read this in about 9 minutes.

Are you tired of developers abusing the smooth traditionalism of Helvetica? Do you wish your web page was a little bit more fun? Do you also want to avoid discussing things with your peers? Well, do I have some code for you. Add this little block into your project and it will globally alias (rename) Helvetica to Comic Sans MS (and Chalkboard SE, browser support). (Yes, I know I recently wrote a blog post about anti-aliasing—that’s a different thing.)

@font-face {
	font-family: Helvetica;
	src: local(Comic Sans MS), local(Chalkboard SE);
}

If you follow me on Twitter, you may have seen this idea before in 2015, and, uh, also in 2014.

<p style="font-family: Helvetica">This is an end-around for any font family properties you have specified, no matter the block’s selector specificity. Think you can use !important to override? Think again.</p>

Let’s check the specification:

If the font family name is the same as a font family available in a given user’s environment, it effectively hides the underlying font for documents that use the stylesheet. This permits a web author to freely choose font-family names without worrying about conflicts with font family names present in a given user’s environment.

The specification allows for this because the alternative—worrying about naming conflicts on every user agent—would be horrific!

Valid local()’s

What are valid values for local()? If you’re think you can just add any font-family name—no, not quite. Let’s consult the specification again:

The locally installed <font-face-name> is a format-specific string that uniquely identifies a single font face within a larger family.

For OpenType and TrueType fonts, this string is used to match only the Postscript name or the full font name in the name table of locally available fonts. Which is used varies by platform and font, so authors should include both of these names to assure proper matching across platforms.

Okay, we feed local() a PostScript or Full Font name. How do we find those?

If you have Mac OS, open up the default font browser—Font Book—and select a font. In the menu bar, select View ➡ Show Font Info and the right pane will show both the PostScript name and Full name values.

How to find the Full Font and PostScript font names in Font Book

Keep in mind that you can’t override generic family keywords, like serif, sans-serif, cursive, fantasy, or monospace. Not even if you quote them in your font-family property, although pedantically speaking this should probably work since font-family: "serif" refers to something different than font-family: serif.

Facebook’s San Francisco Trick

Sometimes I casually browse how different web sites I’m visiting are using @font-face. I stumbled upon Facebook using this trick to their advantage in a clever way. Have a look:

@font-face {
	font-family: 'San Francisco';
	font-weight: 300;
	src: local('-apple-system')
}

@font-face {
	font-family: 'San Francisco';
	font-weight: 400;
	src: local('.SFNSText-Regular')
}

@font-face {
	font-family: 'San Francisco';
	font-weight: 500;
	src: local('-apple-system')
}

@font-face {
	font-family: 'San Francisco';
	font-weight: 600;
	src: local('-apple-system')
}

@font-face {
	font-family: 'San Francisco';
	font-weight: 700;
	src: local('.SFNSText-Semibold')
}

@font-face {
	font-family: 'San Francisco';
	font-weight: 800;
	src: local('-apple-system')
}

#facebook ._-kb.sf {
	font-family: San Francisco, -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', sans-serif;
}

Very cool! They’ve aliased a bunch of local references in the @font-face sources to simplify their font-family property value a bit, varying local sources by font-weight. Let’s dive in with some reduced/separated demos and test cases to fully understand it.

Update: I discovered later that the System Font CSS project used this approach back in 2015, likely predating Facebook’s implementation.

Live Demos

Note: The fallbacks in the demos below are mapped to fantasy. If you see fantasy, the alias didn’t work. On Apple products (where San Francisco is likely to be available) fantasy renders as Papyrus.

-apple-system

@font-face {
	font-family: San Francisco Apple System;
	src: local(-apple-system);
}

San Francisco aliased from local(-apple-system) Supported in Safari (Mobile and Desktop) and Not Supported in Chrome, Firefox (as of 54)

BlinkMacSystemFont

@font-face {
	font-family: San Francisco Blink;
	src: local(BlinkMacSystemFont);
}

San Francisco aliased from local(BlinkMacSystemFont) Not Supported in Chrome, Firefox (as of 54), Safari (as of 10.1)

PostScript Names

@font-face {
	font-family: San Francisco PostScript Name;
	src: local(.SFNSText-Regular);
}

San Francisco aliased from local(.SFNSText-Regular) Not Supported in Chrome, Firefox (as of 54), Safari (as of 10.1)

@font-face {
	font-family: San Francisco PostScript Name Quoted;
	src: local('.SFNSText-Regular');
}

San Francisco aliased from local('.SFNSText-Regular') Supported in Firefox, Safari (Desktop) and Not Supported in Chrome, Mobile Safari

system-ui

Standardization is taking place around the system-ui value, hopefully coming soon to Can I Use. Even better—looks like Chrome has moved forward with this!

Not aliased at all, just using font-family: system-ui Supported in Chrome and Not Supported in Firefox (as of 54), Safari (as of 10.1)

And Chrome’s implementation supports using it as an alias source too! Given that BlinkMacSystemFont did not work as an alias source, I was delighted to see that system-ui did.

@font-face {
	font-family: San Francisco System UI;
	src: local(system-ui);
}

San Francisco aliased from local(system-ui) Supported in Chrome and Not Supported in Firefox (as of 54), Safari (as of 10.1)

Final, Reduced Code

Combining the above test cases results in a simplified version of the San Francisco alias that works in Chrome, Safari (Desktop and Mobile), and Firefox. Notably, this renders BlinkMacSystemFont unnecessary. It also doesn’t require any additional values in the font-family properties littered throughout your CSS. Clean and efficient!

@font-face {
	font-family: My San Francisco Alias;
	src: local(system-ui), local(-apple-system), local('.SFNSText-Regular');
}
p {
	font-family: My San Francisco Alias, fantasy;
}

This should work everywhere San Francisco is available.

Further Explorations

Sources

Retweet to share this post