Custom Styles and Arbitrary Values

This section documents Tailwind CSS v4.x — the CSS-first configuration line, whose v4.0 release shipped in January 2025 — as published at the official Tailwind CSS documentation, which is the reference these pages are written and verified against. No specific patch version is pinned.

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, since Tailwind iterates quickly.

This section’s bibliography lists the reference material consulted while preparing these pages.

When no built-in utility fits, Tailwind gives you graduated escape hatches — from a one-off value in square brackets, through your own reusable @utility, to plain CSS in a @layer. See Adding Custom Styles.

Arbitrary values

Put any CSS value in square brackets and Tailwind generates the utility on demand. Use for spaces (it is converted to a space; keep literal underscores in url() and escape one you need as \).

<div class="top-[117px] lg:top-[344px]"></div>
<div class="bg-[#bada55] text-[22px]"></div>
<div class="grid grid-cols-[1fr_500px_2fr]"></div>
<div class="max-h-[calc(100dvh-4rem)]"></div>
<span class="before:content-['Hello_world']"></span>

Arbitrary properties and variants

<!-- a property with no utility at all -->
<div class="[mask-type:luminance] hover:[mask-type:alpha]"></div>

<!-- set a CSS variable inline, responsively -->
<div class="[--gutter:1rem] lg:[--gutter:2rem]"></div>

<!-- a selector Tailwind has no variant for -->
<div class="[&_p]:mt-4 [&.is-open]:block [&::-webkit-scrollbar]:hidden
            [@supports(display:grid)]:grid"></div>

The CSS-variable shorthand

For values that are genuinely dynamic (a colour from a CMS, a user setting), set a CSS variable with an inline style and reference it with the (--var) shorthand — shorter than [var(--var)]:

<button style="--btn: #7c3aed; --btn-hover: #6d28d9"
        class="bg-(--btn) hover:bg-(--btn-hover) text-white px-4 py-2 rounded">
  Themed button
</button>

When the utility could take more than one CSS data type, add a hint:

<p class="text-(length:--fluid-size)">font-size from a variable</p>
<p class="text-(color:--brand)">colour from a variable</p>

Custom utilities with @utility

@utility registers a class that works with every variant (hover:, md:, dark:) — the v4 replacement for a v3 @layer utilities block.

@import "tailwindcss";

/* static utility */
@utility content-auto { content-visibility: auto; }

/* nested selectors */
@utility scrollbar-none {
  &::-webkit-scrollbar { display: none; }
  scrollbar-width: none;
}

/* functional utility: `tab-*` accepts a number, a named value, or a bare integer */
@theme { --tab-size-github: 8; }

@utility tab-* {
  tab-size: --value(--tab-size-*, integer, [integer]);
}
<pre class="tab-4 md:tab-github">&#8230;</pre>

--value() resolves the part after the dash; --modifier() resolves a / modifier; wrap a fallback with --value(integer, --default(4)). See Functional utilities.

Custom variants

@import "tailwindcss";

/* selector form */
@custom-variant theme-midnight (&:where([data-theme="midnight"] *));

/* at-rule form */
@custom-variant pointer-coarse (@media (pointer: coarse));
/* apply a Tailwind variant inside your own rule */
.panel {
  background: white;
  @variant dark { background: #0f172a; }
  @variant hover, focus { background: #f1f5f9; }
}

@apply and @reference

@apply inlines existing utilities into a custom rule. Reach for it sparingly — mainly to style third-party markup you cannot add classes to; prefer a framework component for your own repeated patterns.

@layer components {
  .select2-dropdown { @apply rounded-b-md border border-gray-200 shadow-md; }
}

In a scoped stylesheet that is compiled separately (a Vue / Svelte <style> block, CSS Modules), the theme and utilities are not in scope, so @apply and @variant fail. Pull them in with @reference — it imports the definitions without duplicating any CSS into that file:

/* Component.vue <style> */
@reference "../app.css";

h1 { @apply text-2xl font-bold text-sky-600; }