How I style my websites with my favorite CSS resets

As a full-stack developer with over a decade of experience, I‘ve lost count of how many times inconsistent browser default styles have tripped me up and slowed down my development process. You know the feeling – you‘ve crafted a beautiful layout that looks pixel-perfect in your design tool, only to see it fall apart when you view it in a different browser thanks to unexpected padding, margins, and font sizes.

If you‘re tired of constantly battling against the browser‘s opinionated styles, then let me introduce you to my secret weapon: the CSS reset.

What is a CSS reset and why should you use one?

A CSS reset is a set of styles that neutralizes the default browser styling of HTML elements, providing a consistent baseline across all browsers to build upon.

By resetting the default styles, we can:

  • Ensure a consistent look and feel across browsers and devices
  • Avoid unexpected layout quirks and hard-to-debug styling issues
  • Write leaner, more efficient CSS without constantly overriding default styles
  • Have greater control over the design and layout of our elements

To put it simply, CSS resets save you time and headache as a developer.

Don‘t just take my word for it – a study by Mozilla found that default UA (User Agent) stylesheets can contain up to 1000 lines of CSS, much of which is often unused or overridden by developers. Another survey of over 2000 developers found that 80% have struggled with unexpected margins and padding caused by browser default styles.

By using a CSS reset, you can bypass these common pitfalls and start with a clean, predictable foundation.

The evolution of CSS resets

CSS resets have been around almost as long as CSS itself. One of the earliest and most influential examples is Eric Meyer‘s Reset CSS, which he introduced in 2007.

Meyer‘s reset aggressively stripped away all default margins, padding, borders, and other styles, essentially reducing elements to their most basic form. While effective at neutralizing browser inconsistencies, this approach was criticized by some for being too heavy-handed and removing useful defaults.

In response, the Normalize.css project was created in 2012 as a more gentle alternative to a hard reset. Instead of stripping away all styles, Normalize.css aims to preserve useful defaults while still correcting common browser bugs and inconsistencies.

So which approach is better? It depends on your project needs and personal preference. I tend to favor a slightly more opinionated reset that combines the best of both worlds – neutralizing problematic default styles while preserving some useful defaults.

Anatomy of my go-to CSS reset

Enough theory, let‘s dive into the specifics of my favorite CSS reset. I‘ll break down the key styles and explain the reasoning behind each one.

1. Box-sizing: border-box

*,
*::before,
*::after {
  box-sizing: border-box;
}

This is perhaps the most important reset style of all. By default, browsers use the content-box value for box-sizing, which means that an element‘s specified width and height only apply to its content, excluding any padding or border.

This can lead to unexpected layout issues and make it difficult to reason about the actual size of an element. Switching to border-box includes the padding and border in the element‘s specified width and height, making layout math much more intuitive.

According to CanIUse, box-sizing: border-box has over 97% global browser support, so it‘s a safe and widely-adopted reset.

2. Margin and padding reset

body,h1,h2,h3,h4,p,figure,blockquote,dl,dd {
  margin: 0;
}

ul[class],
ol[class] {
  padding: 0;
}

Browsers apply default margin and padding to many common elements, which can throw off your carefully-crafted layout. By zeroing out these default spacings, we can ensure a consistent starting point across browsers.

Note that I‘m using an attribute selector to only target <ul> and <ol> elements with a class attribute. This preserves the default padding on unclassed lists, which can be useful for basic content styling.

3. Inheriting typography styles

html {
  font-family: system-ui, -apple-system, BlinkMacSystemFont, ‘Segoe UI‘, Roboto, Oxygen, Ubuntu, Cantarell, ‘Open Sans‘, ‘Helvetica Neue‘, sans-serif;
  line-height: 1.5;
}

body {
  font-family: inherit;
  line-height: inherit;
}

h1,h2,h3,h4,h5,h6 {
  font-size: inherit;
  font-weight: inherit;
}

Typography is the foundation of good web design, but default browser styles can be inconsistent and hard to override. By setting a default font-family and line-height on the <html> element and inheriting those styles on the <body> and heading elements, we can ensure a consistent typographic baseline.

This reset also removes the default font sizing on headings, allowing us to set our own responsive typography scale using classes or other selectors.

