Shorthand Syntax — Both Properties
Both margin and padding use the same shorthand notation:
/* 1 value — all four sides equal */
margin: 16px;
padding: 16px;
/* 2 values — top/bottom | left/right */
margin: 16px 24px; /* 16px top & bottom, 24px left & right */
padding: 8px 16px;
/* 3 values — top | left/right | bottom */
margin: 8px 16px 24px; /* 8px top, 16px horizontal, 24px bottom */
padding: 4px 12px 8px;
/* 4 values — top | right | bottom | left (clockwise from top) */
margin: 8px 16px 24px 0;
padding: 4px 12px 8px 20px;
/* Longhand — individual sides (more explicit, easier to override) */
margin-top: 16px;
margin-right: 24px;
margin-bottom: 16px;
margin-left: 24px;
padding-top: 12px;
padding-right: 20px;
padding-bottom: 12px;
padding-left: 20px;
When using 4 values: Top → Right → Bottom → Left. Think clockwise from the top. The mnemonic "TRouBLe" helps: margin: 10px 20px 30px 40px = Top 10, Right 20, Bottom 30, Left 40.
Centering with margin: auto
Setting margin-left: auto and margin-right: auto on a block element distributes the available horizontal space equally on both sides, centering the element. The element must have a defined width smaller than its container.
/* Classic center: constrained width + auto horizontal margin */
.container {
max-width: 1200px;
width: 100%;
margin: 0 auto; /* 0 top/bottom, auto left/right */
}
/* Center any block element */
.card {
width: 400px;
margin-left: auto;
margin-right: auto;
}
/* Push element to the right (auto left only) */
.btn-right {
display: block;
width: fit-content;
margin-left: auto;
}
/* margin: auto in flexbox — push flex item to far end */
.nav { display: flex; }
.nav .spacer { margin-left: auto; } /* pushes everything after it to the right */
Margin Collapse – In Depth
Vertical margins between adjacent block elements merge (collapse) into a single margin equal to the larger value.
/* SCENARIO 1: Adjacent siblings */
h2 { margin-bottom: 32px; }
p { margin-top: 16px; }
/* Gap between h2 and p = 32px (not 48px) */
/* SCENARIO 2: Parent and first/last child */
.parent { margin-top: 40px; }
.child:first-child { margin-top: 20px; }
/* The child's top margin collapses into the parent's margin */
/* Both become 40px — they don't add! */
/* PREVENT collapse on parent with: */
.parent {
padding-top: 1px; /* any padding prevents collapse */
/* OR: */
border-top: 1px solid transparent;
/* OR: */
display: flow-root; /* creates new formatting context */
/* OR: */
overflow: hidden;
}
When a parent has display: flex or display: grid, its children's margins never collapse with each other or with the parent. This is one of many reasons modern CSS layout uses flexbox and grid rather than block flow for complex layouts.
Negative Margins
Margins can be negative. Negative margins pull the element (or its neighbor) closer — allowing elements to overlap without absolute positioning.
/* Pull element up into previous sibling */
.overlap-card {
margin-top: -40px;
}
/* Extend element beyond its container */
.full-bleed-image {
margin-left: -24px;
margin-right: -24px;
/* extends 24px beyond the container on both sides */
}
/* Classic technique: negative margin + padding for padding on scroll targets */
.anchor-target {
padding-top: 80px; /* offset for fixed header */
margin-top: -80px;
}
/* Negative margin in a grid — removes outer gap */
.grid-wrapper {
margin: 0 -16px; /* compensates for 16px child margins */
}
Percentage Values
When padding or margin is set as a percentage, it is always calculated as a percentage of the element's own width — even for top and bottom values. This is counterintuitive but consistent.
/* On a 1000px wide element: */
padding: 5%; /* = 50px on ALL four sides (5% of width) */
margin: 10%; /* = 100px on ALL four sides */
/* Classic responsive aspect ratio trick (before aspect-ratio property) */
.video-wrapper {
width: 100%;
padding-top: 56.25%; /* 9/16 = 56.25% — forces 16:9 aspect ratio */
position: relative;
}
.video-wrapper iframe {
position: absolute;
inset: 0; /* fills the padding-top space */
}
/* Modern way — use aspect-ratio property instead */
.video-wrapper {
width: 100%;
aspect-ratio: 16 / 9;
}
Logical Properties – Writing Mode Aware Spacing
Modern CSS provides logical properties that adapt to writing direction (LTR/RTL) and writing mode (horizontal/vertical):
/* Physical (LTR-specific) → Logical (writing-mode aware) */
margin-top → margin-block-start
margin-bottom → margin-block-end
margin-left → margin-inline-start
margin-right → margin-inline-end
padding-top → padding-block-start
padding-bottom → padding-block-end
padding-left → padding-inline-start
padding-right → padding-inline-end
/* Shorthand logical properties */
margin-block: 16px; /* top + bottom */
margin-inline: 24px; /* left + right */
padding-block: 8px;
padding-inline: 16px;
/* These flip automatically in RTL documents */
/* For international sites: prefer logical properties */
Professional Spacing Patterns
/* 1. Section vertical rhythm */
section { padding: 80px 0; }
@media (max-width: 768px) { section { padding: 48px 0; } }
/* 2. Card component */
.card {
padding: 24px;
border-radius: 12px;
}
/* 3. Stack spacing — the "lobotomized owl" */
.stack > * + * { margin-top: 1rem; }
/* 4. Horizontal container with safe gutters */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 24px; /* prevents content from touching viewport edges */
}
/* 5. Consistent type spacing */
h1 { margin: 0 0 .5em; }
h2 { margin: 2em 0 .5em; } /* space before heading, tight after */
p { margin: 0 0 1em; }
/* 6. Button internal spacing */
.btn { padding: 10px 24px; }
.btn-sm { padding: 6px 14px; }
.btn-lg { padding: 14px 32px; }
/* 7. Remove all browser default spacing */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
📋 Summary
- Shorthand: 1 value (all) → 2 (TB|LR) → 3 (T|LR|B) → 4 (T|R|B|L clockwise).
margin: 0 autocenters block elements horizontally (requires explicit width).- Margin collapse — vertical margins merge to the larger value. Prevented by flex/grid, padding, or
display: flow-root. - Negative margins — pull elements together or create overlap effects.
- Percentage values — always relative to the element's own width, even for top/bottom.
- Logical properties (
margin-inline,padding-block) — adapt to writing direction automatically. - Use
gapin flexbox/grid instead of margins for spacing between children.
Frequently Asked Questions
Use gap in flex/grid containers for spacing between items — it's cleaner and more predictable. gap: 16px on a flex container adds 16px between all items without adding outer margins. Use margin for spacing between sections and between block-level elements. Avoid using margin on flex/grid children for internal layout spacing — gap is simpler and doesn't suffer from margin collapse.
Two common reasons: (1) The element has no explicit width (or max-width) — auto centering only works when the element's width is less than its container. Without a width, a block element stretches to 100% of its container with no space to distribute. (2) The element is not a block — margin: 0 auto doesn't work on inline elements. Add display: block if needed, or use flexbox justify-content: center on the parent instead.
For most spacing: rem — scales with the user's font size preference and is consistent regardless of nesting. For component-internal padding that should scale with the component's own font size (like button padding): em. For fixed pixel-precise spacing (like 1px borders): px. Avoid percentages for general spacing unless you specifically want something proportional to the width — the behavior (always relative to width, even for vertical margins) is confusing.