Beyond Named Colors: CSS System Colors and Fonts
Most web developers are familiar with named CSS colors like rebeccapurple or coral — fixed hex values with fixed expectations. But there’s another category of named colors in the CSS spec that behaves differently. These are CSS system colors, and unlike their static cousins, they’re designed to be fluid: the specification explicitly allows browsers, operating systems, or even users to set their values based on environment or preference.
The names make the intent clear. Canvas, for instance, represents “the background of application content or documents.” But here’s the subtle part: Canvas is not a universal constant. For dark mode, Safari uses #1e1e1e as its default document background while Chrome uses #121212. The system color keyword simply gives you a way to say, “use whatever the browser is already using” rather than hard-coding a value that will look wrong in one of them.
The full list of system colors is substantial:
CanvasandCanvasTextLinkText,VisitedText, andActiveTextButtonFace,ButtonText, andButtonBorderFieldandFieldTextHighlightandHighlightTextMarkandMarkTextGrayText
These values respond dynamically: they switch when a user toggles between light and dark mode, provided the surrounding CSS supports the change. You don’t necessarily have to use them for their intended purpose, either — nothing stops you from using Highlight as a button background, for example.
System Fonts: The Same Idea, Applied to Type
System fonts follow the same philosophy. The system-ui keyword isn’t a specific face; it references the operating system’s default UI font, which varies across platforms. Historically, developers approximated this with a long CSS stack of named fonts. Now the spec provides keywords to make the intent explicit:
system-uiui-serif,ui-sans-serif,ui-monospace, andui-roundedserif,sans-serif, andmonospacecursive,fantasy,emoji,math, andfangsong
Browser support is scattered. On a Mac in Safari, setting font-family: ui-monospace resolves to SF Mono, but Chrome ignores it and falls back to system-ui, which is SF Pro. Firefox ignores both and ends up at something like fantasy. Font stacks still matter, then — these keywords behave less like hard values and more like intentionally layered fallbacks.
Where the “System” Idea Doesn’t Extend
The definition of “system” things has limits. Named font weights like bold (equivalent to a value of 700) and bolder (relative to the parent’s weight) exist, but they are not dynamic in the way system colors are — nothing about them is delegated to the platform. Similarly, xx-small and the other named font font-size keywords compute to identical values in a comparison between Chrome and iOS Safari, so there’s no system-level adjustment at work.
Server-side named sizes don’t travel at all; you can’t write margin: large and get a result. No universal system sizes exist outside the font world. System-specific variables are limited to colors and fonts—plus two things that are implicitly system-controlled by design:
- Emoji act as system icons in a loose sense — the same character renders differently per platform, a behavior we accept because it keeps the icon visually consistent with the user’s OS.
- Inputs are “system inputs.” Browsers and platforms render form controls distinctively, and the specification leaves that to each implementation.
System colors and fonts occupy a middle ground: CSS gives you the vocabulary to reference platform defaults, but avoids hard-coding the outcome. To use them intentionally, you have to accept the fluidity and plan fallbacks when support is missing.



