CSS Layout

CSS Box Model

The box model is the foundation of CSS layout. Every element is a box with content, padding, border and margin — learn how it works and how to control it.

beginner14 min readUpdated Sep 15, 2026
reset.css
css
/* reset.css */
*,
*::before,
*::after {
  box-sizing: border-box;
}

.box {
  width: 200px;
  padding: 20px;
  border: 4px solid #3b82f6;
}
Core concept
Every element is a rectangular box
Layers
Content, padding, border, margin
Default box-sizing
content-box
Display basics
block, inline, inline-block
Position values
static, relative, absolute, fixed, sticky
Vertical spacing
Margins can collapse

Hands-on

Try the box model

Edit the HTML and CSS to see how padding, border and margin affect sizing.

Try the box model

Edit the HTML and CSS to see how padding, border and margin affect sizing.

Why it matters

Why the box model matters

Predictable layouts

Understanding the box model lets you size and space elements with confidence — no more mysterious overflow or misaligned content.

Precise positioning

Position properties let you break out of normal flow, layer elements and build complex overlays, modals and sticky headers.

Performance-friendly

Box-model-based layouts are pure CSS — no JavaScript, no reflows, and no layout thrashing. Lean and fast by default.

The big picture

The three layers of every box

Content, padding and border sit inside the margin. Understanding those layers is the key to predictable sizing.

Content & padding

Inside

The content area holds the text or media, and padding pushes the border away from it.

Border

Boundary

The border wraps content and padding; with box-sizing: border-box its width counts inside the size.

Margin

Outside

Margin is the empty space outside the border, and adjacent vertical margins can collapse.

Box model at a glance

The essentials

The box model

Content, padding, border and margin — every element is four nested boxes.

box-sizing

content-box vs border-box changes how width and height are calculated.

Display property

block, inline and inline-block control flow and layout.

Positioning

static, relative, absolute, fixed and sticky break elements out of normal flow.

Z-index

Stacking context controls which elements appear on top.

Margin collapse

Vertical margins merge — a quirk every CSS developer must understand.

A short history

How layout sizing evolved

  1. 1996

    CSS1 box model

    The original CSS specification introduces margin, border, padding and content as distinct layers.

    96
  2. 1998

    CSS2 positioning

    relative, absolute, fixed and z-index give developers full control over element placement.

    98
  3. 2011

    box-sizing standardised

    The border-box value is formalised, ending years of browser-specific quirks.

    11
  4. 2018

    Position sticky arrives

    Sticky positioning ships in all major browsers with no JavaScript needed.

    18
  5. Today

    Modern layout baseline

    The box model remains the foundation under Flexbox, Grid and every other CSS layout system.

    Today

The complete guide

CSS Box Model: Everything you need to know

What is the box model?

The CSS box model is the foundational concept behind every layout on the web. It describes how every HTML element is rendered as a rectangular box with four distinct layers: content, padding, border and margin. Whether you are styling a simple paragraph or building a complex dashboard, the box model determines how much space an element occupies and how it relates to its neighbours.

Think of it like a picture frame. The picture itself is the content. The matting around it is the padding. The frame is the border. And the space between this frame and the next one on the wall is the margin. Every element on a web page works exactly this way — nested boxes inside nested boxes.

The four layers

Content is the innermost layer — the text, image, video or other media the element holds. Its size is set with width and height (or by the content itself if those are not specified).

Padding sits between the content and the border. It adds breathing room inside the element so text does not crowd the edges. Padding is transparent by default, so the background colour or image of the element shows through it.

Border wraps the padding and content. It has width, style and colour. Borders can be decorative or structural — they are the visible edge that separates the element from the outside world.

Margin is the outermost layer. It pushes other elements away. Unlike padding, margin is always transparent and sits outside the element’s border. Margins are the primary tool for controlling spacing between elements.

box-sizing: content-box vs border-box

The box-sizing property changes how the browser interprets width and height.

With the default value, content-box, the width and height you set apply only to the content area. Padding and border are added on top. So a div with width: 200px, padding: 20px and a 4px border actually renders at 248px wide. This is counter-intuitive and is the single most common source of layout bugs for beginners.

With border-box, width and height include padding and border. The same div with width: 200px, padding: 20px and a 4px border stays exactly 200px wide — the content area shrinks to make room. This is how most developers expect sizing to work, and it is why a global reset like this is standard practice:

/* reset.css */
*,
*::before,
*::after {
  box-sizing: border-box;
}

