Margins & Padding
Margin creates space outside an element, pushing other elements away. Margins are always transparent and do not have a background color. They are part of the box model's outer layer and can be positive, negative, or auto.
Margin is the primary tool for creating space between sibling elements. Unlike padding, margin can collapse (vertical margins merge into one) and can be negative (pulling elements closer or overlapping them).
| 1 | /* Individual margin properties */ |
| 2 | .element { |
| 3 | margin-top: 16px; |
| 4 | margin-right: 24px; |
| 5 | margin-bottom: 16px; |
| 6 | margin-left: 24px; |
| 7 | } |
| 8 | |
| 9 | /* Auto margins — powerful for centering and pushing */ |
| 10 | .center-block { |
| 11 | width: 300px; |
| 12 | margin-left: auto; |
| 13 | margin-right: auto; |
| 14 | /* Horizontally centers the block within its parent */ |
| 15 | } |
| 16 | |
| 17 | /* Push to the right */ |
| 18 | .push-right { |
| 19 | margin-left: auto; |
| 20 | } |
| 21 | |
| 22 | /* Negative margins — pull elements closer or overlap */ |
| 23 | .pull-up { |
| 24 | margin-top: -20px; /* moves element up by 20px */ |
| 25 | } |
| 26 | |
| 27 | .overlap { |
| 28 | margin-left: -16px; /* shifts element left, can overlap siblings */ |
| 29 | } |
Padding creates space inside an element, between the content and the border. Padded areas inherit the element's background color or image. Unlike margins, padding does NOT collapse and cannot be negative.
| 1 | /* Individual padding properties */ |
| 2 | .element { |
| 3 | padding-top: 24px; |
| 4 | padding-right: 32px; |
| 5 | padding-bottom: 24px; |
| 6 | padding-left: 32px; |
| 7 | } |
| 8 | |
| 9 | /* Padding uses the element's background */ |
| 10 | .card { |
| 11 | background: linear-gradient(135deg, #0D0D0D, #1A1A2E); |
| 12 | padding: 32px; |
| 13 | /* The gradient extends through the padding area */ |
| 14 | border-radius: 8px; |
| 15 | } |
| 16 | |
| 17 | /* Padding relative to font-size with em */ |
| 18 | .button { |
| 19 | font-size: 16px; |
| 20 | padding: 0.75em 1.5em; /* 12px 24px */ |
| 21 | /* Scales proportionally if button font-size changes */ |
| 22 | } |
| 23 | |
| 24 | /* Percentage padding — based on PARENT WIDTH (even for vertical!) */ |
| 25 | .aspect-ratio-box { |
| 26 | padding-top: 56.25%; /* 9/16 * 100 — creates 16:9 aspect ratio */ |
| 27 | height: 0; /* height collapses, padding creates the box */ |
| 28 | position: relative; |
| 29 | overflow: hidden; |
| 30 | } |
Both margin and padding have a powerful shorthand that accepts one to four values. Understanding the shorthand patterns eliminates repetitive code and improves readability.
| Values | Applies To | Example |
|---|---|---|
| 1 value | All four sides | margin: 16px; |
| 2 values | Vertical | Horizontal | margin: 12px 24px; |
| 3 values | Top | Horizontal | Bottom | margin: 8px 16px 12px; |
| 4 values | Top Right Bottom Left (clock order) | margin: 8px 12px 16px 20px; |
| 1 | /* Shorthand patterns — margin and padding work identically */ |
| 2 | |
| 3 | /* 1 value — uniform on all sides */ |
| 4 | .uniform { margin: 16px; padding: 12px; } |
| 5 | |
| 6 | /* 2 values — [vertical] [horizontal] */ |
| 7 | .vertical-horizontal { |
| 8 | margin: 16px 24px; /* top/bottom: 16px, left/right: 24px */ |
| 9 | } |
| 10 | |
| 11 | /* 3 values — [top] [horizontal] [bottom] */ |
| 12 | .three-value { |
| 13 | margin: 8px 16px 12px; /* top: 8px, left/right: 16px, bottom: 12px */ |
| 14 | } |
| 15 | |
| 16 | /* 4 values — top right bottom left (clockwise) */ |
| 17 | .clock-order { |
| 18 | margin: 8px 12px 16px 20px; |
| 19 | /* top: 8px, right: 12px, bottom: 16px, left: 20px */ |
| 20 | } |
| 21 | |
| 22 | /* Common patterns */ |
| 23 | .card { padding: 24px; } /* consistent inner spacing */ |
| 24 | .stack > * + * { margin-top: 16px; } /* stack layout (every child except first) */ |
| 25 | .inline { margin: 0 8px; } /* horizontal gap for inline elements */ |
Margin collapsing is one of the most confusing aspects of CSS. It only applies to vertical margins (top and bottom) between block elements in the same block formatting context. Understanding when collapse happens and how to prevent it is essential for predictable spacing.
| 1 | /* Three types of margin collapse */ |
| 2 | |
| 3 | /* 1. Adjacent siblings — margins merge */ |
| 4 | .sibling-a { margin-bottom: 40px; } |
| 5 | .sibling-b { margin-top: 30px; } |
| 6 | /* Gap = 40px (the larger wins) */ |
| 7 | |
| 8 | /* 2. Parent and first/last child — margins "leak" out */ |
| 9 | .parent { margin-top: 0; } |
| 10 | .child { margin-top: 24px; } |
| 11 | /* The 24px appears outside the parent (pushes parent down) */ |
| 12 | |
| 13 | /* 3. Empty blocks — own margins collapse */ |
| 14 | .empty-block { margin-top: 20px; margin-bottom: 30px; } |
| 15 | /* Empty block contributes 30px (the larger of its own margins) */ |
| 16 | |
| 17 | /* Preventing margin collapse */ |
| 18 | .no-collapse { |
| 19 | display: flow-root; /* creates new BFC */ |
| 20 | /* Alternatives: */ |
| 21 | /* overflow: hidden; (or auto, scroll) */ |
| 22 | /* padding: 1px; (tiny padding prevents collapse) */ |
| 23 | /* border: 1px solid transparent; */ |
| 24 | } |
| 25 | |
| 26 | /* Elements that NEVER collapse margins */ |
| 27 | /* - Flex items */ |
| 28 | /* - Grid items */ |
| 29 | /* - Absolutely positioned elements */ |
| 30 | /* - Float elements */ |
| 31 | /* - Inline-block elements */ |
| 32 | /* - Elements with overflow != visible */ |
Negative margins pull elements in the opposite direction of positive margins. They can pull an element outside its parent, overlap siblings, or counteract other spacing. Negative margins work differently on block vs flex/grid contexts.
| 1 | /* Negative margins — pulling elements */ |
| 2 | .pull-left { |
| 3 | margin-left: -20px; /* shifts element 20px left */ |
| 4 | } |
| 5 | |
| 6 | .pull-up { |
| 7 | margin-top: -24px; /* shifts element 24px up, can overlap previous */ |
| 8 | } |
| 9 | |
| 10 | /* Expanding a child beyond its parent */ |
| 11 | .full-bleed { |
| 12 | margin-left: -50vw; /* pull left to edge */ |
| 13 | margin-right: -50vw; /* pull right to edge */ |
| 14 | width: 100vw; /* compensate for the pull */ |
| 15 | position: relative; |
| 16 | left: 50%; /* center back */ |
| 17 | } |
| 18 | |
| 19 | /* Negative margins in flexbox */ |
| 20 | .flex-overlap { |
| 21 | display: flex; |
| 22 | } |
| 23 | .flex-overlap > * { |
| 24 | margin-right: -8px; /* items overlap slightly */ |
| 25 | } |
| 26 | .flex-overlap > *:last-child { |
| 27 | margin-right: 0; /* remove overlap on last item */ |
| 28 | } |
| 29 | |
| 30 | /* Counteracting parent padding */ |
| 31 | .parent { padding: 24px; } |
| 32 | .child-full { |
| 33 | margin: -24px; /* counteracts parent padding */ |
| 34 | padding: 24px; /* re-apply padding inside */ |
| 35 | /* Effectively the child ignores parent padding */ |
| 36 | } |
warning
Logical properties adapt to the writing direction. Instead of margin-left (physical), you use margin-inline-start (logical). This makes your layouts work correctly in right-to-left (RTL) languages like Arabic and Hebrew without separate stylesheets.
| 1 | /* Physical properties — direction-dependent */ |
| 2 | .element { |
| 3 | margin-left: 16px; /* left margin — wrong for RTL */ |
| 4 | padding-right: 24px; /* right padding — wrong for RTL */ |
| 5 | } |
| 6 | |
| 7 | /* Logical properties — direction-independent */ |
| 8 | .element { |
| 9 | margin-inline-start: 16px; /* start margin — left in LTR, right in RTL */ |
| 10 | margin-inline-end: 16px; /* end margin */ |
| 11 | padding-inline-start: 24px; /* start padding */ |
| 12 | padding-inline-end: 24px; /* end padding */ |
| 13 | margin-block-start: 12px; /* top margin */ |
| 14 | margin-block-end: 12px; /* bottom margin */ |
| 15 | padding-block: 16px; /* top and bottom padding */ |
| 16 | padding-inline: 24px; /* left and right padding (in LTR) */ |
| 17 | } |
| 18 | |
| 19 | /* Shorthand logical properties */ |
| 20 | .rtl-ready { |
| 21 | margin-block: 16px 24px; /* top: 16px, bottom: 24px */ |
| 22 | margin-inline: 8px 16px; /* start: 8px, end: 16px */ |
| 23 | padding-block: 12px; |
| 24 | padding-inline: 20px; |
| 25 | } |
| 26 | |
| 27 | /* border-width logical properties */ |
| 28 | .card { |
| 29 | border-block-start: 2px solid #00FF41; /* top border */ |
| 30 | border-inline-end: 1px solid #333; /* right border in LTR */ |
| 31 | } |
best practice
info