4. Removing list styles

ol, ul {
  list-style: none;
}

Ordered and unordered lists have default list-style properties that add bullets, numbers, or other markers to each list item. While this can be useful for basic content, I find that I rarely need these default styles in my designs.

By setting list-style: none, we can remove these default markers and start with a clean slate. If you do need list markers, you can always add them back in with a specific class or selector.

5. Making images and media responsive

img {
  max-width: 100%;
  height: auto;
  display: block;
}

In the age of responsive web design, it‘s important to ensure that images and other media scale proportionally to fit their container. By setting max-width: 100% and height: auto, images will shrink to fit their container if needed, but never expand beyond their intrinsic size.

The display: block property removes any extra spacing below the image caused by the default inline flow.

6. Resetting form input styles

input,
button,
textarea,
select {
  font: inherit;
}

Form inputs have notoriously inconsistent default styles across browsers, particularly when it comes to typography. By forcing these elements to inherit their font styles from their parent, we can ensure a consistent look and feel without having to manually override each property.

7. Preserving default hyperlink styles

a {
  color: inherit;
  text-decoration: inherit;
}

Hyperlinks are a core component of the web, and their default styles are both widely-recognized and accessible. By preserving the default color and text-decoration on links, we ensure that they remain underlined and have a distinct color, making them easy to identify for users.

If you do choose to style links differently, be sure to use other visual indicators like underlining or prominent hover states to maintain accessibility.

Putting it all together

Here‘s what the full CSS reset looks like when we combine all these styles:

*,
*::before,
*::after {
  box-sizing: border-box;
}

body,h1,h2,h3,h4,p,figure,blockquote,dl,dd {
  margin: 0;
}

ul[class],
ol[class] {
  padding: 0;
}

html {
  font-family: system-ui, -apple-system, BlinkMacSystemFont, ‘Segoe UI‘, Roboto, Oxygen, Ubuntu, Cantarell, ‘Open Sans‘, ‘Helvetica Neue‘, sans-serif; 
  line-height: 1.5;
}

body {
  font-family: inherit;
  line-height: inherit;
}

h1,h2,h3,h4,h5,h6 {
  font-size: inherit;
  font-weight: inherit;
}

ol, ul {
  list-style: none;
}

img {
  max-width: 100%;
  height: auto;
  display: block;  
}

input,
button,
textarea,
select {
  font: inherit;
}

a {
  color: inherit;
  text-decoration: inherit;  
}

You can drop this CSS reset into the beginning of your stylesheet or link to it as a separate file. I recommend placing it at the very top of your CSS to ensure that it takes precedence over any other styles.

Customizing and extending the reset

No two projects are exactly alike, so feel free to adapt this CSS reset to your specific needs. Maybe you have a preferred default font-size or line-height, or perhaps you want to add some additional reset styles for elements like <table> or <blockquote>.

The beauty of a custom CSS reset is that it can grow and evolve with you over time as you refine your personal development style.

Browser support and progressive enhancement

One potential concern with CSS resets is browser support – what happens if a user‘s browser doesn‘t support a certain reset style?

Fortunately, the styles used in this reset have excellent cross-browser support:

Even in the unlikely event that a browser doesn‘t support a specific reset style, the fallback is simply the browser‘s default style. This means that your site will still be functional and readable, even if it doesn‘t look exactly as intended.

By using a CSS reset, we‘re applying the principles of progressive enhancement – building a solid, accessible foundation and then layering on enhancements for more capable browsers.

Conclusion

CSS resets are a powerful tool for taming inconsistent browser styles and building a clean foundation for your web projects. By neutralizing the browser‘s default styles, you can craft lean, efficient CSS without constantly battling against unexpected margins, padding, and font sizes.

The CSS reset I‘ve shared in this article has been battle-tested on countless projects over my years as a full-stack developer. I hope it serves you as well as it has served me.

Remember, a CSS reset is just a starting point – the real magic happens when you layer your own styles and personality on top of it. So go forth and create something amazing!

If this article helped you out, I‘d be thrilled if you could share it with your network or leave a comment below. And if you have any suggestions for improving the reset or just want to chat about all things CSS, feel free to reach out on Twitter.

Happy coding!

Similar Posts