CSS Box Model and Layout¶
Every HTML element is a rectangular box with four layers. Understanding the box model, display, position, and units is foundational for all CSS layout.
Box Model¶
┌────────── Margin ──────────┐
│ ┌──────── Border ──────┐ │
│ │ ┌──── Padding ────┐ │ │
│ │ │ Content area │ │ │
│ │ └─────────────────┘ │ │
│ └──────────────────────┘ │
└────────────────────────────┘
border-box (Always Use)¶
| Box-sizing | width: 200px; padding: 20px; border: 2px |
|---|---|
content-box (default) | Total = 244px |
border-box | Total = 200px (content shrinks to 156px) |
Width and Height¶
width: 300px; width: 50%; width: auto;
min-width: 200px; max-width: 800px;
height: 100px; min-height: 100vh;
overflow: visible | hidden | scroll | auto;
overflow-x: auto; overflow-y: auto;
Gotcha: Percentage height only works if parent has explicit height. Percentage width always works.
Padding¶
padding: 20px; /* All sides */
padding: 10px 20px; /* Vertical | Horizontal */
padding: 10px 20px 15px 25px; /* Top Right Bottom Left (clockwise) */
- Cannot be negative
- Background extends through padding
- Percentage padding is relative to parent's WIDTH (even top/bottom)
Border¶
border: 1px solid #333;
border-radius: 8px; /* Rounded corners */
border-radius: 50%; /* Perfect circle (square element) */
outline: 2px solid blue; /* Outside box model, no layout impact */
outline-offset: 4px;
Border vs Outline: border takes space in box model, outline doesn't. Outline is used for focus indicators.
Margin¶
margin: 20px;
margin: 0 auto; /* Center block horizontally (requires width) */
margin-top: -20px; /* Negative margins pull element */
Margin Collapsing¶
Adjacent vertical margins merge - only the larger one applies:
- Only vertical margins collapse (not horizontal)
- Does NOT happen inside flex/grid containers
- Does NOT happen when padding/border separates parent-child margins
Display¶
display: block; /* Full width, new line */
display: inline; /* Flows with text, ignores width/height */
display: inline-block; /* Inline flow + respects width/height */
display: none; /* Removed from layout entirely */
display: flex; /* Flex container */
display: grid; /* Grid container */
display: none removes from layout. visibility: hidden hides but keeps space.
Position¶
position: static; /* Default: normal flow */
position: relative; /* Offset from normal position, still takes space */
position: absolute; /* Removed from flow, relative to nearest positioned ancestor */
position: fixed; /* Relative to viewport, stays on scroll */
position: sticky; /* Normal until scroll threshold, then fixed */
Relative + Absolute Pattern¶
.parent { position: relative; } /* Establishes context */
.child { position: absolute; top: 0; right: 0; } /* Positioned within parent */
Sticky¶
Requirestop/bottom value. Only works within its containing block. z-index¶
Only works on positioned elements (not static). Common scale: content 0, headers 100, dropdowns 200, modals 1000, toasts 2000.
Float (Legacy)¶
.image { float: left; } /* Text wraps around */
.container::after { content: ""; display: table; clear: both; } /* Clearfix */
Float is legacy for layout. Use Flexbox/Grid. Float remains useful for text wrapping around images.
CSS Units¶
Relative Units¶
| Unit | Relative To | Use |
|---|---|---|
rem | Root font-size (16px default) | Font sizes, spacing (preferred) |
em | Parent font-size (for font-size) / own font-size (other) | Spacing relative to text |
% | Parent property | Widths, padding |
vw/vh | 1% viewport width/height | Full-width/height |
dvh | Dynamic viewport height | Mobile full-height (accounts for browser bar) |
ch | Width of "0" character | Input field widths |
Practical Recommendations¶
- Font sizes:
rem(consistent, accessible, scales with user preference) - Spacing:
remorpx - Widths:
%for fluid,max-widthfor constraints - Heights: avoid fixed, use
min-height - Mobile full-height:
100dvh(not100vhwhich ignores mobile browser bar)
em vs rem¶
html { font-size: 16px; }
.parent { font-size: 20px; }
.child {
font-size: 1.5em; /* 30px (1.5 * parent's 20px) */
font-size: 1.5rem; /* 24px (1.5 * root's 16px) */
padding: 1em; /* relative to element's OWN font-size */
}
Background¶
background: #f5f5f5 url('image.jpg') no-repeat center/cover;
/* Multiple backgrounds with dark overlay */
background:
linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)),
url('image.jpg') center/cover;
/* Gradients */
background: linear-gradient(135deg, #667eea, #764ba2);
background: radial-gradient(circle, #3b82f6, transparent);
background-size: cover fills and crops. contain fits entirely.
Gotchas¶
- Forgetting
border-box: elements larger than expected 100vhon mobile: overflows because it ignores the address bar, use100dvh- Margin collapse surprises: vertical margins between siblings merge
- Percentage padding top/bottom: relative to parent WIDTH, not height
z-indexwithout position: has no effect onstaticelementsemcascading:emcompounds through nested elements,remstays consistent
See Also¶
- css flexbox - 1D layout system
- css grid - 2D layout system
- css responsive design - Viewport units, media queries, fluid sizing
- css selectors and cascade - Selecting elements to style