An example of something to keep in mind with this technique is that you might actually end up causing the browser to render a different font than either you or the user intended.
For a practical example:
Environment
- Latest Firefox on Windows 10.
- Manually installed fonts 'Cascadia Code' and 'JetBrains Mono NL'.
- Firefox default 'monospace' font set to 'JetBrains Mono NL'.
Setting `font-family: monospace;` would end up rendering 'JetBrains Mono NL' - the user-configured default monospace font.
Setting `font-family: 'Cascadia Code', monospace;` would also render 'JetBrains Mono NL' - privacy features prevent pages from querying non-standard system fonts and this will also be reflected as a console warning message: 'Request for font "Cascadia Mono" blocked at visibility level 2 (requires 3)".'
Now, if you were to use he "Monospace Code" font stack listed on this page `font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace;`, you will render... Yup, 'Consolas'!
1. `ui-monospace` - remains unsupported by Firefox which is lame (would also render 'Consolas').
2. `Cascadia Code` - see above, access denied because it isn't natively available on Windows 10 (also, coding ligatures... more like illigatures, amirite?).
3. `Source Code Pro` - skipped due to unavailability.
4. `Menlo` - skipped due to unavailability.
5. `Consolas` - next option in line, this one is available and is the one that will be chosen.
6. `DejaVu Sans Mono` - skipped, font already determined.
7. `monospace` - skipped, font already determined.
These modern font stacks suck. Please, if you want to render font and it has to be something specific, then use an actual web font and simply fall back to the default 'monospace' which is controlled by the user.
It is not default, and explicitly indicates this kind of outcome can potentially happen. But truly agree that the situation here is suboptimal in all aspects.
Also maybe worth noting that we can always force our (three) font faces everywhere simply by unchecking the "Allow pages to choose their own fonts" in settings. Yes, this is nuclear option, but I can attest that I use it time to time, and it is quite usable.
BTW, I have somewhat softer workaround that interestingly makes the (local) Cascadia on modernfontstacks work even in the Strict Tracking Protection mode: I have a "userstyle" [0] (more precisely userCSS in Stylus) that "remaps", among other things, "Consolas" to a @font-face of the same name but loading `src: local("Cascadia Mono")` instead. Not sure why exactly this circumvents that (I don't think that Stylus-injected styles have more privileges than page styles), but I am glad it works nonetheless.
> Allow pages to choose their own fonts" in settings. Yes, this is nuclear option, but I can attest that I use it time to time, and it is quite usable.
Good question! Actually (to my minor dismay): not completely.
Disabling "font support" in Firefox surprisingly still has a hatch for "well-known" icon fonts, with intention to prevent "blind" icons in webpages. I believe it is driven by the pref
that contains "FontAwesome" and (Google) Material Icons and Symbols (many, presumably all, variants). So to truly disable all "non-preferred" fonts, we have to both wipe that pref and also change for the
browser.display.use_document_fonts
to zero. But that's what the GUI checkbox controls, so no need to go to about:config for this one.
> Also maybe worth noting that we can always force our (three) font faces everywhere simply by unchecking the "Allow pages to choose their own fonts" in settings. Yes, this is nuclear option, but I can attest that I use it time to time, and it is quite usable.
Occasionally I deliberately trial major changes for a week or two. Sometimes I revert, other times I stay. I turned font selection off in this way in early 2020, and never went back, it made the web so much better.
Out of the box, Firefox still loads fonts with certain names, to avoid breaking icon fonts. After maybe six months I decided to nuke that with blocking all fonts in uBlock Origin, and although it made some things uglier, and Material Icons is ridiculously stupid in practice (frankly achieving almost the precise opposite of its stated intent for using ligation) it took until this year before I encountered an actual breakage (a couple of sites not realising document.fonts.load() can throw).
I encourage others to turn off font selection, though I wouldn’t encourage most to block web fonts altogether in the way I decided to.
I also urge developers to shun icon fonts: they were always a bad idea, a dodgy hack, and the time when they had meaningful justifying qualities is now long past.
I don't think web pages should stay away from font stacks just to handle people with changed esoteric browser prefs. If you as a user want to see different fonts everywhere, you'll need invasive tools that block font face etc. Or Firefox (where this message comes from) has a setting to "Allow pages to choose their own fonts, instead of your selections above"
These font stacks don't handle anything at all, they just throw a bunch of common typeface names at the wall and they can't even tell what sticks because it's so random. All the while, the user might have a prefered fallback font set that they prefer over any of the ones in the font stack - and even if that isn't the case, simply using 'monospace' as the only fallback will render the default monospace font anyway.
I disagree with the notion that common browser configuration options available for users to change through the main/general browser settings UI would in any way be esoteric. It is wholly irrelevant anyway.
The setting you mention has no effect in the case I outlined above - Even with "Allow pages to choose their own fonts, instead of your selections above." enabled, the same results are observed.
they just throw a bunch of common typeface names at the wall and they can't even tell what sticks because it's so random.
Anytime someone on HN doesn't understand CSS, they throw up their hands and call it random. Just because you don't understand what's happening doesn't mean it's random.
I don't understand the SAM76 programming language, but I don't pretend that
!%ii,*,1,1,!%mu,*,%F,%su,*,1//////////=
is "random."
the user might have a prefered fallback font set that they prefer over any of the ones in the font stack
Great! Then the user gets his preferred font, as requested, instead of the one the page specified. Sounds like a win, so I'm not sure what you're complaining about. I expect you'd also complain if the web page overrode the user's choice.
I disagree with the notion that common browser configuration options available for users to change through the main/general browser settings UI would in any way be esoteric.
Of the six billion or so people on the web, the number of people manually overriding fonts isn't even a rounding error. It's not even a rounding error's rounding error. Get out of the tech bubble.
Accusing the person you are replying to of not understanding css after the knowledge built in to their argument doesn’t paint you in a good light. I don’t have horse in this race, but I’d encourage you to take a beat.
My top level comment was not a complaint at all, but rather a heads-up regarding the potentially unexpected or often misunderstood effects of applying these font stacks, accompanied by a practical example, and a personal recommendation with my reasoning.
Now, please, don't be so hostile. It's nasty and makes you come across as a lot more stupid than I believe you really are.
> Great! Then the user gets his preferred font, as requested, instead of the one the page specified.
No. You've misread the main point. The user would have gotten his preferred font if the font stack was either just plain
font-family: monospace;
or
font-family: <list of fonts their system does *not* support or does *not* allow to be used>, monospace;
. But the case is that the suggested font stack contains some "unwanted" font that their system both supports and allows to be used, that precedes the generic `monospace` font family the user actually prefers, or, more precisely, have assigned their typeface to. Is it more clear now?
I agree it is not a huge "bug" on the first sight, and as it seems even this is somewhat solvable without disabling font support completely. But since it takes some effort and expertise on the user's side, it adds the "bug" some weight nonetheless.
That hurts. I see where you are standing, and can confirm you expressed opinion of the contemporary majority of browser users, but man, how sad it that. The attitude diverged by a light years, when "Setting preferred fonts for generic font families" is now "esoteric". (Web) browsers ("user agents") came to existence with these capabilities in mind, and even now are build around the principle of "preferences reconciliation" between defaults, author and user (as opposed to simple "display what author dictates"). And default font choice is probably the very first aspect it ever had to handle.
The esoteric part is the combination of "Setting preferred fonts for generic font families" AND the security adjustments necessary to trigger "Request for font XYZ blocked at visibility level 2"
Sure if you want to set browser prefs for fonts, go for it. It'll make the OG sites with almost no stylesheet a little more readable (looking at you, wiki.c2.com). But you should not expect or ask web page authors to not use their preferred fonts. If you want to override web page fonts, use a more invasive or pervasive tool.
Font/page size preferences, on the other hand, web page authors should respect and do a better job with.
It's mixed bag... the designer of a given website has an intended look/feel and style... if you override that you can do as you like, but it's not like the author's intent should always simply be dismissed.
Beyond this, not every web developer expressly wants to burden a browser to a specific web font payload when they have a close/suitable match where this modern font stack is good enough in terms of design intent.
Third, if all else fails, the user sees their own selected default... I'm not sure that I understand the objection here... As long as appropriate semantic markup and the font is one that actually scales to appropriate px/pt then it should be fine. If the selected font/typeface doesn't, then it's on the user to select a better default/fallback.
> it's not like the author's intent should always simply be dismissed.
Yes it is. The designer should always understand that the user is ultimately in control of a web page, and that their (the designer's) vision is not what matters at the end of the day.
If you choose to use w3m or lynx you get what you get. Same for disabling fonts or JS... most people don't have time to cater to 0.05% of users who go way off the norm.
Browsers have ceded way too much control to web designers. The user should be in control. When it comes to what fonts the computer uses, the text size, the color scheme, the user preference should be able to easily override the web site's code. Who's computer is it, anyway?
I'd be pretty over the moon if the browser supported the following preferences... especially given the number of electron or otherwise browser embedded UI options..
It might be reasonable to have more than this, and the accent and highlight color may or may not be the same color... but it would go a long way towards matching the system defaults, with appropriate css variables injected as well.
Maybe it’s because I’m already familiar with how fonts are chosen in the browser, but - how does your example of using Monospaced Code demonstrate “render a different font than either or the user intended?” It looks to me like the font renders exactly as intended - the rules are applied, the series of options are considered in turn until the first one qualifies and that one is used.
How else would one expect a series of fallbacks like this to work?
"privacy features prevent pages from querying non-standard system fonts"
Do you know if and where it is documented which fonts various browsers consider "standard" on which platform? I am afraid I know the answer but one can hope.
I'm not sure why would you put "protect" in scare quotes here. This protection against fingerprinting is very real. Having any installed fonts that didn't come with the OS (and that includes fonts that are installed by other programs), makes your computer a lot more easy to fingerprint and track. Not everybody is interested in this protection, but this protection is very real.
It also doesn't seem to be enabled by default, since it tends to break some sites, as explained above. If you want to disable prevent Firefox from doing that, just don't set "Enhanced Tracking Protection" to Strict. You can even go for full Custom mode and enable "Protection from Suspected Fingerprinters" (which blocks some fonts as described by GP) only for private windows.
I tend to add Inconsolata (open Consolas-like typeface) as well as a fallback... since it's closer to what I'm intending if going for the Cascadia Code as a default... in case it's installed in non-windows or otherwise those fonts aren't present.
That is clearly not the intention, else there would be no reason to bother with font stacks. The intention is to list a set of ranked preferences, implemented as fallbacks, that best express the designer’s vision for the site, while avoiding font downloading. In your example, presumably the designer thinks that Consolas works better than JetBrains Mono NL.
Yes, I see what you mean, but if that's really the intent, then having only this font-family rule isn't sufficient. For that argument/reasoning to hold up, it would have to be accompanied by metrics adjustments to compensate for the massive differences between some of the listed fonts in these stacks.
Absolutely true. In fact (and thank you for getting me to think about this), font stacks without metric adjustments don’t really make much sense, do they? (Unless confined to a list of fonts that are very close metrically, which they never are.)
I use this quite a bit! At the very least, if you're going to insist on using a custom font, having the rest of one of these stacks behind it can help guarantee that users with third-party resource blockers or other weird browsers get an experience closer to what you intend.
For example, I always take Google Font's suggestion for Inter[1]:
https://screenspan.net/fallback is a good resource for finding out which system font looks most like the intended webfont, e.g. in my use case, Verdana has similar metrics to Roboto Serif.
One thing to keep in mind when developing these large lists of fonts is that they are generally terrible for performance if the appropriate glyphs for what you are trying to display aren't present in the first font (and the font is available - this isn't an issue if the font isn't available at all).
This is generally more of an issue with non-latin scripts (or when emoji is present for example), and developers adding a font which doesn't have glyph coverage - or sparse glyph coverage.
Chrome/Firefox devtools both have a section "Rendered Fonts"/"Used Fonts" which show which gylphs are used from which font.
`font-family: sans-serif` if not language tagged with incur a similar fallback perfromance penalty (the browser will have to change the "english" sans-serif font, find no glyphs, then use the "other-lang" sans-serfic font).
Right now, the webfont CSS file for my website and blog is 89734 bytes in size. This is a very fast load, with well under a fraction of second of “font change flash” even on a 4g network in a third world country.
Point being, I don’t see the point of having a large font stack in the day and age of webfonts. To get a reasonable looking “flash of content”, I used https://screenspan.net/fallback which determined that Verdana (available everywhere except Android/ChromeOS and readily available even for Linux) has about the same metrics as Roboto Serif, the font I use a subsetted version of for my blog.
As an aside, I feel Roboto Serif is a very good open source Verdana replacement for the 2020s: It’s very easy to read and OFL licensed to boot.
I think at least a small version of a font stack like these isn't a bad idea even if you're using web fonts. Folks who insist on disabling web fonts are likely a small percentage of any given site's readers, but they're out there. (And for certain sites, like this very one, there's a much higher percentage of them, usually ready to hop right out and proclaim how arrogant it is for web developers to choose typefaces for them and CSS was a mistake and we should all go back to VT100 terminals like God intended etc. etc.)
Literally toying with the idea of a "modern" BBS centered around current terminal usage... supporting varying display sizes, images, mouse clicks, urls, etc.
Mostly in that I want at least half a step between someone being able to just click a browser link and participating in discussions.
(Because of the OFL, “Roboto Serif” is replaced by another name since I modified the font when I subsetted it)
Large font stacks made sense in the days of IE6 for the following reasons:
• Dial up users did not have enough bandwidth to download webfonts.
• Only IE supported webfonts, in a weird proprietary “eot” format
• 99% of desktop operating systems all had the same web safe fonts “Verdana/Georgia/Trebuchet/Times New Roman/Arial/etc.”
Here in 2025, font stacks no longer make as much sense:
• 100k for a webfont package is a small file, even on a 4g network in a third world country. [1]
• All mainstream current browsers support woff2 webfonts [3][4]
• On Android, font support is very limited and has no support for the old school “web safe” core fonts for the web (Verdana/etc.)
As an aside, if metric compatibility (i.e. all of the fonts letters are the same size) with an OS core font is needed, “Arimo”/“Liberation Sans” is metrically compatible with Arial, “Liberation Serif”/“Tinos” is metrically compatible with Times New Roman, and “Cousine”/“Liberation Mono” is metrically compatible with Courier New.
[1] CJK users have font files large enough where the download size might be an issue. In that case, we either accept the download size as part of a modern website, or we accept that Android users will get Noto [2] while Mac/Windows users will get different looking system fonts.
[2] These font stacks linked in this article by and large all end up using Noto on Android phones. [5] I personally await the day when Apple and Microsoft include Noto by default with their OSes, so “font-family: Noto, sans-serif;” always does the right thing.
[4] Some people will turn off webfonts, but those people have made it clear they don’t care whether or not they get a font which looks like the design the webmaster intended. Again, use https://screenspan.net/fallback to find a reasonably metrically compatible fallback font.
[5] Looking at them in Firefox on my Android phone, “System UI” works, “Neo-Grotesque” gives a pencil thin font which is very difficult to read (“Inter” on my phone is pencil thin), “Slab Serif” actually looks nice (both in Windows, with Rockwell, and on Android, with Roboto Slab), and “Handwritten” works for its purpose (Android uses a “Cursive” fallback font). All the other font stacks are giving me the system default serif/sans/mono fonts (either Noto or Roboto). With Chrome on my Android phone, source sans pro is used a lot, as well as Google specific metric compatible versions of “Arial”, “Georgia”, “Courier New”; “Slab Serif” doesn’t work there even though Roboto Slab is installed on my Android system. Point being, Android has made web safe fonts a thing of the past.
Even in first-world countries, there are places with terrible coverage, where only 2G/3G service is available. The modern Web is pretty much unusable in those conditions, because Web designers think that “everyone has a fast network now”.
I don't really get it, maybe my phone is just old but I saw exactly 3 fonts on this page: serif, sans, and mono. None of the other fonts are available on my phone so each category looked identical. Is this experience better on other devices? To me this was not a useful demo because it reinforced the fact that you need to ship fonts if you want users to see that specific font.
I assume you're on Android? That's the weak link when it comes to system fonts, it only ships with a handful so many of these stacks end up looking identical in practice. If you go through to the GitHub page there's screenshots of how each stack gets rendered on each platform.
If you're not happy with what Android offers then a possible compromise would be to make a hybrid stack which tries Windows and Apple system fonts first, then falls back to a webfont if those aren't available.
Hah, I ran into the same issue on Linux. I forgot that I only install a couple fonts on my machines (noto, cascadia, and adobe-source-*) so I was also looking at them thinking "Why are these all the same? Even hand-written looks like a normal typed font". Thanks for the suggestion to go to the github for the screenshots: https://github.com/system-fonts/modern-font-stacks
If you're really targeting either, you're probably better off with the fallback sans-serif which is often one or the other based on the platform (historically, not 100% sure on current browsers). Arial displays slightly better on Windows, and Helvetica likewise with Mac.
Not quite. The original sans font on the Mac was Geneva. It was only with the advent of the Laserwriter that Helvetica became a standard font on the Mac.
Depending on the use case that might be a positive. For a basic web application for example it is better to conform to the host OS style.
For most documents mainly designed for reading it should not matter at all. People will do a lot of stuff to your page anyways (reader mode, zooming 10-20x, adblockers that block fonts…)
I don’t think this is a great solution for, broadly, consumer sites and apps.
In a lot of cases, branding matters, and having consistent cross-platform rendering matters.
However, I’ve had good experiences using system-ui with in-house dashboard-y apps. I’m the principle UI designer at my startup, and I recommend this font stack for anyone coding up internal-use-only observability tooling and monitoring stuff. We’re all on Chrome, we’re all on Macs, and getting SF Pro on the page without having to call a CDN or manage font assets is a win.
An example of something to keep in mind with this technique is that you might actually end up causing the browser to render a different font than either you or the user intended.
For a practical example:
Environment
Setting `font-family: monospace;` would end up rendering 'JetBrains Mono NL' - the user-configured default monospace font.Setting `font-family: 'Cascadia Code', monospace;` would also render 'JetBrains Mono NL' - privacy features prevent pages from querying non-standard system fonts and this will also be reflected as a console warning message: 'Request for font "Cascadia Mono" blocked at visibility level 2 (requires 3)".'
Now, if you were to use he "Monospace Code" font stack listed on this page `font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace;`, you will render... Yup, 'Consolas'!
These modern font stacks suck. Please, if you want to render font and it has to be something specific, then use an actual web font and simply fall back to the default 'monospace' which is controlled by the user.This is excellent analysis, but I think you've forgot to mention one particular detail in your environment description:
It is not default, and explicitly indicates this kind of outcome can potentially happen. But truly agree that the situation here is suboptimal in all aspects.Also maybe worth noting that we can always force our (three) font faces everywhere simply by unchecking the "Allow pages to choose their own fonts" in settings. Yes, this is nuclear option, but I can attest that I use it time to time, and it is quite usable.
BTW, I have somewhat softer workaround that interestingly makes the (local) Cascadia on modernfontstacks work even in the Strict Tracking Protection mode: I have a "userstyle" [0] (more precisely userCSS in Stylus) that "remaps", among other things, "Consolas" to a @font-face of the same name but loading `src: local("Cascadia Mono")` instead. Not sure why exactly this circumvents that (I don't think that Stylus-injected styles have more privileges than page styles), but I am glad it works nonetheless.
[0] https://userstyles.world/style/23838
IIRC, Safari has this limitation with rendering only system fonts and it cannot be disabled.
> Allow pages to choose their own fonts" in settings. Yes, this is nuclear option, but I can attest that I use it time to time, and it is quite usable.
Does this nuke icon fonts? I presume yes.
Good question! Actually (to my minor dismay): not completely. Disabling "font support" in Firefox surprisingly still has a hatch for "well-known" icon fonts, with intention to prevent "blind" icons in webpages. I believe it is driven by the pref
that contains "FontAwesome" and (Google) Material Icons and Symbols (many, presumably all, variants). So to truly disable all "non-preferred" fonts, we have to both wipe that pref and also change for the to zero. But that's what the GUI checkbox controls, so no need to go to about:config for this one.Icon fonts are bad for accessibility. Better to use SVG graphics and provide alt text for screen readers.
How so? aria-label= and role= attributes exist, this is not 1999.
> Also maybe worth noting that we can always force our (three) font faces everywhere simply by unchecking the "Allow pages to choose their own fonts" in settings. Yes, this is nuclear option, but I can attest that I use it time to time, and it is quite usable.
Occasionally I deliberately trial major changes for a week or two. Sometimes I revert, other times I stay. I turned font selection off in this way in early 2020, and never went back, it made the web so much better.
Out of the box, Firefox still loads fonts with certain names, to avoid breaking icon fonts. After maybe six months I decided to nuke that with blocking all fonts in uBlock Origin, and although it made some things uglier, and Material Icons is ridiculously stupid in practice (frankly achieving almost the precise opposite of its stated intent for using ligation) it took until this year before I encountered an actual breakage (a couple of sites not realising document.fonts.load() can throw).
I encourage others to turn off font selection, though I wouldn’t encourage most to block web fonts altogether in the way I decided to.
I also urge developers to shun icon fonts: they were always a bad idea, a dodgy hack, and the time when they had meaningful justifying qualities is now long past.
I don't think web pages should stay away from font stacks just to handle people with changed esoteric browser prefs. If you as a user want to see different fonts everywhere, you'll need invasive tools that block font face etc. Or Firefox (where this message comes from) has a setting to "Allow pages to choose their own fonts, instead of your selections above"
These font stacks don't handle anything at all, they just throw a bunch of common typeface names at the wall and they can't even tell what sticks because it's so random. All the while, the user might have a prefered fallback font set that they prefer over any of the ones in the font stack - and even if that isn't the case, simply using 'monospace' as the only fallback will render the default monospace font anyway.
I disagree with the notion that common browser configuration options available for users to change through the main/general browser settings UI would in any way be esoteric. It is wholly irrelevant anyway.
The setting you mention has no effect in the case I outlined above - Even with "Allow pages to choose their own fonts, instead of your selections above." enabled, the same results are observed.
they just throw a bunch of common typeface names at the wall and they can't even tell what sticks because it's so random.
Anytime someone on HN doesn't understand CSS, they throw up their hands and call it random. Just because you don't understand what's happening doesn't mean it's random.
I don't understand the SAM76 programming language, but I don't pretend that
is "random."the user might have a prefered fallback font set that they prefer over any of the ones in the font stack
Great! Then the user gets his preferred font, as requested, instead of the one the page specified. Sounds like a win, so I'm not sure what you're complaining about. I expect you'd also complain if the web page overrode the user's choice.
I disagree with the notion that common browser configuration options available for users to change through the main/general browser settings UI would in any way be esoteric.
Of the six billion or so people on the web, the number of people manually overriding fonts isn't even a rounding error. It's not even a rounding error's rounding error. Get out of the tech bubble.
Accusing the person you are replying to of not understanding css after the knowledge built in to their argument doesn’t paint you in a good light. I don’t have horse in this race, but I’d encourage you to take a beat.
Oh you flatterer!
My top level comment was not a complaint at all, but rather a heads-up regarding the potentially unexpected or often misunderstood effects of applying these font stacks, accompanied by a practical example, and a personal recommendation with my reasoning.
Now, please, don't be so hostile. It's nasty and makes you come across as a lot more stupid than I believe you really are.
> Great! Then the user gets his preferred font, as requested, instead of the one the page specified.
No. You've misread the main point. The user would have gotten his preferred font if the font stack was either just plain
or . But the case is that the suggested font stack contains some "unwanted" font that their system both supports and allows to be used, that precedes the generic `monospace` font family the user actually prefers, or, more precisely, have assigned their typeface to. Is it more clear now?I agree it is not a huge "bug" on the first sight, and as it seems even this is somewhat solvable without disabling font support completely. But since it takes some effort and expertise on the user's side, it adds the "bug" some weight nonetheless.
> esoteric browser prefs
That hurts. I see where you are standing, and can confirm you expressed opinion of the contemporary majority of browser users, but man, how sad it that. The attitude diverged by a light years, when "Setting preferred fonts for generic font families" is now "esoteric". (Web) browsers ("user agents") came to existence with these capabilities in mind, and even now are build around the principle of "preferences reconciliation" between defaults, author and user (as opposed to simple "display what author dictates"). And default font choice is probably the very first aspect it ever had to handle.
(Or were you referring to some other "pref"?)
The esoteric part is the combination of "Setting preferred fonts for generic font families" AND the security adjustments necessary to trigger "Request for font XYZ blocked at visibility level 2"
Sure if you want to set browser prefs for fonts, go for it. It'll make the OG sites with almost no stylesheet a little more readable (looking at you, wiki.c2.com). But you should not expect or ask web page authors to not use their preferred fonts. If you want to override web page fonts, use a more invasive or pervasive tool.
Font/page size preferences, on the other hand, web page authors should respect and do a better job with.
It's mixed bag... the designer of a given website has an intended look/feel and style... if you override that you can do as you like, but it's not like the author's intent should always simply be dismissed.
Beyond this, not every web developer expressly wants to burden a browser to a specific web font payload when they have a close/suitable match where this modern font stack is good enough in terms of design intent.
Third, if all else fails, the user sees their own selected default... I'm not sure that I understand the objection here... As long as appropriate semantic markup and the font is one that actually scales to appropriate px/pt then it should be fine. If the selected font/typeface doesn't, then it's on the user to select a better default/fallback.
> it's not like the author's intent should always simply be dismissed.
Yes it is. The designer should always understand that the user is ultimately in control of a web page, and that their (the designer's) vision is not what matters at the end of the day.
If you choose to use w3m or lynx you get what you get. Same for disabling fonts or JS... most people don't have time to cater to 0.05% of users who go way off the norm.
Browsers have ceded way too much control to web designers. The user should be in control. When it comes to what fonts the computer uses, the text size, the color scheme, the user preference should be able to easily override the web site's code. Who's computer is it, anyway?
I'd be pretty over the moon if the browser supported the following preferences... especially given the number of electron or otherwise browser embedded UI options..
It might be reasonable to have more than this, and the accent and highlight color may or may not be the same color... but it would go a long way towards matching the system defaults, with appropriate css variables injected as well.> If you as a user want to see different fonts everywhere, you'll need invasive tools that block font face etc.
You have it backwards. These tools allow you to see the same fonts everywhere.
Just because the page author thinks lowercase f should look out of place doesn't mean I should have to see them like that. :p
Maybe it’s because I’m already familiar with how fonts are chosen in the browser, but - how does your example of using Monospaced Code demonstrate “render a different font than either or the user intended?” It looks to me like the font renders exactly as intended - the rules are applied, the series of options are considered in turn until the first one qualifies and that one is used.
How else would one expect a series of fallbacks like this to work?
Interesting.
"privacy features prevent pages from querying non-standard system fonts"
Do you know if and where it is documented which fonts various browsers consider "standard" on which platform? I am afraid I know the answer but one can hope.
How do I make sure my browser doesn't "protect" me in such a way?
I'm not sure why would you put "protect" in scare quotes here. This protection against fingerprinting is very real. Having any installed fonts that didn't come with the OS (and that includes fonts that are installed by other programs), makes your computer a lot more easy to fingerprint and track. Not everybody is interested in this protection, but this protection is very real.
It also doesn't seem to be enabled by default, since it tends to break some sites, as explained above. If you want to disable prevent Firefox from doing that, just don't set "Enhanced Tracking Protection" to Strict. You can even go for full Custom mode and enable "Protection from Suspected Fingerprinters" (which blocks some fonts as described by GP) only for private windows.
Your example is instructive, but I fail to see what the problem is. This is working as intended, no?
It's exactly what the manual specifies: https://github.com/system-fonts/modern-font-stacks?tab=readm...
Windows 11+ -> Cascadia Code Windows 7+ -> Consolas
I tend to add Inconsolata (open Consolas-like typeface) as well as a fallback... since it's closer to what I'm intending if going for the Cascadia Code as a default... in case it's installed in non-windows or otherwise those fonts aren't present.
It already works as intended. If the intent is to render a default system font, then let the system handle that by simply applying 'monospace'.
That is clearly not the intention, else there would be no reason to bother with font stacks. The intention is to list a set of ranked preferences, implemented as fallbacks, that best express the designer’s vision for the site, while avoiding font downloading. In your example, presumably the designer thinks that Consolas works better than JetBrains Mono NL.
Yes, I see what you mean, but if that's really the intent, then having only this font-family rule isn't sufficient. For that argument/reasoning to hold up, it would have to be accompanied by metrics adjustments to compensate for the massive differences between some of the listed fonts in these stacks.
Absolutely true. In fact (and thank you for getting me to think about this), font stacks without metric adjustments don’t really make much sense, do they? (Unless confined to a list of fonts that are very close metrically, which they never are.)
I use this quite a bit! At the very least, if you're going to insist on using a custom font, having the rest of one of these stacks behind it can help guarantee that users with third-party resource blockers or other weird browsers get an experience closer to what you intend.
For example, I always take Google Font's suggestion for Inter[1]:
and change it to: or e.g. EB Garamond[2] from: to: It makes for less layout shift on slower connections too.1. https://fonts.google.com/specimen/Inter
2. https://fonts.google.com/specimen/EB+Garamond
https://screenspan.net/fallback is a good resource for finding out which system font looks most like the intended webfont, e.g. in my use case, Verdana has similar metrics to Roboto Serif.
But there's no guarantee that system-ui is even a sans serif font. Why make that change?
One thing to keep in mind when developing these large lists of fonts is that they are generally terrible for performance if the appropriate glyphs for what you are trying to display aren't present in the first font (and the font is available - this isn't an issue if the font isn't available at all).
This is generally more of an issue with non-latin scripts (or when emoji is present for example), and developers adding a font which doesn't have glyph coverage - or sparse glyph coverage.
Chrome/Firefox devtools both have a section "Rendered Fonts"/"Used Fonts" which show which gylphs are used from which font.
Additionally if you are showing non-latin, make sure to language tag your markup: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/...
`font-family: sans-serif` if not language tagged with incur a similar fallback perfromance penalty (the browser will have to change the "english" sans-serif font, find no glyphs, then use the "other-lang" sans-serfic font).
Right now, the webfont CSS file for my website and blog is 89734 bytes in size. This is a very fast load, with well under a fraction of second of “font change flash” even on a 4g network in a third world country.
Point being, I don’t see the point of having a large font stack in the day and age of webfonts. To get a reasonable looking “flash of content”, I used https://screenspan.net/fallback which determined that Verdana (available everywhere except Android/ChromeOS and readily available even for Linux) has about the same metrics as Roboto Serif, the font I use a subsetted version of for my blog.
As an aside, I feel Roboto Serif is a very good open source Verdana replacement for the 2020s: It’s very easy to read and OFL licensed to boot.
I think at least a small version of a font stack like these isn't a bad idea even if you're using web fonts. Folks who insist on disabling web fonts are likely a small percentage of any given site's readers, but they're out there. (And for certain sites, like this very one, there's a much higher percentage of them, usually ready to hop right out and proclaim how arrogant it is for web developers to choose typefaces for them and CSS was a mistake and we should all go back to VT100 terminals like God intended etc. etc.)
Literally toying with the idea of a "modern" BBS centered around current terminal usage... supporting varying display sizes, images, mouse clicks, urls, etc.
Mostly in that I want at least half a step between someone being able to just click a browser link and participating in discussions.
My font stack looks something like this:
(Because of the OFL, “Roboto Serif” is replaced by another name since I modified the font when I subsetted it)Large font stacks made sense in the days of IE6 for the following reasons:
• Dial up users did not have enough bandwidth to download webfonts.
• Only IE supported webfonts, in a weird proprietary “eot” format
• 99% of desktop operating systems all had the same web safe fonts “Verdana/Georgia/Trebuchet/Times New Roman/Arial/etc.”
Here in 2025, font stacks no longer make as much sense:
• 100k for a webfont package is a small file, even on a 4g network in a third world country. [1]
• All mainstream current browsers support woff2 webfonts [3][4]
• On Android, font support is very limited and has no support for the old school “web safe” core fonts for the web (Verdana/etc.)
As an aside, if metric compatibility (i.e. all of the fonts letters are the same size) with an OS core font is needed, “Arimo”/“Liberation Sans” is metrically compatible with Arial, “Liberation Serif”/“Tinos” is metrically compatible with Times New Roman, and “Cousine”/“Liberation Mono” is metrically compatible with Courier New.
[1] CJK users have font files large enough where the download size might be an issue. In that case, we either accept the download size as part of a modern website, or we accept that Android users will get Noto [2] while Mac/Windows users will get different looking system fonts.
[2] These font stacks linked in this article by and large all end up using Noto on Android phones. [5] I personally await the day when Apple and Microsoft include Noto by default with their OSes, so “font-family: Noto, sans-serif;” always does the right thing.
[3] 96% over at https://caniuse.com/?search=woff2
[4] Some people will turn off webfonts, but those people have made it clear they don’t care whether or not they get a font which looks like the design the webmaster intended. Again, use https://screenspan.net/fallback to find a reasonably metrically compatible fallback font.
[5] Looking at them in Firefox on my Android phone, “System UI” works, “Neo-Grotesque” gives a pencil thin font which is very difficult to read (“Inter” on my phone is pencil thin), “Slab Serif” actually looks nice (both in Windows, with Rockwell, and on Android, with Roboto Slab), and “Handwritten” works for its purpose (Android uses a “Cursive” fallback font). All the other font stacks are giving me the system default serif/sans/mono fonts (either Noto or Roboto). With Chrome on my Android phone, source sans pro is used a lot, as well as Google specific metric compatible versions of “Arial”, “Georgia”, “Courier New”; “Slab Serif” doesn’t work there even though Roboto Slab is installed on my Android system. Point being, Android has made web safe fonts a thing of the past.
> on a 4g network in a third world country
Such as the US?
Even in first-world countries, there are places with terrible coverage, where only 2G/3G service is available. The modern Web is pretty much unusable in those conditions, because Web designers think that “everyone has a fast network now”.
I don't really get it, maybe my phone is just old but I saw exactly 3 fonts on this page: serif, sans, and mono. None of the other fonts are available on my phone so each category looked identical. Is this experience better on other devices? To me this was not a useful demo because it reinforced the fact that you need to ship fonts if you want users to see that specific font.
I assume you're on Android? That's the weak link when it comes to system fonts, it only ships with a handful so many of these stacks end up looking identical in practice. If you go through to the GitHub page there's screenshots of how each stack gets rendered on each platform.
If you're not happy with what Android offers then a possible compromise would be to make a hybrid stack which tries Windows and Apple system fonts first, then falls back to a webfont if those aren't available.
Hah, I ran into the same issue on Linux. I forgot that I only install a couple fonts on my machines (noto, cascadia, and adobe-source-*) so I was also looking at them thinking "Why are these all the same? Even hand-written looks like a normal typed font". Thanks for the suggestion to go to the github for the screenshots: https://github.com/system-fonts/modern-font-stacks
Yeah I'm on android. I guess the hybrid approach offers a couple benefits, thanks for the reply.
I've been using the Verdana core web font on personal sites for close to twenty years now, I still think it's very readable and easy on the eyes.
I find it generally more "well-kerned" than a lot of modern web fonts.
Works everywhere.
Similarly: https://www.cssfontstack.com/
This one surprised me:
I know Microsoft prefers Arial over Helvetica, so I guess I shouldn't be surprised. But I didn't expect macOS to adopt it so widely. Then again, the Mac was designed from day one for this sort of thing.If you're really targeting either, you're probably better off with the fallback sans-serif which is often one or the other based on the platform (historically, not 100% sure on current browsers). Arial displays slightly better on Windows, and Helvetica likewise with Mac.
I believe Helvetica has shipped with every Macintosh since the very first one.
Not quite. The original sans font on the Mac was Geneva. It was only with the advent of the Laserwriter that Helvetica became a standard font on the Mac.
It just means it's installed by default on all Macs, but not Windows
Good resource.
Pretty sure I've seen it posted before, perhaps on HN itself.
https://news.ycombinator.com/item?id=35150345 ("Show HN: Modern Font Stacks – New system font stack CSS for modern OSs (modernfontstacks.com)" (2023); 144 comments)
Thanks! Macroexpanded:
Modern Font Stacks - https://news.ycombinator.com/item?id=35168652 - March 2023 (9 comments)
Show HN: Modern Font Stacks – New system font stack CSS for modern OSs - https://news.ycombinator.com/item?id=35150345 - March 2023 (142 comments)
https://news.ycombinator.com/from?site=modernfontstacks.com
Sure there is no flash with “system ui” font but that font is different on every OS?
Depending on the use case that might be a positive. For a basic web application for example it is better to conform to the host OS style.
For most documents mainly designed for reading it should not matter at all. People will do a lot of stuff to your page anyways (reader mode, zooming 10-20x, adblockers that block fonts…)
I don’t think this is a great solution for, broadly, consumer sites and apps.
In a lot of cases, branding matters, and having consistent cross-platform rendering matters.
However, I’ve had good experiences using system-ui with in-house dashboard-y apps. I’m the principle UI designer at my startup, and I recommend this font stack for anyone coding up internal-use-only observability tooling and monitoring stuff. We’re all on Chrome, we’re all on Macs, and getting SF Pro on the page without having to call a CDN or manage font assets is a win.