My CSS reset with line-by-line explanation

The bare minimum CSS reset that I always use to start with



TLDR

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

body {
  /* colors */
  --text-color: #333333;
  --bg-color: #f1f5ef;
  --link-text-color: #0070f3;
  --button-text-color: white;
  --button-bg-color: #7c3aed;
  --button-hover-bg-color: #c4b5fd;

  /* line-height */
  --paragraph-line-height: 1.5;

  overflow-wrap: break-word;
  tab-size: 2;
  color: var(--text-color);
  background-color: var(--bg-color);
}

h1,
h2,
h3,
h4,
h5,
h6 {
  margin-block-end: 1rem;
}

p,
ul {
  line-height: var(--paragraph-line-height);
  margin-block-end: 1rem;
}

a {
  color: var(--link-text-color);
  text-decoration: none;
}
a:hover,
a:focus,
a:active {
  text-decoration: underline;
}

button {
  padding: 0.25rem 0.5rem;
  color: var(--button-text-color);
  background-color: var(--button-bg-color);
  border: none;
  border-radius: 0;
  cursor: pointer;
}
button:focus,
button:hover,
button:active {
  background-color: var(--button-hover-bg-color);
}

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

Explanation

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
  • box-sizing: border-box is the most important one. It even should be browser's default.
  • For margin and padding, I like to remove them all and start with zero space. Later, I will gradually add it to each tag.

body {
  /* all possible colors in your website */
  --text-color: #333333;
  --bg-color: #f1f5ef;
  --link-text-color: #0070f3;
  --button-text-color: white;
  --button-bg-color: #7c3aed;
  --button-hover-bg-color: #c4b5fd;
  /* ... other colors */

  /* line-height */
  --paragraph-line-height: 1.5;

  overflow-wrap: break-word;
  tab-size: 2;
  color: var(--text-color);
  background-color: var(--bg-color);
}
  • I think all possible colors in our website should be centralized in a single place. I use CSS variables to define all values here. These variables will be used across all css files.
  • Optionally, you can centralize line-height, z-index, or spacing here as well.
  • overflow-wrap: break-word to prevent a horizontal scroll when there is a long text, e.g. URL, and the screen size is small.
  • tab-size: 2 for display a tab character as 2 spaces. The tab character might be appeared in textarea and pre tags.

h1,
h2,
h3,
h4,
h5,
h6 {
  margin-block-end: 1rem;
}

p,
ul,
ol {
  line-height: var(--paragraph-line-height);
  margin-block-end: 1rem;
}
  • For margin-block-end (a.k.a. margin-bottom), I think 1rem looks good for headings, paragraph, and list.
  • However, for line-height, I think the browser's default only looks good on headings. It's too tight for others. So, I set it to 1.5 for paragraph and list.

a {
  color: var(--link-text-color);
  text-decoration: none;
}
a:hover,
a:focus,
a:active {
  text-decoration: underline;
}
  • I use my custom color for a normal-state anchor tag. This will also eliminate all browser's default colors for other states. In other words, all :hover, :focus, :active, :visited states will be the same color as a normal state.
  • The outline when a user navigates by pressing a tab key, however, will not be replaced. It's still using the browser's default style.

button {
  padding: 0.25rem 0.5rem;
  color: var(--button-text-color);
  background-color: var(--button-bg-color);
  border: none;
  border-radius: 0;
  cursor: pointer;
}
button:focus,
button:hover,
button:active {
  background-color: var(--button-hover-bg-color);
}
  • I replace most of the browser's default style for button tag. This also makes our button style stays consistence across all browsers / OS.
  • Similar to a tag, the outline is not replaced and still using the browser's default.

img {
  display: block;
  margin-inline: auto;
  max-width: 100%;
}
  • Horizontally center an image.
  • In case the image's width is wider than its container, max-width: 100% will prevent overflow issue.