The Box Model
If there is one mental model you must internalize before writing another line of CSS, it is this: every HTML element is a rectangular box. Not sometimes — always. A heading, a button, an image, a <div> you cannot even see — all boxes. And every box is built from the same four layers, stacked from inside out.
You already know these layers from Figma. CSS just gives them names.
The four layers
Section titled “The four layers”1. Content
Section titled “1. Content”The innermost area. This is where your text, image, or child elements live. You control its size with width and height.
.card { width: 320px; height: 200px;}2. Padding
Section titled “2. Padding”Space inside the box, between the content and the border. Think of it as the inner spacing in a Figma auto-layout frame — pushing the content away from the edges without moving the element itself.
.card { padding: 2rem; /* all four sides */ padding: 1rem 2rem; /* top/bottom 1rem, left/right 2rem */ padding-top: 1rem; /* one side only */}3. Border
Section titled “3. Border”A visible line drawn around the element — exactly like Figma’s stroke. You set its thickness, style, and color:
.card { border: 2px solid #7C3AED; /* width style color */ border-radius: 12px; /* rounded corners */}4. Margin
Section titled “4. Margin”Space outside the box, pushing neighboring elements away. This is not part of the element’s visual area — it is invisible breathing room between boxes. Think of it as the gap between frames in Figma’s layout grid.
.card { margin: 2rem; /* all sides */ margin: 1rem 0; /* top/bottom 1rem, left/right 0 */ margin-bottom: 1.5rem; /* one side only */}Shorthand order
Section titled “Shorthand order”When you give two values — padding: 1rem 2rem — the order is top/bottom first, left/right second. Four values follow the clockwise compass: top, right, bottom, left.
padding: 1rem 2rem 1rem 2rem; /* top right bottom left */The box-sizing trap
Section titled “The box-sizing trap”Here is where most beginners get surprised. By default, width in CSS measures only the content area. If you set a box to width: 300px then add padding: 20px and border: 2px solid, the actual rendered width becomes 344px — not 300px.
This is the opposite of how design tools work. In Figma, the frame boundary includes strokes and inner spacing. The CSS property box-sizing: border-box matches that behavior: width now measures from border edge to border edge — padding and border are included, not added on top.
/* Add this to every project's global styles */*, *::before, *::after { box-sizing: border-box;}With border-box, a width: 300px element is always exactly 300px wide, no matter how much padding or border you add. Padding and border eat into the content area instead of expanding the box outward. Predictable. Figma-like.
display: block, inline, and inline-block
Section titled “display: block, inline, and inline-block”The box model only fully applies when an element is displayed as a block. The display property controls this:
| Value | Behavior |
|---|---|
block | Takes up the full available width, stacks vertically. Default for <div>, <p>, <h1>–<h6>. |
inline | Sits in the flow of text. Width/height have no effect. Default for <span>, <a>, <strong>. |
inline-block | Sits in text flow but respects width, height, padding, and margin. Useful for buttons and badges. |
This is why a <div> stacks below the previous element but a <span> does not — one is block, the other inline.
Try editing the CSS: increase padding on .box, change border width, or adjust the width. With box-sizing: border-box set, the outer edge of .box stays at 320px — the content area shrinks to absorb your changes.