CSS Reset

06 02 2022

CSS Reset

Modern CSS Reset

In this article, you will learnModern CSS Reset how to reset CSS.

I think about and enjoy very boring CSS stuff—probably much more than I should do, to be honest. One thing that I’ve probably spent too much time thinking about over the years, is CSS resets.

In this modern era of web development, we don’t really need a heavy-handed reset, or even a reset at all, because CSS browser compatibility issues are much less likely than they were in the old IE 6 days. That era was when resets such as normalize.css came about and saved us all heaps of hell. Those days are gone now and we can trust our browsers to behave more, so I think resets like that are probably mostly redundant.

A reset of sensible defaults permalink

I still like to reset stuff, so I’ve been slowly and continually tinkering with a reset myself over the years in an obsessive code golf manner. I’ll explain what’s in there and why, but before I do that, here it is in its entirety:

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

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

/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
ul[role='list'],
ol[role='list'] {
  list-style: none;
}

/* Set core root defaults */
html:focus-within {
  scroll-behavior: smooth;
}

/* Set core body defaults */
body {
  min-height: 100vh;
  text-rendering: optimizeSpeed;
  line-height: 1.5;
}

/* A elements that don't have a class get default styles */
a:not([class]) {
  text-decoration-skip-ink: auto;
}

/* Make images easier to work with */
img,
picture {
  max-width: 100%;
  display: block;
}

/* Inherit fonts for inputs and buttons */
input,
button,
textarea,
select {
  font: inherit;
}

/* Remove all animations, transitions and smooth scroll for people that prefer not to see them */
@media (prefers-reduced-motion: reduce) {
  html:focus-within {
   scroll-behavior: auto;
  }
  
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

Breaking it down

We start with box-sizing. I just flat out reset all elements and pseudo-elements to use box-sizing: border-box.

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

Some people think that pseudo-elements should inherit box sizing, but I think that’s silly. If you want to use a different box-sizing value, set it explicitly—at least that’s what I do, anyway. I wrote about box-sizing more over on CSS From Scratch.

<code class=" language-css">/* Remove default margin */
body,
h1,
h2,
h3,
h4,
p,
li,
figure,
figcaption,
blockquote,
dl,
dd {
  margin: 0;
}

After box-sizing, I do a blanket reset of margin, where it gets set by the browser styles. This is all pretty self-explanatory, so I won’t get into it too much.

But although I will mention the situation with the lists. Here I chose only those lists that have the class attribute, because if I'm going to use pure <ul> or <ol>, I want it to look really like a list. Here the main thing is not to overdo it, covering everything, as in the previous moment, which will remove all the indentations.

body {
  min-height: 100vh;
  scroll-behavior: smooth;
  text-rendering: optimizeSpeed;
  line-height: 1.5;
}

Let's move on: styles for the body. It's just here for me. It is very useful to specify to occupy all viewport, even when it is empty, I do it, exposing min-height on 100vh. I also like smooth scrolling to anchors, so here I will expose scroll-behavior: smooth.

I only set two text styles. I set the line-height to be 1.5 because the default 1.2 just isn’t big enough to have accessible, readable text. I also set text-rendering to optimizeSpeed. Using optimizeLegibility makes your text look nicer, but can have serious performance issues such as 30 second loading delays, so I try to avoid that now. I do sometimes add it to sections of microcopy though.

ul[class],
ol[class] {
  list-style: none;
}

As with indents, I reset list stylization only for elements that specify class.

a:not([class]) {
  text-decoration-skip-ink: auto;
}

For links without specifying the class, I will set text-decoration-skip-ink: auto, so that the underline will render much more readable. In general, it could be put all the links, but I had a few conflicts, so I left as described above.

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

Good ol’ fluid image styles come next. I set images to be a block element because frankly, life is too short for that weird gap you get at the bottom, and realistically, images—especially with work I do—tend to behave like blocks.

article > * + * {
  margin-top: 1em;
}

I really like this trick in CSS and I finally decided to add it for reset. The so-called "lobotomized owl selector" selects the direct descendants of the article and gives them an external indentation of 1em. This indicates a clear periodicity in the content flow in the article. In general, in fact, I use a handy piece of .flow, now in almost every project. You can read more about it at 24 Ways. And in general, it seems to me that this is now my CSS.

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

Another thing I finally dared to default is font: inherit for inputs that, simply put, do what they have to do. Enough of this small (mono, in some cases) text!

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

Last, and by no means least, is a single @media query that resets animations, transitions and scroll behaviour if the user prefers reduced motion. I like this in the reset, with specificity trumping !important selectors, because most likely now, if a user doesn’t want motion, they won’t get it, regardless of the CSS that follows this reset.

Wrapping up

That’s it, a very tiny reset that makes my life a lot easier. If you like it, you can use it yourself, too! You can find it on GitHub or NPM.

Поширити

Напишіть свій коментар

Ваша електронна адреса не буде опублікована. Обов’язкові поля позначені *