Border-box makes layouts predictable. You set a width, and the element respects it. There is no mental arithmetic to figure out why your columns are wider than expected. Use it everywhere and forget the headaches.

Block vs inline vs inline-block

Every element has a default display behaviour that controls how it participates in layout.

Block elements start on a new line and stretch to fill the full width of their parent. They stack vertically. Examples include div, p, h1 through h6, section, article, header, footer and ul. Block elements accept width, height, margin on all sides and padding on all sides.

Inline elements flow within text without breaking the line. They only take up as much width as their content needs. Examples include span, a, strong, em, img and code. Inline elements ignore width and height, and vertical margin and padding do not affect surrounding layout — they visually shift but do not push other elements.

Inline-block elements are a hybrid. They flow inline like text but behave like blocks internally — they accept width, height, margin and padding on all sides. Navigation links, badges and tags are classic use cases. They remain in the text flow but give you full control over sizing and spacing.

Property Block Inline Inline-block
Starts on new line Yes No No
Width/height Yes No Yes
Vertical margin/padding Yes No (visual only) Yes
Horizontal margin/padding Yes Yes Yes

The display property

The display property is the most powerful layout tool in CSS. It controls not only the box model behaviour but also how an element participates in layout algorithms.

The most common values:

  • block — full-width box, stacks vertically.
  • inline — flows with text, no box-model sizing.
  • inline-block — inline flow with box-model sizing.
  • none — removes the element from layout entirely. It takes no space and is not rendered.
  • flex — turns the element into a flex container. Children become flex items with one-dimensional layout control.
  • grid — turns the element into a grid container. Children are placed in a two-dimensional grid.
  • inline-flex — flex container that flows inline.
  • inline-grid — grid container that flows inline.

Modern CSS gives you flex and grid for layout, but understanding block and inline is still essential because they are the foundation that flex and grid build on. Every element without an explicit display value falls back to block or inline depending on the element type.

Width and height calculations

How width and height are calculated depends entirely on box-sizing.

With content-box:

Actual width = width + padding-left + padding-right + border-left + border-right
Actual height = height + padding-top + padding-bottom + border-top + border-bottom

With border-box:

Actual width = width (padding and border are included)
Actual height = height (padding and border are included)

A practical consequence: with content-box, setting width: 100% on an element with padding or border will cause horizontal overflow. With border-box it works as expected. This is one of the strongest arguments for always using border-box.

For sizing within a container, remember that percentages for width refer to the parent’s content width (even with border-box), while percentages for height require the parent to have an explicit height — otherwise the percentage is treated as auto.

Overflow and scrolling

When content is larger than its container, the overflow property decides what happens.

  • overflow: visible (default) — content spills outside the box. It is visible but can overlap siblings.
  • overflow: hidden — content is clipped at the box edge. No scrollbar, no way to see the rest.
  • overflow: scroll — a scrollbar appears whether it is needed or not.
  • overflow: auto — a scrollbar appears only when content overflows. This is usually the best choice.
  • overflow-x and overflow-y let you control horizontal and vertical overflow independently.

Overflow is especially important with fixed-width containers, modals, code blocks and any element whose content might grow. Without it, unexpected horizontal scrollbars on the page are common.

Margin collapse

Vertical margins have a quirk that surprises nearly every beginner: they collapse. When two vertical margins touch, the larger one wins instead of the two adding together.

/* style.css */
.box-a { margin-bottom: 30px; }
.box-b { margin-top: 20px; }
/* The gap between them is 30px, not 50px */

Margin collapse happens in three situations:

  1. Adjacent siblings — the bottom margin of one and the top margin of the next merge.
  2. Parent and first child — the parent’s top margin collapses with its first child’s top margin (if the parent has no border, padding or content to separate them).
  3. Parent and last child — same as above but for the bottom.

Margin collapse never happens with:

  • Horizontal margins.
  • Flex and grid items (the box model is different inside these containers).
  • Elements with overflow set to anything other than visible.
  • Elements with border or padding that separate the margins.

Understanding margin collapse prevents the “why is this gap the wrong size” problem that drives developers to add arbitrary padding or negative margins.

Positioning: static, relative, absolute, fixed, sticky

The position property takes an element out of or modifies its place in normal document flow.

static is the default. The element sits in normal flow, and top, right, bottom, left and z-index have no effect.

relative keeps the element in flow but lets you offset it with top, right, bottom and left. The original space is preserved — it is like nudging the element visually while keeping its layout slot.

