August 14, 2026
Rebuilding Firefox.com with Mozilla and Lincoln Loop on modern, native CSS with no preprocessors, and what that means for design systems today.
Back in 2008, fresh out of college, I discovered CSS Zen Garden, Dave Shea’s project where one HTML file could be restyled into something completely different using nothing but CSS. It was a glimpse of the dream: clean, reusable design, fully separated from content.
Then you tried to ship real client work, and the dream fell apart. There were no CSS variables. The properties available couldn’t express a full-fidelity design, so we leaned on server-side processing, images, table-based layouts, and endless hacks. Every browser rendered things differently, so much of the work was just making one design behave across all of them. Zen Garden showed what was possible in theory. Production was another story.
That gap took the better part of two decades to close, and most of the closing happened in the last few years. Custom properties gave us variables the browser understands. Grid and Flexbox gave us layout that doesn’t fight the medium. The properties we lacked in 2008 now exist, and they’re implemented consistently enough that you can design against them instead of around them.
Firefox.com
That gap is finally closed. Modern CSS now does natively what we used to need preprocessors and hacks for. On the rebuild of Firefox.com, working with Mozilla and the team at Lincoln Loop, I built the whole system in modern, native CSS with no preprocessors. Custom properties are exported straight from design files, native CSS is written once with no hacks, and it works in every modern browser, with a minimal branded stylesheet giving legacy browsers basic, accessible branding.
Together we built a design system of more than 70 components and 25 page templates, implemented as Wagtail components so the site’s content team can assemble pages without engineering help. The site currently supports 19 locales.
There’s one honest footnote. We did end up with PostCSS in production, used for a single job: inlining @import statements. Native @import still has terrible performance characteristics in some browsers, and on a site like this one that matters more than architectural purity. The authored CSS is still plain, native CSS. Nothing in it depends on a build step to be valid or to make sense. The build only flattens what the browser would otherwise fetch serially.
That distinction is worth keeping in mind when someone tells you a project is “no build step.” What matters is whether the source you write is the language the browser speaks, or a dialect that only exists until compilation.
... continue reading