Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tw-spacing-semantics-plugin

A production-ready Tailwind CSS v4 plugin that adds a semantic spacing layer — p-md, gap-xl, mx-2xl, top-lg — built on an isolated --space-* custom property system that never touches Tailwind's own spacing scale.


Why this exists

Tailwind's built-in spacing utilities use numeric keys: p-4, gap-8, mt-12. These are structural primitives tied to the raw --spacing unit. They work great for low-level layout work, but design systems benefit from named, semantic tokens: is this the "comfortable" padding or the "tight" padding?

Also, changing --spacing-xl, for example, will modify classes that already have semantic variants such as max-w-xl, forcing you to create your custom spacings with another prefix like max-w-s-xl.

This plugin adds that semantic layer without touching Tailwind's internals. Utilities like max-w-xl, w-4, h-screen, and gap-8 continue working exactly as Tailwind intended.

The default token scale is based on the concepts of Refactoring UI by Adam Wathan & Steve Schoger. Yes, the Tailwind creators!.


Features

  • Fully isolated --space-* namespace — zero interference with Tailwind internals
  • Generates only p-*, m-*, -m-*, top-*/right-*/bottom-*/left-*, gap-*, space-x-*/space-y-*, their negative variants and logical (ms-*, pe-*, mbs-*, …) utilities
  • Two-level customization: global scale factor + individual token override
  • Native Tailwind v4 responsive variants (sm:px-xl, md:gap-2xl)
  • CSS-first, ESM, npm-publishable
  • JIT tree-shakable — only used utilities appear in output
  • Zero Tailwind internals mutated

Installation

pnpm add tw-spacing-semantics-plugin

Setup

In your Tailwind v4 CSS entry file:

@import 'tailwindcss';
@import 'tw-spacing-semantics-plugin';

That's it. All semantic utilities are now available.


Default token reference

At Tailwind's default --spacing: 0.25rem:

Token Multiplier Value (rem) Value (px)
none 0 0px
3xs × 0.5 0.125rem 2px
2xs × 1 0.25rem 4px
xs × 2 0.5rem 8px
sm × 3 0.75rem 12px
md × 4 1rem 16px
lg × 6 1.5rem 24px
xl × 8 2rem 32px
2xl × 12 3rem 48px
3xl × 16 4rem 64px
4xl × 24 6rem 96px
5xl × 32 8rem 128px
6xl × 48 12rem 192px
7xl × 64 16rem 256px
8xl × 96 24rem 384px
9xl × 128 32rem 512px
10xl × 192 48rem 768px
11xl × 256 64rem 1024px

Generated utilities

Every token is available across spacing axes.

Padding

Classes generated
p-{t} px-{t} py-{t} pt-{t} pr-{t} pb-{t} pl-{t}
ps-{t} pe-{t} pbs-{t} pbe-{t} (logical)

Padding does NOT support negative values.


Margin and negative margin

Classes generated
m-{t} mx-{t} my-{t} mt-{t} mr-{t} mb-{t} ml-{t} ms-{t} me-{t} mbs-{t} mbe-{t}
-m-{t} -mx-{t} -my-{t} -mt-{t} -mr-{t} -mb-{t} -ml-{t}
-ms-{t} -me-{t} -mbs-{t} -mbe-{t} (logical)

Logical margins (ms/me/mbs/mbe) follow the writing direction of the document, so they flip automatically in RTL layouts. Their negative variants are also supported.


Gap

Classes generated
gap-{t} gap-x-{t} gap-y-{t}

Gap does NOT support negative values in CSS.


Space between children

Classes generated
space-x-{t} space-y-{t}
-space-x-{t} -space-y-{t}

Applies the semantic token as spacing between sibling elements (margin-based, like Tailwind's native space-x-*/space-y-*). Negative variants collapse the space between siblings.


Inset (positioning)

Classes generated
inset-{t} inset-x-{t} inset-y-{t}
-inset-{t} -inset-x-{t} -inset-y-{t}
top-{t} right-{t} bottom-{t} left-{t}
-top-{t} -right-{t} -bottom-{t} -left-{t}

Only the classes you actually used will appear in the final CSS.


Usage

<!-- Semantic padding -->
<article class="p-md"></article>

<!-- Responsive semantic padding -->
<section class="px-sm sm:px-md lg:px-xl"></section>

<!-- Semantic gap in a grid -->
<div class="grid grid-cols-3 gap-lg"></div>

<!-- Responsive gap -->
<div class="flex flex-col gap-sm md:gap-lg"></div>

<!-- Margin -->
<div class="mt-md mb-lg"></div>

<!-- Negative margin -->
<div class="-mt-md -mb-lg"></div>

<!-- Horizontal negative margin -->
<div class="-mx-xl"></div>

<!-- Semantic inset positioning -->
<div class="top-md left-lg"></div>

<!-- Inset shorthand -->
<div class="inset-lg inset-x-md inset-y-sm"></div>

<!-- Negative inset -->
<div class="-top-sm -right-md -inset-x-xl"></div>

<!-- Responsive inset -->
<div class="top-sm md:top-lg xl:top-2xl"></div>

<!-- Mixed layout: Tailwind structural + semantic spacing -->
<div class="max-w-xl mx-auto px-md py-lg">
	<!-- max-w-xl → max-width: var(--container-xl) -->
	<!-- px-md    → padding-inline: var(--space-md) -->
</div>

<!-- Logical padding (flips in RTL) -->
<div class="ps-md pe-lg"></div>

<!-- Logical margin -->
<div class="ms-auto me-md"></div>

<!-- Spacing between children -->
<ul class="space-y-md">
	<li></li>
	<li></li>
</ul>
<div class="flex space-x-lg">
	<button></button>
	<button></button>
</div>

Customization

By changing --spacing

If you have a custom --spacing theme, the plugin will automatically adapt the utilities to use your custom spacing.

@import 'tailwindcss';
@import 'tw-spacing-semantics-plugin';

@theme {
	--spacing: 4rem;
}

Individual token overrides

Pin a specific token to an exact value.

@theme {
	--space-md: 1.5rem; /* always 24px, regardless of --spacing */
	--space-xl: 2.75rem; /* always 44px, regardless of --spacing */
}

Add new tokens

If you need more tokens you can add them.

@theme {
	--space-4xs: calc(var(--spacing) * 0.25)
	--space-12xl: calc(var(--spacing) * 512)
}
```

## Responsive variants

All semantic utilities participate in Tailwind v4's full variant system with no extra configuration:

```html
<!-- Responsive -->
<div class="py-sm md:py-lg xl:py-2xl">…</div>
<div class="gap-md lg:gap-xl">…</div>

<!-- State-based -->
<button class="px-md hover:px-lg transition-all">…</button>

<!-- Combined -->
<section class="p-sm sm:p-md lg:p-xl dark:p-lg">…</section>
```

---

## License

MIT