Substitute web fonts with StopTheMadness

November 3, 2022
By Jeff Johnson of Underpass App Company

I got a feature request from John Gruber, famous for Daring Fireball, also famous for despising the Arial typeface.

Honestly, the most shocking thing about the Apple Developer Program License Agreement is that the PDF is entirely typeset in Arial. Clearly it should be San Francisco, but Helvetica would be acceptable. Arial should be a firing offense.

What you may not know about Gruber, though, is that as much as he despises Arial, he dislikes Courier New even more! If Arial demands firing, then I suppose that Courier New demands… the firing squad? Anyway, Gruber requested that my Safari extension StopTheMadness add font substitution rules in order to replace all instances of Arial on the web with Helvetica and all instances of Courier New with Courier.

I told Gruber that he didn't need to wait for me to add the feature, because substituting fonts was already possible in StopTheMadness on both desktop and mobile by using a custom <style> element containing some @font-face rules.

The @font-face CSS at-rule specifies a custom font with which to display text; the font can be loaded from either a remote server or a locally-installed font on the user's own computer.

In this case, we use pre-installed fonts that come with the system. Here are the rules to substitute Helvetica for Arial.

@font-face {
 font-family: "Arial";
 font-stretch: 50% 200%;
 font-style: normal;
 font-weight: 1 1000;
 src: local("Helvetica");
}
@font-face {
 font-family: "Arial";
 font-stretch: 50% 200%;
 font-style: italic;
 font-weight: 1 1000;
 src: local("Helvetica");
}
@font-face {
 font-family: "Arial";
 font-stretch: 50% 200%;
 font-style: oblique;
 font-weight: 1 1000;
 src: local("Helvetica");
}

And here are the rules to substitute Courier for Courier New.

@font-face {
 font-family: "Courier New";
 font-stretch: 50% 200%;
 font-style: normal;
 font-weight: 1 1000;
 src: local("Courier");
}
@font-face {
 font-family: "Courier New";
 font-stretch: 50% 200%;
 font-style: italic;
 font-weight: 1 1000;
 src: local("Courier");
}
@font-face {
 font-family: "Courier New";
 font-stretch: 50% 200%;
 font-style: oblique;
 font-weight: 1 1000;
 src: local("Courier");
}

The font-stretch and font-weight attributes accept a range. If those attributes aren't specified, then they take the default value of "normal", which is 100% stretch and 400 weight. The default values wouldn't cover the bold text in an <h1> element, for example, so we specify the full range.

Unfortunately, the font-style attribute doesn't accept a range for some strange reason (CSS amirite!), so we need three separate rules to cover all the styles.

In our testing, using these rules in StopTheMadness appears to work great! Here's where you would add the rules in the desktop Safari extension.

StopTheMadness Custom Elements tab, Default options for all websites

Although I've shown how font substitution is possible in StopTheMadness, it's still not very convenient or discoverable for the majority of users, given that you need to write CSS and use three different @font-face rules for each font. I could add a specific font substitution feature to make this easier in StopTheMadness, but my question is whether I should? I know that Gruber wanted the feature, but I have no idea how many other people would want it. Not everyone possesses Gruber's keen typeface discernment. So this is why I'm blogging about it, to gauge public opinion. If you would like a font substitution feature, please let me know. I always love to get feature requests and bug reports from my customers. I'm reachable by email, and now you can also join my brand new Slack for StopTheMadness support!

Update: November 4, 2022

I've received a good amount of "votes" for a font substitution feature, thanks to Gruber's link to this article, so I'll get to work on it! There's no need to vote for that anymore, but please send me your other feature requests.

Update: November 5, 2022

See Substitute web fonts with StopTheMadness, Part 2 for more technical details.