Chapter 6 of 14 · Tailwind CSS for Beginners — Complete Free Tutorial

Spacing: Margin and Padding

If typography is the voice of an interface, spacing is its breathing. This chapter of the Tailwind CSS for Beginners series covers the single scale behind every p-, m- and gap- class, how to apply padding and margin on one side at a time, when to centre with mx-auto, and why gap usually beats margin for spacing between children. The CSS underneath is the box model from The Box Model, unchanged.

One spacing scale for everything

Every spacing value is a multiple of one theme variable, --spacing, which defaults to 0.25rem (4px at the usual root size). The class number is simply the multiplier:

ClassCalculationResult
p-10.25rem × 14px — a tight gap
p-40.25rem × 41rem — comfortable padding
gap-60.25rem × 61.5rem — space between children
m-80.25rem × 82rem — separation between blocks
p-pxspecial caseExactly 1px

One pleasant v4 difference: the scale is generated dynamically, so p-13 and mt-17 exist and produce 3.25rem and 4.25rem. In v3 only the named steps worked and any other number fell back to nothing. Prefer the standard steps anyway — that is what keeps a design rhythmic.

The whole scale comes from one variable, so changing --spacing in your theme rescales padding, margin, gap and width steps together: set it to 1px for a pixel-precise dashboard, or 0.375rem for a roomier product, and every class follows without a rewrite.

Padding

Padding lives inside the element, so the background extends into it — which is exactly why cards look the way they do: a surface, a border, and room to breathe inside them. Use the four-sided form, the axis forms, or one side at a time:

<section class="bg-white p-6">
  <p class="px-4 py-2 bg-slate-100">Comfortable inside the row</p>
  <p class="pt-0 pb-0 ps-4 pe-4 bg-slate-100">Flush vertically, padded on the inline sides</p>
</section>

Expected output:

A white panel with even space around its contents. Inside, two grey
strips: the first has equal space above, below and at both ends; the
second touches top and bottom but keeps space at its left and right.

The ps- and pe- classes are logical properties — padding on the start and end of the line — so they flip automatically in right-to-left layouts, where pl- and pr- would not.

Margin, and the auto-centring trick

Margin sits outside the border and separates an element from its neighbours. Negative values are available with a leading minus, which is how you overlap elements:

<div class="w-64 mx-auto my-8 bg-indigo-50 p-6 rounded-xl">
  <h3 class="-mt-1 text-xl font-bold">Pulled up slightly</h3>
  <p class="mt-4 text-sm text-slate-600">Centred in its parent, with air above and below.</p>
</div>

Expected output:

A mid-width indigo-tinted panel centred horizontally on the page,
with generous space above and below. The heading sits slightly
closer to the top edge than normal, and the description has a clear
gap between it and the heading.

mx-auto only centres a box that has a width to centre — combine it with w-64, max-w-md or max-w-prose. For centring children inside a container, flexbox or grid utilities do the job instead, as you will see in Flexbox with Tailwind.

Spacing that changes with the screen

Spacing utilities accept breakpoint prefixes like any other, which is how a panel that is snug on a phone gains air on a desktop:

<section class="p-4 md:p-8 lg:p-12 space-y-4 md:space-y-6">
  <h2 class="text-2xl md:text-3xl font-bold">Quarterly numbers</h2>
  <p class="text-slate-600">Revenue is up across every region.</p>
</section>

Expected output:

On a narrow screen the section hugs its content with 16px padding
and modest gaps. Widen the window and the padding jumps to 32px,
then 48px, while the heading grows a step.

Negative margins and arbitrary values take prefixes too, so responsive spacing never needs a hand-written media query. The variant system behind md: is explained properly in Responsive Design with Breakpoints.

When to use gap instead of margin

SituationReach forWhy
Space between flex or grid childrengap-4No double edges, no first/last-child tricks
Breathing room inside a cardp-6The background fills the padding
Distance from a container edgem-6Margin belongs outside the border
Space above a heading inside a stackmt-* or gap on the parentEither works; one source of truth is better

