Reset your CSS ?

Should we be normalizing or resetting our CSS?

ยท

6 min read

But why do we need these in the first place? Well, if I open a pure HTML5 page, there'll be something interesting

Out of the box, we have some default styles that are provided by a browser (called user agent stylesheets). There are two challenges here that Web Developers have to face

  • These styles are super opinionated and usually don't match our intentions

  • There are slightly different ways to implement user agent stylesheets ( by different browsers: Chrome, Firefox, Safari, IE, etc....)

Introduction to Reset CSS

Reset CSS was introduced to fix this problem. It will override all user agent styles, so you can start with an absolutely clean slate. This is kind of the hard-core solution to the problem

Let's take a look at how reset CSS works.

We reset everything (padding, margin, border, list style: none, etc ..) But with this approach, this can be troublesome since we have to rebuild everything from scratch again. Can we do it better?

Basic rules to create a custom CSS

When creating custom CSS, we should think about what properties in CSS we would like to override and why we should do it. I'll break down some of the key points that we should keep in mind when overriding HTML behaviors agent style

/*
  1. Use a more-intuitive box-sizing model.
*/
*, *::before, *::after {
  box-sizing: border-box;
}
/*
  2. Remove default margin
*/
* {
  margin: 0;
}
/*
  Typographic tweaks!
  3. Add accessible line-height
  4. Improve text rendering
*/
body {
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
/*
  5. Improve media defaults
*/
img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
}
/*
  6. Remove built-in form typography styles
  (keys to remember is all of it is interactive elements)
*/
input, button, textarea, select {
  font: inherit;
}
/*
  7. Avoid text overflows
*/
p, h1, h2, h3, h4, h5, h6 {
  overflow-wrap: break-word;
}
/*
  8. I usually use ul li to have a list of elements and find the
default padding is sometimes annoying to me
*/
ul {
  padding: 0;
}

ul li {
  list-style: none;
  display: inline-block;
  cursor: pointer;
}
/*
  9. Create a root stacking context
*/
#root, #__next {
  isolation: isolate;
}

Inheriting box-sizing

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

This will work great if we want to keep some special cases with a content box

<body>
  <header class="legacy">
    <nav>
      <!-- Legacy stuff here -->
    </nav>
  </header>
  <main>
    <section>
      <!-- Modern stuff here -->
    </section>
    <aside class="legacy">
      <!-- Legacy stuff here -->
    </aside>
  </main>
</body>
๐Ÿ’ก
Essentially, every element will figure out its box-sizing behavior from its parent. If it has an ancestor that sets the legacy, it'll be a content box. Otherwise, it'll ultimately inherit from HTML and use border-box

Remove default margin

* {
 margin:0;
}

Browsers make common-sense assumptions around the margin. For example, an h1 will include more margin than a paragraph by default and it might not be accurate for a modern web application

๐Ÿ’ก
This is a very logical decision that they chose to make. With a large font size like heading they will make a large margin for it. But this may not true to most cases

Tweaking line-height

Line height controls the vertical spacing between each line of text in a paragraph. The default value varies between browsers, but it tends to be around 1.2.

This unitless number is a ratio based on the font size. It functions just like the em unit. With a line-height of 1.2, each line will be 20% larger than the element's font size.

body {
 line-height:1.5;
}
๐Ÿ’ก
The line-height will be 50% larger than the element's font size

Here's the problem: for those who are dyslexic, these lines are packed too closely together, making it harder to read. The WCAG criteria state that line height should be at least 1.5. But this led to a heading with the default font size being way too large; we need to override it specifically for each heading and paragraph

Sensible media defaults

img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
}

Inherit fonts for interactive elements

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

Here's another weird thing: by default, buttons and inputs don't inherit typographical styles from their parents. Instead, they have their own weird styles.

For example, <textarea> will use the system-default monospace font. Text inputs will use the system-default sans-serif font. And both will choose a microscopically small font size (13.333px in Chrome).

๐Ÿ’ก
The font is a rarely-used shorthand that sets a bunch of font-related properties, like font size, font weight, and font family. By setting it to inherit, we instruct these elements to match the typography in their surrounding elements

๐Ÿ’ก
I guess this kind of makes sense; they chose to have different font with interactive elements like textarea elements for this case

Overflow-wrap for text document

p, h1, h2, h3, h4, h5, h6 {
  overflow-wrap: break-word;
}

In CSS, text will automatically line-wrap if there isn't enough space to fit all of the characters on a single line.

๐Ÿ’ก
By default, it will look for "soft wrap" opportunities; these are the characters that the algorithm can split on. In English, it's a white space and hyphens, but this varies from language to language. If a line doesn't have any soft wrap opportunities, it will cause the text to overflow

๐Ÿ’ก
Now that you have it, this will be the baseline for any custom CSS that we found on the NPM. The ideas and concepts will be the same

Introduction to Normalizing CSS

Let's leave the browser's default and make all the browsers' default the same

<!-- firefox and chrome will have different user's agent stylesheet
font-weight: 700 for chrome
font-weight: 400 for firefox. -->
<strong> kind </strong>

Normalizing CSS will unify the browser's default

๐Ÿ˜‡
Normalize CSS is a good choice when you want to maintain some of the default browser styles for elements while ensuring a consistent starting point for your custom styles

Introduction to CSS remedy

CSS Remedy takes a slightly different approach. These days, browsers are far more consistent in how they render CSS. However, there are limitations on how far browsers can improve their User Agent Stylesheet. The defaults for the web have to be consistent with the past. Many desirable changes would break millions of existing websites.

You, however, don't have to stay in the past. You can override the user agent styles with more modern ideas of how CSS should work by default. Introducing CSS Remedy. (https://github.com/jensimmons/cssremedy/issues)

Let's take a look at how CSS Remedy works.

๐Ÿ˜›
CSS Remedy sets CSS properties or values to what they would be if the CSSWG were creating the CSS today, from scratch, and didn't have to worry about backward compatibility.

Conclusion

The choice between Reset CSS, Normalize CSS, or Remedy.css depends on your specific project requirements and how much control you want over the default styles. If you need complete control and are willing to define all styles yourself, Reset CSS might be appropriate. If you want a more consistent baseline while preserving some default styles, Normalize CSS is a good choice. For a middle-ground approach that fixes common issues while keeping some defaults, Remedy.css could be worth exploring.

About me: I'm a FE developer who likes to share my understanding of my world. If you find this article useful, please subscribe to my blog to receive high-quality content. For now, take care and see you soon

ย