Entry 01

The reset

Start every new project with it. In an existing project add one rule at a time and look at the result, because min-width: 0 and the font rules change how things already render.

Open
Make the frame narrower. The two halves stay equal, the heading stays balanced, and the wide image stays inside.
Code CSS · 40 lines
*,
*::before,
*::after {
  box-sizing: border-box;
  min-width: 0;
}

:root {
  interpolate-size: allow-keywords;
  scrollbar-gutter: stable;
  text-wrap: pretty;
  overflow-wrap: break-word;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

body {
  margin: 0;
  min-height: 100svh;
}

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

img, svg, video {
  display: block;
  max-width: 100%;
  height: auto;
}

input, textarea, select { font-size: max(16px, 1rem); }

button, a, [role="button"] { touch-action: manipulation; }

button, [role="button"] {
  user-select: none;
  -webkit-user-select: none;
}
Why it works, the rules and the credits 14 reasons · 8 rules · support · credits

Why it works

  1. min-width: 0 lets flex and grid items shrink below their content. Their default is min-width: auto, which is why a long word or a wide child overflows a grid.
  2. interpolate-size: allow-keywords turns on transitions to and from auto for the whole page. Accordion that animates its height depends on it.
  3. text-wrap: pretty tells the browser to spend more effort on line breaks. It avoids a last line that holds one short word, and Safari also evens out the ragged edge. The property inherits, so :root reaches every element.
  4. text-wrap: balance gives headings lines of similar length.
  5. font-synthesis: none stops the browser from faking a bold or italic that the font file lacks.
  6. The two smoothing rules switch macOS from subpixel to grayscale antialiasing. Text renders thinner and matches the weight shown in Figma. Other systems ignore them.
  7. 100svh is the viewport height with the mobile browser toolbars showing, so the page never sits behind them. 100dvh changes as the toolbar moves and re-lays out the page each time.
  8. scrollbar-gutter: stable reserves the scrollbar's space. The page does not shift sideways when a modal locks scrolling or when content grows past one screen.
  9. overflow-wrap: break-word breaks a word that cannot fit on a line, such as a URL, where it would otherwise run out of its box. Long text that wraps, truncates or clamps has the rest.
  10. -webkit-text-size-adjust: 100% stops iOS from inflating text in landscape.
  11. -webkit-tap-highlight-color: transparent removes the gray flash iOS and Android paint over a tapped element.
  12. Inputs at 16px or more stop iOS Safari from zooming the page on focus. It does not zoom back out.
  13. touch-action: manipulation tells the browser the element never double-tap zooms, so click fires without the wait.
  14. user-select: none on controls stops a long press from selecting a button's label.

Rules

  1. Load every weight and style the design uses. With font-synthesis: none a missing bold renders as regular.
  2. With min-width: 0 on everything, a sized image, icon or avatar in a flex row shrinks to make room for the text beside it. Give it flex: none.
  3. The reset removes the tap highlight, so every pressable element needs its own :active state. Press feedback has it.
  4. Never fix input zoom with user-scalable=no or maximum-scale=1. That takes zoom away from people who need it.
  5. Keep user-select: none to controls. Never set it on body or on links, because people copy text.
  6. Text the user types inherits pretty, in textarea and contenteditable. If lines shift while typing, set text-wrap: stable on that element.
  7. The reserved gutter puts centered content slightly off-center on a page too short to scroll. Chris Coyier documents this. Accept it.
  8. svh is for documents and heroes. An app shell with UI pinned to the bottom uses height: 100dvh, so it tracks the toolbar. Emil Kowalski draws this line in his mobile-native skill.

Support

text-wrap: pretty in Chrome 117 and Safari 26, ignored by Firefox. scrollbar-gutter in Chrome 94, Firefox 97, Safari 18.2. interpolate-size in Chrome 129 only. The rest works everywhere.

Credits

Borrowed from: Travis Arnold, @souporserious on X, 2025-04-02, "2025 CSS Reset" · Ayomidé Daniel, @aydahnizzy on X, 2025-10-10, for the font rules · text-wrap: pretty on everything is a house rule · Kevin Powell, 3 modern CSS properties to add to your reset, 2026-04-02, for svh and the gutter · Emil Kowalski, mobile-native skill, for the touch rules · Chris Coyier, The Downsides of scrollbar-gutter: stable, 2025-12-03 · Ahmad Shadeed, Defensive CSS, for overflow-wrap and the flex: none rule

Background: Jen Simmons, Better typography with text-wrap pretty · Adam Argyle, CSS text-wrap: pretty

Docs: MDN: text-wrap · MDN: font-synthesis · MDN: font-smooth