Browser Defaults & Resetting CSS
Every browser ships with its own built-in stylesheet. Before you write a single line of CSS, the browser has already applied styles to your HTML. Understanding and controlling these defaults is the foundation of consistent cross-browser design.
What Are Browser Default Styles?
Every browser (Chrome, Firefox, Safari, Edge) includes a built-in stylesheet called the user agent stylesheet. It provides default visual styles for every HTML element so that unstyled pages are still readable.
Examples of browser defaults:
| Element | Default browser style |
|---|---|
body |
margin: 8px |
h1 |
Large font-size, bold, top and bottom margin |
p |
Top and bottom margin |
a |
Blue colour, underlined |
ul, ol |
Left padding, disc/decimal list markers |
button |
OS-native button appearance |
input |
OS-native input appearance, border |
Browser defaults are like a furnished apartment β someone else has put furniture in it before you arrived. You can add your own furniture and rearrange things, but first you need to know what's already there. Some of it you'll keep. Some of it you'll throw out. Either way, you need to be aware of it.
Why Defaults Cause Problems
The trouble is that different browsers have slightly different default stylesheets. What looks correct in Chrome might have slightly different spacing in Firefox or Safari. This is the original cross-browser CSS problem.
/* The body margin: 8px default means your content doesn't touch the edges.
But some browsers use slightly different values.
A new developer writes: */
body {
background: navy;
}
/* ...and wonders why there's a white gap around the edges.
The answer: browser default margin: 8px */
The CSS Reset Approach
A CSS reset is a small stylesheet you load before your own CSS that aggressively removes all browser defaults β setting everything back to a consistent baseline across all browsers.
The most famous is Eric Meyer's Reset CSS (2011):
/* A simplified version of a CSS reset */
html, body, div, span, h1, h2, h3, h4, h5, h6,
p, blockquote, pre, a, abbr, em, img, ol, ul, li,
form, label, table, tbody, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
body { line-height: 1; }
ol, ul { list-style: none; }
The philosophy: wipe the slate completely clean, then build everything intentionally from scratch.
Pros: Maximum control. Nothing unexpected.
Cons: You have to re-style everything yourself, including basic things like list markers and heading sizes.
The Normalize Approach
Normalize.css (by Nicolas Gallagher, 2012) takes a different philosophy: instead of removing all defaults, it makes browser defaults consistent across browsers, while keeping the useful ones.
/* Normalize.css does things like: */
/* 1. Correct the line height in all browsers */
html { line-height: 1.15; }
/* 2. Remove the margin in all browsers */
body { margin: 0; }
/* 3. Render the main element consistently in IE */
main { display: block; }
/* 4. Correct font size and margin on h1 elements within section/article */
h1 { font-size: 2em; margin: 0.67em 0; }
Pros: Keeps sensible defaults. Headings still look like headings. Less to write from scratch.
Cons: Less predictable if you don't know what Normalize kept.
The Modern Minimal Reset
In 2021 and beyond, many developers use a lightweight custom reset β a small set of rules that fixes the most common pain points without being as extreme as Meyer's reset:
/* Modern CSS Reset (Josh Comeau style, simplified) */
*, *::before, *::after {
box-sizing: border-box; /* prevents width from blowing out with padding */
}
* {
margin: 0; /* removes browser default margins */
}
body {
line-height: 1.5; /* more readable than browser default */
-webkit-font-smoothing: antialiased; /* smoother fonts on Mac */
}
img, picture, video, canvas, svg {
display: block;
max-width: 100%; /* images never overflow their container */
}
input, button, textarea, select {
font: inherit; /* form elements inherit font from parent */
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word; /* prevents text overflow */
}
This is what most modern projects start with. It's short, well-reasoned, and fixes the common issues without removing everything useful.
The box-sizing: border-box Rule
This is the single most important reset rule. By default (box-sizing: content-box), when you set width: 200px on an element and add
padding: 20px, the element becomes 240px wide β the
padding is added on top of the width.
With box-sizing: border-box, padding and borders are
included inside the width you set:
/* content-box (browser default β confusing) */
.box {
width: 200px;
padding: 20px;
/* actual width rendered: 200 + 20 + 20 = 240px */
}
/* border-box (what everyone actually wants) */
*, *::before, *::after {
box-sizing: border-box;
}
.box {
width: 200px;
padding: 20px;
/* actual width rendered: 200px (padding is inside) */
}
Put
*, *::before, *::after { box-sizing: border-box; } at
the top of every project's CSS. It makes sizing elements
dramatically more intuitive and predictable.
Viewing Browser Defaults in DevTools
You can see exactly what browser default styles are being applied to any element:
- Right-click any element on a page β click Inspect.
- In the Styles panel, scroll to the bottom β you'll see a section labelled "user agent stylesheet".
- These are the browser's default rules being applied to that element.
- Your own CSS rules appear above them β and can override them.
Interview Questions
What is the user agent stylesheet?
The built-in CSS stylesheet that every browser ships with. It provides default visual styles for HTML elements so unstyled pages are readable. Different browsers have slightly different user agent stylesheets, which is the root cause of cross-browser inconsistency.
What is the difference between a CSS reset and Normalize.css?
A CSS reset aggressively removes all browser defaults to give you a blank slate. Normalize.css instead makes browser defaults consistent across browsers while preserving useful ones. Resets require more manual styling; Normalize requires less but leaves some browser-specific values in place.
Why do developers use box-sizing: border-box?
The browser default (content-box) adds padding and borders on top of a declared width, making sizing unpredictable. With border-box, padding and borders are included inside the declared width, making layouts far more predictable and easier to calculate.
ποΈ Exercise
Create a blank HTML page with only an <h1>, a
<ul> with three items, and a
<button>. Open it in the browser with no CSS at
all. Then open DevTools and find the "user agent stylesheet"
entries for each element. Write down what default styles the
browser is applying.
Then add this minimal reset and observe what changes:
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
body { line-height: 1.5; }
img, picture { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; }
Summary
- Every browser has a built-in user agent stylesheet that styles HTML elements before your CSS runs.
- Different browsers have slightly different defaults β the source of classic cross-browser CSS bugs.
- A CSS reset removes all browser defaults to give you a clean slate (more work, total control).
- Normalize.css makes defaults consistent across browsers while preserving useful ones.
- The modern minimal reset fixes the most painful issues (margin, box-sizing, font inheritance) without being as extreme.
-
box-sizing: border-boxon all elements is the single most important reset rule β always use it. - Use DevTools β Styles panel β "user agent stylesheet" section to see what defaults the browser is applying.