built-in scale → arbitrary value: the escape hatch
Tailwind ships a curated scale: w-4 = 1rem, p-8 = 2rem,
text-cyan-500 = a specific oklch. But design specs aren't always on
the scale — a Figma frame is 17rem wide, a brand
color is #1da1f2, a grid is
1fr 2fr 1fr. Arbitrary values let you write the
exact CSS value inline — no new utility, no @theme entry, no plugin.
The JIT compiler reads the brackets and emits one rule.
| syntax | what it does | example | compiles to |
|---|---|---|---|
[value] |
one-shot arbitrary value | w-[17rem] |
width: 17rem |
[type:value] |
type hint — disambiguates the compiler | [color:#fff] · [length:300px] |
color: #fff · width: 300px |
| underscore → space | JIT converts _ inside [] to a space |
grid-cols-[1fr_2fr_1fr] |
grid-template-columns: 1fr 2fr 1fr |
| escaped underscore | \_ keeps a literal underscore |
bg-[length:18px\_18px] |
background-size: 18px 18px |
| CSS variable | reference a token defined in @theme or :root |
bg-[var(--color-brand)] |
background-color: var(--color-brand) |
| URL | background-image from a path | bg-[url('/hero.jpg')] |
background-image: url('/hero.jpg') |
1 · arbitrary width — w-[Nrem] computes to N × 16px
Drag the slider. The box below uses w-[17rem]
— an arbitrary rem value. 1rem = 16px (browser default), so
w-[17rem] must compute to 272px. The gold-check pins exactly
this fact via getComputedStyle().
computed width: —
2 · arbitrary colors — hex, rgb(), and var() bridges
Brand colors rarely sit on Tailwind's palette. Arbitrary values accept any CSS
color syntax — #hex, rgb(), hsl(),
oklch(), or var(--token). The right card pulls its
color from the @theme token --color-brand — the same
token a bg-brand utility would use, proving arbitrary values and
@theme are interoperable, not competing.
hex
bg-[#1da1f2]
Twitter blue, off the Tailwind scale.
rgb()
bg-[rgb(44,46,51)]
Full rgb() syntax, no alpha shorthand.
var() → @theme
bg-[var(--color-brand)]
Same token as bg-brand — interoperable.
Type hint: when the value is ambiguous (e.g. a CSS variable that could be
a color or a length), prefix with [color:var(--x)] or
[length:var(--x)] so the JIT picks the right CSS property.
3 · arbitrary grid — underscores become spaces
Multi-value CSS properties (grid-template-columns,
transform, box-shadow) need spaces. Class names can't
contain spaces, so inside [] the JIT treats _ as a
space: grid-cols-[1fr_2fr_1fr] →
grid-template-columns: 1fr 2fr 1fr.
Escaped underscore: to keep a real _ (e.g. in a filename or
background-size), write \_:
bg-[length:18px\_18px] → background-size: 18px 18px
(here the _ became a space, the \_ would stay literal).
4 · arbitrary URL — bg-[url('...')] background images
Background images inline: bg-[url('...')]. Pair with
bg-cover, bg-center, and an overlay. The URL must be
quoted (single quotes inside the brackets) so the JIT doesn't choke on spaces
or query strings. Below uses an inline SVG data-URI so the demo is self-contained.
Production note: for real images, prefer bg-[url('/hero.jpg')]
with a path from your public/ dir. The JIT emits
background-image: url('/hero.jpg') verbatim.
5 · live playground — type a value, watch it compile
Type any arbitrary value below. The class is applied live and the computed
style is read back — proving the JIT compiled your bracket on the fly. Try
#e74c3c, oklch(0.7 0.2 145), or
var(--color-accent2).
computed background-color: —
intent → pattern
| intent | pattern | why |
|---|---|---|
| off-scale length | w-[17rem] · p-[13px] · gap-[0.75rem] |
exact value from a spec, no need to extend the theme for a one-off |
| brand color off the palette | bg-[#1da1f2] · text-[rgb(44,46,51)] |
any CSS color syntax inline |
| ambiguous value → force property | border-[color:var(--brand)] · w-[length:var(--w)] |
type hint tells JIT which property to emit |
| multi-value property | grid-cols-[1fr_2fr_1fr] · shadow-[0_4px_12px_rgba(0,0,0,.5)] |
underscores inside [] become spaces |
| literal underscore in value | bg-[length:18px\_18px] |
\_ keeps the underscore (background-size, filenames) |
| reuse a design token inline | bg-[var(--color-brand)] · w-[var(--card-width)] |
bridge to @theme — token stays the single source of truth |
| background image | bg-[url('/hero.jpg')] bg-cover bg-center |
emit background-image: url(...) without a custom utility |
| z-index, content, anything | z-[9999] · content-['→'] · rotate-[17deg] |
any utility that takes a value accepts arbitrary brackets |