TypeScript

Fix Tailwind v4 padding and margin not working

Prove that the utility exists but loses the CSS cascade, restore spacing with one layer change, and inspect the child margins behind space-x.

Mahdi Ben RhoumaMahdi Ben Rhouma
8 min read

TL;DR#

When Tailwind v4 generates your spacing classes but padding, margin and space-between still become zero, inspect the winning CSS rule. A normal reset outside every cascade layer overrides normal utilities inside Tailwind's utilities layer. Move that reset into @layer base. Reordering the same unlayered reset will not fix this conflict. Check the computed styles on the element and, for space-between, its children.

The Stack Overflow report uses the Tailwind v4 browser script and a navigation bar with mx-auto, p-6 and space-x-6. The reporter can recreate the desired spacing with ordinary CSS, but the utilities appear ineffective. Their stylesheet contains this reset:

css
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

There is no compiler error to fix in that example. The declarations can exist in the browser and still lose the cascade. The additional rules for the navigation and button in the question conceal the problem by setting spacing manually; they do not make the original utilities take precedence.

Why it happens#

Tailwind's Preflight documentation shows its layer order: theme, base, components, utilities. Importing Tailwind places Preflight in base and generated utilities in utilities. That gives normal utility declarations precedence over normal base declarations, so a reset can establish defaults without cancelling the classes added to an element.

A rule outside those layers occupies a different position. The CSS Cascade specification gives normal unlayered declarations precedence over normal declarations in explicit layers. This comparison happens before selector specificity. A universal selector can therefore override a class selector here, even though the universal selector has lower specificity. It can also win when its stylesheet appears earlier.

The reset touches two separate kinds of spacing. Padding and ordinary margins apply directly to an element. Tailwind's space-between utilities apply margins to children. The universal reset matches those children too, so the navigation's space-between disappears alongside its own padding. This is why changing only the padding class does not repair all the visible symptoms.

Preflight already resets default margins, padding and box sizing. If the custom reset merely duplicates that behaviour, removing it is another option. If it also contains defaults your application needs, put those defaults in the base layer rather than deleting the whole stylesheet.

One change, measured in Chromium#

Reproduced on 13 October 2026 with Tailwind CSS and its CLI 4.3.3, Chromium 153.0.8010.12, and Playwright 1.63.0 in the official Playwright Docker image. The browser loaded real CSS compiled by Tailwind. A probe had m-2 p-4, and a separate navigation had mx-auto p-6 w-64 with a flex space-x-6 row.

With the reset outside any layer, the browser reported zero spacing. Keeping the same declarations and wrapping only that reset in the base layer restored it:

text
unlayered-after: {"padding":"0px","margin":"0px","navPadding":"0px","navMargin":"0px","space":"0px","gap":"24px"}
base-layer-fix-only: {"padding":"16px","margin":"8px","navPadding":"24px","navMargin":"512px","space":"24px","gap":"24px"}

These measurements use the default spacing scale and root font size, a left-to-right document, and a viewport wide enough to leave room around the fixed-width navigation. They are evidence for that fixture, rather than pixel targets for every application theme.

Moving the unlayered reset before the generated CSS still produced zeros. A separate control placed ID selectors resetting the same elements inside base, after the generated CSS; the utilities still supplied the expected spacing. Those controls distinguish layer precedence from file order and selector specificity.

