Arbitrary values and properties

Tailwind CSS · Advanced · 10 min

Real designs always have a few one-off values, and this is how you handle them without leaving the markup.

When the scale doesn't have what you need, put any CSS value in square brackets:

  • w-[37px], top-[117px], bg-[#bada55], grid-cols-[200px_1fr_auto].
  • Spaces are written as underscores (class names can't contain spaces): grid-rows-[auto_1fr_auto]. Write \_ for a real underscore.
  • CSS functions work: w-[calc(100%-2rem)], h-[min(50vh,30rem)].

CSS variables have a shorthand with parentheses: bg-(--brand-color) compiles to background-color: var(--brand-color). (In v3 this was written bg-[--brand-color].) That's the clean way to pass dynamic values from JavaScript: set style="--progress: 40%" on the element and use w-(--progress).

When a value is ambiguous, add a type hint: text-(length:--size) is a font size, while text-(color:--accent) is a colour.

Arbitrary properties apply any CSS declaration as a class, with variants still available: [mask-type:luminance], hover:[mask-type:alpha].

Arbitrary variants build a selector on the fly: [&>*]:p-4 styles all direct children, [&:nth-child(3)]:underline, and data-[state=open]:rotate-180.

Use these sparingly. If the same arbitrary value appears in several places, it belongs in @theme as a token. And class names must be complete strings in the source; you can't build w-[${n}px] at runtime.

Example

<!-- one-off values -->
<div class="top-[117px] grid grid-cols-[220px_1fr] bg-[#0b1020]">...</div>

<!-- dynamic value from JS through a CSS variable -->
<div class="h-2 w-full rounded bg-gray-200">
  <div class="h-2 w-(--progress) rounded bg-emerald-500" style="--progress: 40%"></div>
</div>

<!-- arbitrary property and arbitrary variant -->
<img class="[mask-image:linear-gradient(black,transparent)]" src="/hero.jpg" alt="">
<ul class="[&>li]:py-2 [&>li:not(:last-child)]:border-b">
  <li>One</li><li>Two</li>
</ul>

<button data-state="open" class="transition data-[state=open]:rotate-180">▾</button>

Remember

  • Square brackets take any value; underscores stand for spaces
  • bg-(--var) is shorthand for var(--var)
  • Arbitrary properties [prop:value] and variants [&>li]: work with modifiers
  • Repeated one-offs belong in @theme

Watch out for

  • Building class names dynamically, like w-[${n}px], which the scanner can't see.

Check yourself

  1. How do you write grid-template-columns: 1fr 300px as a Tailwind class?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: tailwindcss.com/docs/adding-custom-styles#using-arbitrary-values