Suggest an editImprove this articleRefine the answer for “CSS box-sizing property”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`box-sizing`** controls how `width` and `height` are calculated in CSS. `content-box` (default) adds padding and border on top of the stated width. `border-box` keeps the stated width as the final outer size. ```css *, *::before, *::after { box-sizing: border-box; /* industry-standard reset */ } ``` **Key point:** with `border-box`, `width: 200px` is always 200px, regardless of padding or border.Shown above the full answer for quick recall.Answer (EN)Image**`box-sizing`** defines whether an element's `width` and `height` include only content, or content plus padding and border. ## Theory ### TL;DR - `content-box` (browser default): `width: 200px` + `padding: 20px` = 240px actual. Padding adds outside. - `border-box`: `width: 200px` is the final size. Padding carves space from inside. - Analogy: content-box is ordering a 200px pizza where toppings spill beyond the edge; border-box is a box where everything fits inside exactly 200px. - Decision rule: use `border-box` everywhere via `* { box-sizing: border-box; }`. That is what Bootstrap, Tailwind, and React resets all do. ### Quick example ```css .content-box { box-sizing: content-box; /* browser default */ width: 200px; padding: 20px; border: 5px solid; /* actual total width: 200 + 40 + 10 = 250px */ } .border-box { box-sizing: border-box; width: 200px; padding: 20px; border: 5px solid; /* actual total width: 200px, content area = 150px */ } ``` The first box overflows to 250px. The second stays at exactly 200px. Same property values, different sizing model. ### Key difference Browsers default to `content-box` per the CSS2.1 spec. So `width: 200px; padding: 20px` produces an element that actually takes up 240px. Most developers expect the opposite. That mismatch is why horizontal scroll on mobile has been the number one CSS bug on StackOverflow for years. `border-box` fixes it: the number you write becomes the number you get. ### When to use - Fixed-width UI components (cards, modals, buttons) - `border-box`, so padding does not break the layout. - Flex or grid children - `border-box`, prevents items from overflowing their containers. - Text-heavy content blocks where content drives the size - `content-box` works here, though `border-box` does not hurt either. - Universal reset - `border-box` on `*` is the industry standard. Paul Irish's 2012 article showed it fixes most padding-related layout bugs instantly. ### Comparison table | | content-box | border-box | |---|---|---| | What `width` means | content area only | total outer size | | Browser default | Yes (CSS2.1) | No | | Content area size | equals `width` | `width - padding - border` | | When to use | pure content sizing (rare) | 99% of layouts | ### How browsers calculate this CSS engines like Blink (Chrome) and Gecko (Firefox) read `box-sizing` during style resolution. For `border-box`, the engine subtracts `padding + border` from the specified width before assigning the content width. For `content-box`, it skips that step. This happens in the layout phase, before paint, per CSS2.1 section 10.2. ### Common mistakes **Forgetting the browser default.** You set `width: 300px; padding: 24px` and the card overflows its container. The total is 348px, not 300px. Fix: add the universal reset to your global styles. ```css /* Standard global reset */ *, *::before, *::after { box-sizing: border-box; } ``` **Mixing box-sizing inside flexbox.** One child uses `content-box`, another `border-box`. The layout breaks because flex tracks outer sizes. Set `box-sizing` on the container and let children inherit. ```css .flex-container { display: flex; box-sizing: border-box; /* children inherit */ } .flex-child { flex: 1; padding: 20px; /* stays within flex track, no overflow */ } ``` **Using `border-box` on `img` elements.** Images rarely have padding or border by default. The value does not cause bugs, but it will silently shrink content space if you later add padding. Better to skip it for images or set `content-box` explicitly. **Forgetting pseudo-elements.** `::before` and `::after` do not automatically inherit `box-sizing` in older resets. That is why the modern pattern explicitly includes `*::before, *::after`. ### Real-world usage - React (create-react-app, Vite) - `* { box-sizing: border-box; }` in `index.css` by default. - Tailwind CSS - applies `border-box` on `html` and `body` via preflight reset. - Bootstrap 5 - universal `border-box` selector for grid consistency. - Next.js - global reset includes it to prevent hydration mismatches. - Material UI - cards and buttons use `border-box` to match design tokens. ### Follow-up questions **Q:** What is the browser default for `box-sizing` and why does it matter? **A:** `content-box`, inherited from CSS2.1. Without a reset, every element with padding grows larger than its stated width. That breaks layouts in ways that are surprisingly hard to trace. **Q:** How does `box-sizing` interact with `min-width` and `max-width`? **A:** Same rules apply. With `border-box`, `min-width: 200px` means the total outer size is at least 200px. Padding and border are still subtracted from the content area inside. **Q:** Does `box-sizing` affect `::before` and `::after`? **A:** Yes. They inherit from the parent, but older reset stylesheets only targeted `*`. The modern pattern is `*, *::before, *::after { box-sizing: border-box; }` to cover pseudo-elements explicitly. **Q:** In a component library, how do you handle `box-sizing` conflicts when users override it with their own CSS? **A:** Document that the library assumes `border-box` and instruct users to include the universal reset. For fully isolated components, Shadow DOM encapsulation prevents external overrides entirely. Both approaches are used in production libraries. ## Examples ### content-box vs border-box side by side ```html <!DOCTYPE html> <html> <style> .content-box { box-sizing: content-box; width: 200px; padding: 20px; border: 5px solid navy; background: lightblue; margin-bottom: 12px; } .border-box { box-sizing: border-box; width: 200px; padding: 20px; border: 5px solid darkred; background: lightcoral; } </style> <div class="content-box">Total width: 250px (content 200 + padding 40 + border 10)</div> <div class="border-box">Total width: 200px (padding and border fit inside)</div> </html> ``` The blue box is 250px wide despite `width: 200px`. The red box is exactly 200px. Open DevTools, hover both elements, and check the box model panel to see the difference visually. ### React card component A typical pattern in component libraries. Without `border-box`, adding padding causes the card to exceed its container width and push other elements out of alignment. ```jsx function RepoCard({ name, stars }) { return ( <div style={{ boxSizing: 'border-box', /* 300px stays 300px even with padding */ width: '300px', padding: '16px', border: '1px solid #ddd', borderRadius: '6px' }}> <h3>{name}</h3> <span>⭐ {stars}</span> </div> ); } // Output: card always occupies exactly 300px, no parent overflow ``` Hover state padding changes do not shift the layout. I saw this cause a visible layout jump in production once, when someone removed the global reset and every card on the page widened by 32px overnight.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.