Fix#

  1. Confirm that the utility exists and is overridden. Inspect an affected element in the browser's developer tools. Find the padding or margin declaration from the utility, then follow the winning declaration to its stylesheet. Temporarily untick the reset's matching declaration. If spacing returns, the browser has supplied a concrete cause to repair. If the utility is absent, investigate CSS generation or stylesheet loading instead; wrapping an unrelated reset cannot generate a missing class.

    A build that stops before producing CSS requires a different fix. If it reports that Tailwind is being used directly as a PostCSS plugin, follow the Tailwind PostCSS plugin relocation fix first. The cascade diagnosis assumes that compiled styles reached the browser.

  2. Move the global reset into base. For a compiled Tailwind project, keep the existing Tailwind import and change the reset's placement. This is a complete minimal input stylesheet:

    css
    @import "tailwindcss";
     
    @layer base {
      * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
      }
    }

    Remove the old unlayered copy. Adding a layered copy while leaving the original active preserves the declaration that caused the failure. Include any existing pseudo-element reset selectors inside the same block when moving your actual stylesheet.

    The question uses the browser script rather than a compiled project. Keep that integration and wrap the reset in base in its stylesheet; do not add an npm package import to an ordinary browser stylesheet. Tailwind's Play CDN instructions use a style element with the text/tailwindcss type for custom CSS processed by the browser package. That integration is intended for development.

  3. Regenerate the stylesheet your page loads. Use your existing application's build process. For the isolated CLI fixture, save the input as fixed.css and rebuild it with the documented Tailwind CLI:

    bash
    npx @tailwindcss/cli -i fixed.css -o fixed.out.css

    The page must load that output. Changing the input while continuing to serve an older output does not change the browser's cascade. Check the loaded stylesheet in developer tools after rebuilding, including whether an old reset remains in another imported file.

Verify the fix#

Inspect the same element again. Its utility declaration should now win over the reset. Compare the computed padding and margins, rather than judging only whether the page looks different. For the navigation's horizontal spacing, inspect a non-final child link: the space-between rule sets its margin, so checking only the row's own margin misses the property being changed.

The reproduction's navigation also demonstrates a separate centring condition. Its width was constrained, leaving available horizontal space for automatic margins. If your navigation already fills its parent, successful automatic margins do not imply a visible gap on either side. Preserve the reset fix and inspect the element's width before treating an unchanged position as another cascade failure.

Editor completion is a separate signal. If the browser's utility now works but suggestions remain absent while typing, the Tailwind v4 IntelliSense diagnosis checks CSS entrypoint discovery and automatic suggestions inside strings. Missing editor suggestions do not establish that a browser declaration lost the cascade.

One email a month — the latest explained errors

What the site published that month — mostly Next.js, Supabase and Node errors, explained. You confirm by email; unsubscribe any time in one click.

When the reset is layered but spacing still disappears#

Check importance before increasing specificity. The reproduction also put an important margin and padding reset inside base; those declarations still forced the measurements to zero. Moving a reset into a layer does not make an important declaration become normal. Remove unnecessary importance from reset defaults and inspect any remaining deliberate important overrides separately. The normal-declaration ordering explained above does not describe conflicts between important declarations, whose layer ordering is reversed.

Component styles need their own placement decision. The question includes a button class and navigation-specific spacing rules outside any layer. If those are defaults that utility classes should override, Tailwind's custom styles documentation recommends the components layer. Moving only the universal reset cannot stop another unlayered component rule from winning the same property.

For a flex row, gap can be a useful layout choice. In the reproduction, gap-6 remained effective while the margin and padding reset broke space-between, because that reset did not set the gap property. Tailwind's upgrade guide describes the changed child selector in v4 and recommends flex or grid with gap for layouts affected by that change. Switching to gap still leaves incorrectly overridden padding and margins to repair.

If a shadcn stylesheet subsequently fails with Cannot apply unknown utility class border-border, continue with the border-border theme configuration fix. That page checks how Tailwind receives the custom border colour. For the spacing failure here, keep the diagnosis attached to the winning browser declaration: generated utilities regain control when reset defaults occupy the intended layer.

Further reading: Fix Tailwind v4: dark class changes no background colour. Also see Tailwind v4 @source inline(): replace the v3 safelist. Also see Tailwind @apply not working in Storybook: add postcss-loader. Also see Custom font is not working in Tailwind CSS: fix @font-face.

Frequently Asked Questions

|

Have more questions? Contact us

Still stuck? Paste your error.

Paste the error message or stack trace — we check it against every fix and tool on the site.

Matching happens in your browser. When you search, a cleaned error signature is sent so we can spot errors we do not cover yet — never the raw text, your IP address or your e-mail. Do not paste passwords or keys. Details

Written by

Mahdi Ben Rhouma
Mahdi Ben Rhouma

Full-Stack Dev — Next.js & Supabase

Solo developer building SaaS products with Next.js and Supabase. Writing about production patterns the official docs skip.

Remote