Margin and Padding
Purpose and Scope
Spacing utilities are the Tailwind CSS classes used to express the distance around and inside elements. Margin controls space outside a box, padding controls space inside a box, and related scroll-padding utilities control the snap offset inside scroll containers. In Tailwind CSS v4, the standard numeric spacing scale is expressed through the CSS variable --spacing, so classes like m-4, px-6, or scroll-pt-12 compile to calculations based on that design token. Arbitrary values, custom properties, pixel shortcuts, and logical-direction variants let the same API cover fixed layouts, internationalized layouts, and component-level overrides.
The source files for this page are the public entry points that make spacing utilities available across the supported runtime paths. The core tailwindcss package exposes the compiler and CSS entry files; the browser package creates an in-page compiler for Play CDN-style usage; the CLI routes command-line builds to the build command; and the Node package re-exports compile, optimization, source-map, and instrumentation helpers for integration packages. The utility definitions themselves are consumed through the compiler pipeline, so application authors usually interact with spacing through class candidates in markup and CSS imports rather than through a separate spacing-specific JavaScript API.
Sources: packages/tailwindcss/src/index.ts, packages/tailwindcss/package.json, package.json, packages/@tailwindcss-browser/src/index.ts, packages/@tailwindcss-cli/src/index.ts, packages/@tailwindcss-node/src/index.ts
Relevant Source Files
packages/tailwindcss/src/index.ts- Core package entry point for parsing CSS, processing Tailwind directives, building the design system, compiling class candidates, and returning compiler results used by integrations.packages/tailwindcss/package.json- Declares thetailwindcsspackage metadata, export map, CSS entry files such asindex.css,theme.css, andutilities.css, and build/test scripts for the package.package.json- Defines the monorepo-level scripts that build, test, lint, and run playground workflows, which is useful when validating spacing output across packages.packages/@tailwindcss-browser/src/index.ts- Browser runtime entry point that creates a Tailwind compiler in the page, injects a default@import "tailwindcss"when needed, tracks discovered classes, and rebuilds generated CSS.packages/@tailwindcss-cli/src/index.ts- CLI entry point that parsestailwindcss,tailwindcss build, andtailwindcss canonicalizecommands before delegating to the build or canonicalization command handlers.packages/@tailwindcss-node/src/index.ts- Node integration entry point that re-exports compile, optimization, source-map, normalization, instrumentation, and environment helpers, and registers ESM cache hooks when available.
Core Concepts
A Tailwind spacing class has two parts: a property prefix and a value suffix. The prefix selects which CSS property is emitted, while the suffix chooses the value. For margin, m-* targets all sides, mx-* and my-* target logical inline and block axes, ms-* and me-* target logical inline start and end, and physical classes like mt-*, mr-*, mb-*, and ml-* target top, right, bottom, and left. Padding follows the same shape with p-*, px-*, py-*, ps-*, pe-*, pt-*, pr-*, pb-*, and pl-*, but padding does not support auto or negative values because those are not meaningful padding values in CSS.
The official v4 spacing scale is token-driven. A class like p-4 maps to padding: calc(var(--spacing) * 4), while mx-2 maps to margin-inline: calc(var(--spacing) * 2). The px suffix is a special literal shortcut, so m-px and p-px produce 1px. Custom-property forms such as m-(--card-gap) and arbitrary-value forms such as p-[clamp(1rem,2vw,2rem)] allow codebases to keep a utility-first workflow when a value is not part of the shared scale. Negative margin classes use a leading dash, for example -mt-4 or -mx-px; equivalent negative padding classes are not part of the padding API.
Logical direction matters for modern layout systems. Classes like ms-4, me-4, ps-4, and pe-4 compile to inline-start and inline-end properties rather than hard-coded left and right properties. That makes them adapt to writing mode and text direction. Block-axis classes such as mbs-*, mbe-*, pbs-*, and pbe-* provide the same idea for block start and block end. Prefer logical utilities for reusable components, design-system primitives, and internationalized interfaces; use physical utilities when a layout intentionally depends on top, right, bottom, or left regardless of writing direction.
Utility Reference
| Family | Examples | CSS target | Value support |
|---|---|---|---|
| Margin all sides | m-4, -m-4, m-auto, m-px, m-[2rem] | margin | scale, negative scale, auto, 1px, custom property, arbitrary value |
| Margin inline/block axes | mx-6, my-2, -mx-px, mx-auto | margin-inline, margin-block | scale, negative scale, auto, 1px, custom property, arbitrary value |
| Margin logical edges | ms-4, me-4, mbs-2, mbe-2 | logical margin start/end properties | scale, negative scale, auto, 1px, custom property, arbitrary value |
| Margin physical edges | mt-4, mr-4, mb-4, ml-4 | physical margin properties | scale, negative scale, auto, 1px, custom property, arbitrary value |
| Padding all sides | p-4, p-px, p-[3ch] | padding | scale, 1px, custom property, arbitrary value |
| Padding inline/block axes | px-6, py-3 | padding-inline, padding-block | scale, 1px, custom property, arbitrary value |
| Padding logical edges | ps-4, pe-4, pbs-2, pbe-2 | logical padding start/end properties | scale, 1px, custom property, arbitrary value |
| Padding physical edges | pt-4, pr-4, pb-4, pl-4 | physical padding properties | scale, 1px, custom property, arbitrary value |
| Scroll padding | scroll-p-4, scroll-px-8, scroll-pt-16 | scroll-padding properties | scale, negative scale, custom property, arbitrary value |
Use the broadest utility that matches the design intent, then narrow it only when needed. A card component often starts with p-6 because all sides share the same inset. A horizontally padded page shell might use px-4 sm:px-6 lg:px-8 so vertical rhythm remains independent. An element that must visually overlap a neighbor may use negative margin such as -mt-2, but that should be a deliberate layout choice because negative margins affect surrounding flow. Scroll-padding utilities belong to snap-container and anchor-offset workflows, not ordinary element spacing, even though they share the same token scale.
<section class="mx-auto max-w-3xl px-4 py-10">
<article class="rounded-lg p-6 shadow-sm">
<h2 class="mb-3 text-xl font-semibold">Spacing with tokens</h2>
<p class="-mt-1 ps-4 text-sm">
Logical padding and margin utilities adapt better to direction-aware layouts.
</p>
</article>
</section>System-to-Code Mapping
The core package is responsible for turning class candidates such as p-6, mt-4, or scroll-px-8 into generated CSS during compilation. Its entry file imports the CSS parser, AST utilities, theme implementation, design-system builder, variant engine, and candidate compiler. The exported compile path parses input CSS, substitutes imports and functions, applies compatibility hooks, processes directives such as @theme and @tailwind utilities, and then builds the CSS for the classes requested by the calling integration. Spacing is therefore not a standalone runtime feature; it is part of the same class-candidate compilation model as color, typography, layout, and state variants.
Sources: packages/tailwindcss/src/index.ts, packages/tailwindcss/package.json
The tailwindcss package manifest explains why spacing utilities are available in several installation styles. The package export map exposes the main library entry, the bundled stylesheet entry, and direct CSS files such as index.css, preflight.css, theme.css, and utilities.css. That means a project can import tailwindcss as CSS for the default layers, while integrations can import the compiler entry to build only the utilities required by discovered class candidates. The manifest also keeps compatibility exports like ./plugin, ./defaultTheme, ./colors, and ./lib/util/flattenColorPalette, which matters for applications migrating custom plugins that may emit spacing-related utilities.
Sources: packages/tailwindcss/package.json
Runtime packages call into that same core rather than redefining spacing behavior. The browser runtime imports tailwindcss, gathers <style type="text/tailwindcss"> blocks, injects @import "tailwindcss" when the page has not provided imports, creates a compiler with browser-specific stylesheet and module loaders, and tracks the set of classes seen on the page so it can pass new classes to build(...). The CLI entry point parses user intent and delegates to build handling or candidate canonicalization. The Node package re-exports compile and optimization helpers and installs module-resolution hooks where supported. These paths should produce the same spacing CSS for the same input candidates.
Sources: packages/@tailwindcss-browser/src/index.ts, packages/@tailwindcss-cli/src/index.ts, packages/@tailwindcss-node/src/index.ts
Build and Validation Flow
For an application build, spacing classes begin as text in source files or as utility usage in CSS features such as @apply. The integration creates or reuses a Tailwind compiler, discovers class candidates, and asks the compiler to build the necessary output. Numeric spacing classes resolve against --spacing, so changing the theme token changes the entire spacing scale consistently. Because the repository root scripts run formatting, TypeScript linting, package builds, Rust tests, Vitest tests, integration tests, and UI tests through workspace commands, contributors can validate that compiler and integration changes do not unintentionally alter spacing behavior in one entry path while preserving it in another.
Sources: package.json
A simple local check is to place spacing classes in markup, import Tailwind, and run the build path used by the project. CLI users can run the tailwindcss command with an input and output file; Vite, PostCSS, Webpack, and Node-based integrations call into the same package-level compiler through their respective adapters. Browser runtime users can add a Tailwind style block and rely on the in-page compiler. If a class uses an arbitrary value or custom property, verify that the generated declaration is valid CSS and that the value is intentional enough to justify not using the shared --spacing scale.
@import "tailwindcss";
@theme {
--spacing: 0.25rem;
}<div class="mx-auto mt-8 max-w-xl p-6">
<button class="px-4 py-2">Save changes</button>
</div>Practical Guidance
Prefer scale-based spacing utilities for ordinary component work because they keep rhythm consistent and make global theme adjustments predictable. Use arbitrary values when the spacing is tied to a browser feature, container query, external asset, or one-off calculation that does not belong in the shared scale. Use custom-property forms when the value is dynamic but named, such as p-(--dialog-padding) or scroll-mt-(--header-height) in a component system. Use auto margins for distribution and centering patterns, not as a substitute for padding; padding always reserves internal space, while auto margin participates in layout negotiation outside the element.
When combining spacing with variants, think of spacing as the declaration and variants as the condition. Responsive classes like md:px-8, state classes like hover:-translate-y-1 combined with mt-*, and direction-aware logical utilities can all coexist because Tailwind composes variants around compiled utility candidates. The safest workflow is to choose semantic layout intent first: external separation with margin, internal inset with padding, scroll snap offset with scroll padding, and container width or flex/grid gap utilities when the spacing belongs to a layout model instead of an individual box. From here, read the Theme page for token customization and the Scroll and Snap Utilities page for scroll-specific spacing behavior.