Tailwind CSS 7 🎨 Core Spacing Scale Mechanics (Padding, Margin, Gap, Space-Between)
Tailwind’s spacing scale is the backbone of consistent layouts. Every padding, margin, gap, and space-between utility draws from a single configurable unit, and in v4 that unit is a CSS variable you can change at runtime. This means the same numeric class — p-4, m-2, gap-6 — always refers to the same physical distance, and changing the base unit rescales the entire system without touching component code.
The scale itself is deceptively simple: one unit equals 0.25rem (4px by default), and utilities accept any multiple of that unit dynamically. There is no fixed list of “allowed” numbers in v4; p-17 works if you need it. The discipline comes from convention, not configuration — most design systems stick to multiples of 4px and a curated set of steps to avoid visual chaos.
This chapter covers the spacing scale mechanics, the four spacing utility families (padding, margin, gap, and space-between), their directional variants, negative margins, logical properties, and the patterns that keep spacing consistent across a codebase.
Key point: Every spacing utility in Tailwind v4 derives from --spacing (default 0.25rem). The numeric suffix multiplies that base: p-4 = 4 × 0.25rem = 1rem. Utilities accept any integer, and directional variants (px, py, pt, mt, etc.) let you target specific sides without custom CSS.
Why the spacing scale exists
The inconsistency problem. Without a scale, developers hardcode pixel values: padding: 13px here, margin: 17px there. The result is a layout that looks subtly broken — elements that almost align but do not, spacing that almost matches but drifts. A scale constrains the possible values, so repeated elements use identical spacing and the layout reads as intentional rather than accidental.
The rescalability problem. A hardcoded 16px is fixed forever. A spacing token derived from --spacing changes when the token changes. If a design review concludes that everything feels cramped, changing --spacing from 0.25rem to 0.3rem rescales the entire UI proportionally.
The semantic clarity problem. p-4 is shorter and more readable than padding: 1rem. The numeric suffix communicates “four units of spacing,” which maps directly to the scale. When a team agrees that 4 means “standard internal padding” and 8 means “page section separation,” the class names themselves document the intent.
The responsive consistency problem. Responsive variants (md:p-6, lg:gap-8) apply the same scale at different breakpoints. Without a shared scale, each breakpoint would need its own hardcoded values, and the relationships between them would be ad hoc rather than systematic.
a. The spacing scale: one unit, any multiple
Tailwind v4 defines a single spacing variable:
@theme {
--spacing: 0.25rem;
}
Every numeric spacing utility multiplies this value:
| Class | Calculation | Value (default) |
|---|---|---|
p-1 | 1 × 0.25rem | 4px |
p-2 | 2 × 0.25rem | 8px |
p-4 | 4 × 0.25rem | 16px |
p-6 | 6 × 0.25rem | 24px |
p-8 | 8 × 0.25rem | 32px |
p-12 | 12 × 0.25rem | 48px |
p-16 | 16 × 0.25rem | 64px |
p-24 | 24 × 0.25rem | 96px |
The px keyword is special: p-px = 1px exactly, bypassing the scale.
In v4, the scale is dynamic. p-17 produces 17 × 0.25rem = 4.25rem. There is no “invalid” number. The scale is a formula, not a lookup table. This is a change from v3, where only predefined values existed unless you extended the config.
The practical recommendation is to stick to established steps — 0.5, 1, 1.5, 2, 3, 4, 6, 8, 12, 16 — because these are the values designers and developers expect. Arbitrary numbers work but fragment the system.
b. Padding utilities
Padding controls the space between an element’s border and its content. Tailwind provides padding utilities for every side combination.
| Class | Applies To | Example |
|---|---|---|
p-4 | All sides | padding: 1rem |
px-4 | Left and right | padding-inline: 1rem |
py-4 | Top and bottom | padding-block: 1rem |
pt-4 | Top | padding-top: 1rem |
pr-4 | Right | padding-right: 1rem |
pb-4 | Bottom | padding-bottom: 1rem |
pl-4 | Left | padding-left: 1rem |
ps-4 | Inline start (logical) | padding-inline-start: 1rem |
pe-4 | Inline end (logical) | padding-inline-end: 1rem |
A card with consistent internal spacing:
<div class="p-6 bg-white rounded-lg shadow">
<h2 class="text-lg font-semibold">Title</h2>
<p class="mt-2 text-gray-600">Content goes here.</p>
</div>
The p-6 applies 24px on all sides. The mt-2 on the paragraph adds 8px of margin between the title and the text.
Padding on an axis:
<button class="px-4 py-2 bg-blue-500 text-white rounded">
Save
</button>
px-4 gives 16px left and right; py-2 gives 8px top and bottom. This is the standard button padding pattern.
c. Margin utilities
Margin controls the space outside an element’s border, separating it from siblings and its parent.
| Class | Applies To | Example |
|---|---|---|
m-4 | All sides | margin: 1rem |
mx-4 | Left and right | margin-inline: 1rem |
my-4 | Top and bottom | margin-block: 1rem |
mt-4 | Top | margin-top: 1rem |
mr-4 | Right | margin-right: 1rem |
mb-4 | Bottom | margin-bottom: 1rem |
ml-4 | Left | margin-left: 1rem |
mx-auto | Center horizontally | margin-inline: auto |
The mx-auto utility is the standard centering technique for block elements with a defined width:
<div class="max-w-2xl mx-auto px-4">
Centered container with horizontal padding.
</div>
Negative margins use a leading hyphen:
<div class="-mt-4">Pulled up by 16px</div>
<div class="-ml-2">Pulled left by 8px</div>
Negative margins are useful for overlapping elements, offsetting grid gaps, and fine-tuning alignment, but they are easy to overuse. Prefer restructuring the layout when possible.
d. Gap utilities
gap controls the space between items in flexbox and grid containers. Unlike margin, which applies to individual elements, gap applies uniformly between all children, eliminating the “first/last child” problem.
| Class | Applies To | Example |
|---|---|---|
gap-4 | Both axes | gap: 1rem |
gap-x-4 | Column gap | column-gap: 1rem |
gap-y-4 | Row gap | row-gap: 1rem |
Flex items with consistent spacing:
<div class="flex gap-4">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
Grid with different horizontal and vertical gaps:
<div class="grid grid-cols-3 gap-x-6 gap-y-4">
<div>Cell</div>
<div>Cell</div>
<div>Cell</div>
</div>
gap is generally preferred over space-x/space-y for flex and grid layouts because it does not depend on child selectors and works correctly with wrapping and dynamic content.
e. Space-between utilities
space-x-* and space-y-* add margin between children, simulating a gap in containers where gap is not applicable or where the design requires margin-based spacing.
| Class | Applies To | CSS |
|---|---|---|
space-x-4 | Left margin on all but first child | margin-left: 1rem |
space-y-4 | Top margin on all but first child | margin-top: 1rem |
space-x-reverse | Reverse horizontal order | Flips margin direction |
Vertical stack with spacing:
<div class="space-y-4">
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<p>Paragraph 3</p>
</div>
This renders margin-top: 1rem on paragraphs 2 and 3, producing uniform vertical spacing without manual margins.
space-x for horizontal lists:
<div class="flex space-x-4">
<span>Item 1</span>
<span>Item 2</span>
<span>Item 3</span>
</div>
The trade-off between space-* and gap: gap is more robust because it does not rely on child selectors and handles flex wrapping correctly. space-* is useful when you need the spacing to come from margin (for example, when the container is not a flex or grid container) or when you need the space-x-reverse behavior for RTL layouts.
f. Logical properties for internationalization
Tailwind v4 supports logical properties that map to physical sides based on text direction.
| Logical Class | Physical Equivalent (LTR) | Physical Equivalent (RTL) |
|---|---|---|
ps-4 | padding-left | padding-right |
pe-4 | padding-right | padding-left |
ms-4 | margin-left | margin-right |
me-4 | margin-right | margin-left |
pbs-4 | padding-top | padding-top |
pbe-4 | padding-bottom | padding-bottom |
For a layout that must work in both LTR and RTL languages, logical properties eliminate the need for direction-specific overrides:
<div class="ps-4 pe-2">
Content with logical padding.
</div>
In LTR, ps-4 is left padding; in RTL, it is right padding. The same class works in both.
g. Responsive and state variants
Every spacing utility accepts responsive prefixes and state modifiers.
<div class="p-4 md:p-6 lg:p-8">
Responsive padding.
</div>
<div class="m-2 hover:m-4">
Margin changes on hover.
</div>
<div class="gap-2 md:gap-4">
Responsive grid gap.
</div>
The pattern is to start with mobile-first values and increase at larger breakpoints. p-4 md:p-6 means 16px on small screens and 24px on medium and up.
Complete Example Session
<!-- ============================================
PART 1: CARD WITH PADDING
============================================ -->
<div class="p-6 bg-white rounded-lg shadow">
<h2 class="text-lg font-semibold">Card Title</h2>
<p class="mt-2 text-gray-600">Card body content.</p>
</div>
<!-- ============================================
PART 2: BUTTON WITH AXIS PADDING
============================================ -->
<button class="px-4 py-2 bg-blue-500 text-white rounded">
Save Changes
</button>
<!-- ============================================
PART 3: CENTERED CONTAINER
============================================ -->
<div class="max-w-2xl mx-auto px-4">
Centered content with horizontal padding.
</div>
<!-- ============================================
PART 4: FLEX ITEMS WITH GAP
============================================ -->
<div class="flex gap-4">
<div class="p-2 bg-gray-100">Item 1</div>
<div class="p-2 bg-gray-100">Item 2</div>
<div class="p-2 bg-gray-100">Item 3</div>
</div>
<!-- ============================================
PART 5: GRID WITH DIFFERENT AXIS GAPS
============================================ -->
<div class="grid grid-cols-3 gap-x-6 gap-y-4">
<div>Cell 1</div>
<div>Cell 2</div>
<div>Cell 3</div>
<div>Cell 4</div>
<div>Cell 5</div>
<div>Cell 6</div>
</div>
<!-- ============================================
PART 6: VERTICAL STACK WITH SPACE-Y
============================================ -->
<div class="space-y-4">
<p>First paragraph.</p>
<p>Second paragraph.</p>
<p>Third paragraph.</p>
</div>
<!-- ============================================
PART 7: NEGATIVE MARGIN FOR OVERLAP
============================================ -->
<div class="relative">
<div class="bg-blue-100 p-4">Base layer</div>
<div class="-mt-4 bg-white p-4 shadow">Overlapping layer</div>
</div>
<!-- ============================================
PART 8: LOGICAL PROPERTIES
============================================ -->
<div class="ps-4 pe-2 py-3 bg-gray-50">
Logical padding works in LTR and RTL.
</div>
<!-- ============================================
PART 9: RESPONSIVE SPACING
============================================ -->
<div class="p-4 md:p-6 lg:p-8">
Padding increases with viewport.
</div>
<div class="gap-2 md:gap-4 lg:gap-6 grid grid-cols-2">
<div>Item</div>
<div>Item</div>
</div>
<!-- ============================================
PART 10: COMPOSED CARD LAYOUT
============================================ -->
<div class="max-w-md mx-auto p-6 bg-white rounded-lg shadow">
<h2 class="text-xl font-semibold mb-4">Profile</h2>
<div class="flex items-center gap-4">
<img src="avatar.jpg" alt="" class="w-12 h-12 rounded-full" />
<div>
<p class="font-medium">Alice Nguyen</p>
<p class="text-sm text-gray-500">Engineer</p>
</div>
</div>
<div class="mt-6 flex gap-2">
<button class="px-4 py-2 bg-blue-500 text-white rounded">Follow</button>
<button class="px-4 py-2 bg-gray-200 rounded">Message</button>
</div>
</div>
These ten parts cover padding, margin, gap, space-between, negative margins, logical properties, responsive spacing, and a composed layout that uses all of them together. Each pattern is idiomatic Tailwind v4.
Quick Reference
Spacing Utility Families
| Family | Prefix | Controls |
|---|---|---|
| Padding | p-*, px-*, py-*, pt-*, pr-*, pb-*, pl-* | Space inside border |
| Margin | m-*, mx-*, my-*, mt-*, mr-*, mb-*, ml-* | Space outside border |
| Gap | gap-*, gap-x-*, gap-y-* | Space between flex/grid items |
| Space Between | space-x-*, space-y-* | Margin between children |
Common Scale Values
| Class | Value (default --spacing: 0.25rem) |
|---|---|
*-0 | 0 |
*-px | 1px |
*-0.5 | 2px |
*-1 | 4px |
*-2 | 8px |
*-3 | 12px |
*-4 | 16px |
*-6 | 24px |
*-8 | 32px |
*-12 | 48px |
*-16 | 64px |
Directional Variants
| Suffix | Sides |
|---|---|
| (none) | All sides |
x | Left and right |
y | Top and bottom |
t | Top |
r | Right |
b | Bottom |
l | Left |
s | Inline start (logical) |
e | Inline end (logical) |
Gap vs Space-Between
| Aspect | gap-* | space-x-* / space-y-* |
|---|---|---|
| Works on | Flex, grid | Any container |
| Mechanism | CSS gap property | margin on all but first child |
| Wrapping | Handles correctly | May need flex-wrap adjustments |
| RTL reversal | Automatic | Needs space-x-reverse |
| Recommended | Preferred for flex/grid | For non-flex containers or RTL |
Best Practices
✅ Do This:
<div class="p-4">Standard padding</div>
<div class="p-6 md:p-8">Responsive padding</div>
<div class="flex gap-4">Gap between flex items</div>
<div class="mx-auto max-w-2xl">Centered container</div>
<div class="ps-4 pe-2">Logical padding for i18n</div>
❌ Don’t Do This:
<div class="p-[13px]">Arbitrary value when p-3 exists</div>
<div class="mt-4 mb-4">Use my-4 for vertical</div>
<div class="space-x-4 flex-wrap">Gap is more robust</div>
<div class="m-4 p-4">Stacking margin and padding on same element</div>
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Spacing looks inconsistent | Mixing scale steps randomly | Stick to a curated set (4, 6, 8, 12, 16) |
| Margin collapse surprises | Vertical margins collapse | Use gap or space-y instead |
| First/last child spacing | space-* adds to all but first | Expected behavior; use gap if problematic |
| Arbitrary brackets overused | Not knowing v4 supports any number | Use p-17 instead of p-[68px] |
| RTL layout broken | Using physical properties | Use logical ps/pe/ms/me |
| Negative margin overlap issues | Overuse of negative margins | Restructure layout with relative positioning |
Real-World Examples
1. Card Padding
<div class="p-6 bg-white rounded-lg shadow">Card content</div>
2. Button Padding
<button class="px-4 py-2 bg-blue-500 text-white rounded">Click</button>
3. Centered Container
<div class="max-w-4xl mx-auto px-4">Page content</div>
4. Flex with Gap
<div class="flex items-center gap-3">Icon and text</div>
5. Grid Gaps
<div class="grid grid-cols-3 gap-6">Grid items</div>
6. Vertical Stack
<div class="space-y-4">Form fields</div>
7. Responsive Section Spacing
<section class="py-8 md:py-12 lg:py-16">Section content</section>
8. Negative Margin Overlap
<div class="-mt-8 bg-white rounded-t-lg p-4">Overlapping card</div>
9. Logical Padding for RTL
<div class="ps-4 pe-2">Bidirectional content</div>
10. Composed Layout
<div class="max-w-md mx-auto p-6 bg-white rounded-lg shadow">
<h2 class="text-xl font-semibold mb-4">Title</h2>
<div class="flex gap-4">
<img src="avatar.jpg" class="w-12 h-12 rounded-full" />
<div>
<p class="font-medium">Name</p>
<p class="text-sm text-gray-500">Role</p>
</div>
</div>
<div class="mt-6 flex gap-2">
<button class="px-4 py-2 bg-blue-500 text-white rounded">Action</button>
</div>
</div>
Visual
The Spacing Scale Formula
┌──────────────────────────────────────────────────────────────┐
│ --spacing: 0.25rem (4px) │
│ │
│ p-1 = 1 × 0.25rem = 0.25rem = 4px │
│ p-2 = 2 × 0.25rem = 0.50rem = 8px │
│ p-4 = 4 × 0.25rem = 1.00rem = 16px │
│ p-6 = 6 × 0.25rem = 1.50rem = 24px │
│ p-8 = 8 × 0.25rem = 2.00rem = 32px │
│ p-12 = 12 × 0.25rem = 3.00rem = 48px │
│ p-16 = 16 × 0.25rem = 4.00rem = 64px │
│ │
│ In v4, any integer works: p-17, p-23, p-100 │
│ The scale is a formula, not a lookup table. │
└──────────────────────────────────────────────────────────────┘
Padding vs Margin vs Gap
┌──────────────────────────────────────────────────────────────┐
│ PADDING (inside) MARGIN (outside) │
│ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ ┌───────────────┐ │ │ │ │
│ │ │ │ │ │ ┌───────────────┐ │ │
│ │ │ CONTENT │ │ │ │ CONTENT │ │ │
│ │ │ │ │ │ └───────────────┘ │ │
│ │ └───────────────┘ │ │ │ │
│ │ padding │ │ margin │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
│ GAP (between children) │
│ ┌─────┐ gap ┌─────┐ gap ┌─────┐ │
│ │ A │◄─────►│ B │◄─────►│ C │ │
│ └─────┘ └─────┘ └─────┘ │
│ │
│ SPACE-Y (margin between stacked children) │
│ ┌─────────────────────┐ │
│ │ A │ │
│ └─────────────────────┘ │
│ ┌─────────────────────┐ ← margin-top on B │
│ │ B │ │
│ └─────────────────────┘ │
│ ┌─────────────────────┐ ← margin-top on C │
│ │ C │ │
│ └─────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
Directional Variants
┌──────────────────────────────────────────────────────────────┐
│ DIRECTIONAL PADDING AND MARGIN │
│ │
│ pt / mt │
│ ▲ │
│ │ │
│ pl / ml ◄───┼───► pr / mr │
│ │ │
│ ▼ │
│ pb / mb │
│ │
│ p-4 → all four sides │
│ px-4 → left and right (horizontal) │
│ py-4 → top and bottom (vertical) │
│ pt-4 → top only │
│ pr-4 → right only │
│ pb-4 → bottom only │
│ pl-4 → left only │
│ │
│ Logical: │
│ ps-4 → inline start (left in LTR, right in RTL) │
│ pe-4 → inline end (right in LTR, left in RTL) │
└──────────────────────────────────────────────────────────────┘
Gap vs Space-Between
┌──────────────────────────────────────────────────────────────┐
│ GAP SPACE-X │
│ │
│ <div class="flex gap-4"> <div class="flex space-x-4"> │
│ <div>A</div> <div>A</div> │
│ <div>B</div> <div>B</div> │
│ <div>C</div> <div>C</div> │
│ </div> </div> │
│ │
│ CSS: gap: 1rem CSS: margin-left: 1rem │
│ Applied to container on all but first child │
│ │
│ Pros: Pros: │
│ - No child selector - Works on any container │
│ - Handles wrapping - space-x-reverse for RTL │
│ - Preferred for flex/grid │
│ │
│ Cons: Cons: │
│ - Only flex/grid - Depends on child order │
│ - First-child edge cases │
└──────────────────────────────────────────────────────────────┘
Summary
| Item | Value |
|---|---|
| Base unit | --spacing: 0.25rem (4px) |
| Scale formula | class-value × var(--spacing) |
| Dynamic in v4 | Any integer works (p-17, m-23) |
| Padding | p-*, px-*, py-*, pt-*, pr-*, pb-*, pl-* |
| Margin | m-*, mx-*, my-*, mt-*, mr-*, mb-*, ml-* |
| Gap | gap-*, gap-x-*, gap-y-* |
| Space-between | space-x-*, space-y-* |
| Centering | mx-auto |
| Negative margins | -mt-4, -ml-2 |
| Logical properties | ps-*, pe-*, ms-*, me-* |
| Responsive | md:p-6, lg:gap-8 |
Key takeaways:
- The spacing scale is one formula, not a fixed list. Every numeric utility multiplies
--spacing(default0.25rem). In v4, any integer works dynamically. - Padding is inside; margin is outside. Padding separates content from its own border. Margin separates the element from siblings and parent.
- Gap is preferred for flex and grid. It applies uniformly between children without child-selector dependencies and handles wrapping correctly.
- Space-between uses margin on children.
space-y-4addsmargin-topto all but the first child. Useful for stacks and non-flex containers. - Directional variants target specific sides.
pxfor horizontal,pyfor vertical,pt/pr/pb/plfor individual sides. - Logical properties support RTL.
ps-4andpe-4map to left/right based on text direction, eliminating direction-specific overrides. - Negative margins pull elements.
-mt-4moves an element up by16px. Useful for overlaps and grid gap adjustments, but easy to overuse. - Responsive spacing scales with breakpoints.
p-4 md:p-6 lg:p-8increases padding as the viewport grows.
Remember: Tailwind’s spacing scale is a single number with directional variants. The number is a multiple of --spacing, and in v4 that multiple can be any integer. The variants determine which sides the value applies to. Padding pushes content inward; margin pushes siblings away; gap spaces flex and grid children; space-between spaces stacked children through margin. Choose gap over space-* when the container is flex or grid, use logical properties for internationalized layouts, and stick to a curated set of scale steps to keep spacing consistent. The scale is simple; the discipline is in using it deliberately rather than arbitrarily.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!