# It’s 2026, are we still doing CSS resets?

CSS resets are still useful, but mine has become less about removing browser
styles and more about setting a few practical defaults. Here is the small,
slightly aggressive reset I tend to start projects with.

This is not a comprehensive reset or a normalization stylesheet. It is a
collection of defaults that prevent problems I run into repeatedly. Some of them
make strong assumptions, so take the useful parts rather than copying the whole
thing blindly.

## Let everything shrink

```css
* {
  min-width: 0;
}
```

Flex and grid children default to `min-width: auto`, which can make long text or
other content push a layout wider than intended. Applying `min-width: 0`
globally avoids having to remember it for every component.

## Make elements positioning contexts

```css
* {
  position: relative;
}

html,
body {
  position: initial;
}
```

This is the most aggressive rule in the reset. It makes the nearest parent a
positioning context for absolutely positioned children, which is often exactly
what I want in component-based layouts.

It can also change where existing or third-party elements are positioned, so
leave it out if that is not a convention you want across the entire project. I
reset `html` and `body` because making either one relative can cause unexpected
positioning behavior is some UI libraries, including React Aria.

## Tame vertical overscroll

```css
html,
body {
  overscroll-behavior-y: none;
}
```

This disables the vertical rubber-band effect on macOS. Using the y-axis
property instead of the `overscroll-behavior` shorthand leaves horizontal back
and forward swipe gestures alone. It is still a preference rather than a neutral
reset, and may not suit content-heavy sites where scroll chaining is expected.

Read more about
[macOS mouse gestures and overscroll behavior](/overscroll-behavior).

## Give the page a minimum height

```css
body {
  min-height: 100dvh;
}
```

`100dvh` makes the body at least as tall as the dynamic viewport, including when
mobile browser controls change the visible area. This is a useful base for
full-height layouts and [sticky footers](/sticky-footer-with-pure-css).

## Remove the inline image gap

```css
img {
  display: block;
}
```

Images are inline elements by default, so they reserve space for the text
baseline. Most of the time I use images as blocks and do not want that gap.

## Improve heading and paragraph wrapping

```css
h1,
h2,
h3,
h4,
p {
  text-wrap: pretty;
}
```

`text-wrap: pretty` asks the browser to favor nicer line breaks and avoid short
last lines when possible (also known as orphans). It is a small typographic
improvement, though the browser ultimately decides how to balance the lines.

## Make SVG transforms predictable

```css
svg {
  display: inline-block;
  flex-shrink: 0;
}

svg * {
  transform-origin: center;
  transform-box: fill-box;
}
```

Inline-block SVGs are easier to size and align, and icons rarely need to shrink
inside a flex layout. Setting the transform box and origin also makes rotations
and scaling happen around each SVG element's visual center.

These defaults assume your SVGs are mostly icons. They can be too broad for
illustrations, charts, or SVGs whose elements need a different transform origin.

## The full reset

Here is the complete version without comments, ready to copy and adjust:

```css
* {
  min-width: 0;
  position: relative;
}

html,
body {
  position: initial;
  overscroll-behavior-y: none;
}

body {
  min-height: 100dvh;
}

img {
  display: block;
}

h1,
h2,
h3,
h4,
p {
  text-wrap: pretty;
}

svg * {
  transform-origin: center;
  transform-box: fill-box;
}

svg {
  display: inline-block;
  flex-shrink: 0;
}
```
