A Fresh Take on CSS Resets
Modern CSS resets are less about fixing browser inconsistencies and more about establishing a set of opinionated defaults. As layout techniques evolve and browsers converge, the traditional reset has transformed into a curated collection of styles that make sense for almost any project from day one.
Josh Comeau recently published his own custom reset, which reads more like a set of sensible default behaviors than a defensive measure against browser quirks. It's a list of choices that aren't design-specific but help create a more predictable foundation for styling.
margin: 0;
This is a solid baseline. The era when we needed a global reset is largely behind us—with grid and flexbox handling most layout weight, box-sizing matters less in day-to-day work. Still, having a predictable box model in place is preferable. If it's going in a reset, the inheritance model is the better approach, keeping it easier to override for individual components.
Zeroing out margins is a strong move. It forces you to be explicit about applying spacing, which tends to lead to more intentional design decisions. Consider zeroing padding as well, since list elements carry default indentation that can cause friction.
html, body { height: 100%; }
Setting a full-height foundation is a smart call. It prevents unexpected gaps with background colors and lets percentage-based heights work as intended. A simple body { height: 100vh; } isn't always reliable—mobile browser UI quirks make it an awkward fallback.
Not every choice in the reset lands. Applying -webkit-font-smoothing: antialiased; globally tends to make type look overly thin. It's useful as an opt-in tool for specific headings or accents, not as a site-wide default.
Likewise, putting typographic sizing rules on the body element muddies the meaning of rem, which is rooted at the <html> level. Root font-size adjustments for media queries belong at the root, not on the body.
The 1.5 default for line-height is a workable choice. Headings will almost always need less, and that's where a dedicated selector comes in. There's a clever alternative using calc() that scales line-height more smoothly across type sizes:
line-height: calc(1em + 0.5rem);
This approach keeps small text readable without making large headings feel cluttered. It's worth trying on a new project—previously explored by Jesús Ricarte as a technique for calculating optimal line-height.
Setting media elements to display: block is a wise reset choice. It eliminates the annoying inline gaps from line-height and ensures these elements don't stretch beyond their containers. Adding iframe and object to the list would be a safe extension.
Wrapping long content is another must-have. URLs and unbroken strings breaking out of their containers is a common source of layout headaches. Applying wrapping rules to text-specific elements works well, but cascading them from a content wrapper is often more effective—and adding list and quote elements to the chain covers more ground. The exact combination of overflow-wrap, word-break, and hyphens remains a surprisingly tricky field to pin down precisely.
The final bit—giving #root and #__next an isolation: isolate treatment—is curious. Mounting React apps and creating a stacking context at the top level is understandable, but the practical benefit isn't immediately obvious. It does no harm, though.
Overall, this reset reflects how the role of resets has shifted: less about erasing browser differences, more about declaring a sane, modern default environment that can be built upon with confidence.