Vertical margins between block siblings can still collapse in normal flow, while gap never does. A flex column with gap-6 is therefore the most predictable way to stack items: adding or removing a child cannot double a gap, and reordering children cannot change the rhythm. Reach for margins when you need space that depends on position — a larger gap above a heading, or nothing at all above the first item.

Common mistakes

  • Mixing padding with margin — wanting the parent's background to show between items means margin or gap, not padding.
  • Using mx-auto without a width — a full-width block is already as wide as its parent, so auto margins change nothing.
  • Spacing every child — space-y-4 styles all but the last child; a parent gap-4 is cleaner and survives reordering.
  • Odd one-off values — three instances of mt-[13px] mean your scale is missing a step, or your layout needs a token.
  • Ignoring logical sides — pl- breaks in right-to-left layouts where ps- keeps working.

Practice checklist

  1. Build a card with p-6 outer padding and gap-4 between its rows; then try gap-8.
  2. Centre a max-w-md box with mx-auto and confirm it does nothing until you give it a width.
  3. Add -mt-2 to a heading and inspect how it changes the optical alignment.
  4. Replace every margin you wrote between siblings with one gap on the parent.

Spacing shapes the boxes themselves, which is where sizing and the box model take over — Width, Height and the Box Model.

Quiz: Spacing: Margin and Padding

5 questions · 70% to pass

Frequently Asked Questions

Tailwind is a utility-first CSS framework: instead of writing custom classes like .card-title, you compose elements from small single-purpose utilities such as text-lg font-semibold text-slate-800. The styles ship as a generated stylesheet containing only the classes your project uses, so the CSS stays small and consistent.

Bootstrap ships a opinionated component layer (buttons, navbars with Bootstrap's own look) that you override with custom CSS. Tailwind ships primitive utilities and lets you design freely — two sites built with Tailwind can look completely different, while two Bootstrap sites tend to look related. You can still build components; you just compose them from utilities first.

You need the fundamentals: the box model, specificity, Flexbox, Grid, media queries and pseudo-classes. Tailwind does not replace CSS knowledge — it renames it. Understanding what padding, margin, gap and z-index mean makes every utility class obvious instead of something to memorise.

v4 is CSS-first: configuration lives in CSS with @import "tailwindcss" and @theme tokens instead of a JavaScript tailwind.config.js, the engine is rewritten in Rust for much faster builds, and modern CSS features (container queries, cascade layers) are built in. This tutorial teaches v4 and notes where v3 differed.

Long class lists are a real trade-off, and the tutorial covers two fixes: consistent ordering (layout → spacing → typography → colour) and small component classes for repeated combinations. The generated CSS contains only classes you actually use — Tailwind removes everything else at build time, so the stylesheet is typically smaller than an unused framework.

Three utilities cover most cases: mx-auto centres a fixed-width block horizontally, flex items-center justify-centre centres children inside a flex parent, and grid place-items-center does the same for grids. Chapter 8 and chapter 9 show both patterns with examples.

Yes — Tailwind is a build step that scans your template files for class names and generates CSS, so it works with any framework or none. It does not ship runtime JavaScript, and the classes look the same in JSX, Blade, PHP or static HTML files.

In v4 you define design tokens in CSS with @theme, for example --color-brand-500: #4f46e5; creates bg-brand-500, text-brand-500 and friends. For a one-off value you can always use arbitrary values like bg-[#0f172a], which need no configuration at all.

A variant prefixes a utility with the condition it applies under: hover:bg-indigo-600 on hover, focus:ring-2 while focused, dark:bg-slate-900 in dark mode, and sm: / md: / lg: at breakpoints. Variants stack, such as md:hover:text-lg, and chapter 11 covers the full pattern.

Yes. Tailwind compiles to a static stylesheet with no JavaScript requirement, and because it ships only used classes, pages stay fast — a Core Web Vitals win that helps SEO. Accessibility, semantic markup and good content remain your job; Tailwind only styles what you write.