absolute removes the element from flow entirely. It is positioned relative to its nearest positioned ancestor — any ancestor with position set to relative, absolute, fixed or sticky. If no such ancestor exists, it uses the viewport. Absolute elements do not affect the layout of siblings or parents.

fixed also removes the element from flow, but positions it relative to the viewport. It stays in the same place when the page scrolls. Use it for sticky headers, floating action buttons and modals that must stay visible.

sticky is a hybrid. The element scrolls normally until it reaches a threshold (top, right, bottom or left), then it “sticks” in place. It is the modern replacement for JavaScript scroll listeners. Navigation bars that stay at the top while you scroll are the classic use case.

/* style.css */
.sticky-nav {
  position: sticky;
  top: 0;
  z-index: 10;
}

Z-index and stacking context

When elements overlap, z-index determines which one appears on top. It only works on positioned elements — those with position set to anything other than static.

But z-index is not a simple global number. It creates or participates in a stacking context. A stacking context is a self-contained layer that encapsulates its children. A child with z-index: 9999 inside a stacking context with z-index: 1 will never appear above an element with z-index: 2 in the parent context.

Stacking contexts are created by:

  • Elements with position and z-index other than auto.
  • Elements with opacity less than 1.
  • Elements with transform, filter, backdrop-filter or perspective.
  • Elements with isolation: isolate.
  • Elements inside a flex or grid container with a z-index.

Understanding stacking contexts is the key to solving “z-index doesn’t work” problems. The solution is almost never a bigger number — it is understanding which stacking context your element lives in.

Layout best practices

  • Always use box-sizing: border-box globally. It eliminates an entire class of sizing bugs.
  • Avoid width: 100% with padding on content-box elements. Use border-box instead.
  • Prefer max-width over width for content that should not stretch too wide.
  • Use margin: auto for horizontal centering inside block containers.
  • Use overflow: auto instead of overflow: hidden when you want scrollbars for overflowed content.
  • Avoid giving fixed height to containers with dynamic content — let them grow with the content.
  • For vertical spacing, be aware of margin collapse. Use gap in flex/grid or padding on a parent instead.
  • Never use position: absolute for general layout — it breaks the document flow and makes responsive design harder.
  • Use position: sticky instead of JavaScript for scroll-aware headers and sidebars.
  • Keep stacking contexts shallow. Overlapping z-index values across deeply nested components leads to confusion.
  • Test layouts at multiple widths. The box model behaves differently when the viewport shrinks.

Common mistakes

  • Forgetting to set box-sizing: border-box and getting unexpected widths.
  • Using width on inline elements and wondering why nothing changes.
  • Applying margin on inline elements and not getting the spacing expected.
  • Using position: absolute without a positioned parent, causing elements to fly to the viewport corner.
  • Confusion when z-index does not work — usually a stacking context issue.
  • Surprised by margin collapse between parent and child elements.
  • Setting a fixed height on a container and watching content overflow invisibly.
  • Using overflow: hidden to “fix” layout when the real problem is incorrect sizing.

When to use the box model vs Flexbox or Grid

The box model is not a layout system on its own — it is the foundation that all CSS layouts build on. Flexbox and Grid do not replace the box model; they use it. Every flex item and grid cell still has content, padding, border and margin.

Use the box model directly for:

  • Controlling spacing inside and around individual elements.
  • Setting explicit sizes for cards, buttons, inputs and containers.
  • Understanding why elements overflow or do not fit their parents.

Use Flexbox when you need to align and distribute items along one axis — navigation bars, card rows, centreing content.

Use Grid when you need two-dimensional layout with rows and columns — page shells, dashboards, image galleries.

The best CSS developers reach for the box model first to understand what is happening, then layer flex or grid on top for higher-level layout. Learning the box model is not separate from learning modern layout — it is the prerequisite that makes everything else make sense.

Sizing an element

border-box makes width include padding and border, so the element stays the size you set.

Prefer
*,
*::before,
*::after {
  box-sizing: border-box;
}

.box {
  width: 200px;
  padding: 20px;
}
Avoid
.box {
  width: 200px;
  padding: 20px;
  /* actually renders 240px wide */
}

Spacing between items

In flex and grid, gap is clearer and avoids the collapsed-margin surprises.

Prefer
.row {
  display: flex;
  gap: 1rem;
}
Avoid
.row > * + * {
  margin-left: 1rem;
}

FAQ

Frequently asked questions

Keep learning

Related topics from the roadmap.

$ start learning

Ready to start learning Box Model & Layout?

Our interactive tutorial walks you through Box Model & Layout step by step — with quizzes and real code you can run in the browser.