@csszyx/mcp-server 0.9.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/llms-full.txt ADDED
@@ -0,0 +1,3701 @@
1
+ # CSSzyx
2
+
3
+ > Object-syntax Tailwind CSS. Type-safe. Zero runtime. SSR-safe.
4
+
5
+ CSSzyx is a build-time CSS framework that transforms JSX `sz` props into Tailwind v4 utility classes. The compiler runs at build time — no runtime overhead in the browser.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install csszyx
11
+ ```
12
+
13
+ ### Vite
14
+
15
+ ```js
16
+ // vite.config.ts
17
+ import csszyx from "csszyx/vite";
18
+ import tailwindcss from "@tailwindcss/vite";
19
+
20
+ export default defineConfig({
21
+ plugins: [
22
+ ...csszyx(), // csszyx MUST come before tailwindcss
23
+ tailwindcss(),
24
+ ],
25
+ });
26
+ ```
27
+
28
+ ### Next.js (Webpack)
29
+
30
+ ```js
31
+ // next.config.js
32
+ const csszyxWebpack = require("@csszyx/unplugin/webpack").default;
33
+
34
+ module.exports = {
35
+ webpack(config) {
36
+ config.plugins.unshift(...csszyxWebpack());
37
+ return config;
38
+ },
39
+ };
40
+ ```
41
+
42
+ ## Core Syntax
43
+
44
+ ### Basic usage
45
+
46
+ ```tsx
47
+ // Before (Tailwind)
48
+ <div className="flex items-center p-4 bg-blue-500 rounded-lg" />
49
+
50
+ // After (CSSzyx)
51
+ <div sz={{ flex: true, items: 'center', p: 4, bg: 'blue-500', rounded: 'lg' }} />
52
+ ```
53
+
54
+ The compiler transforms `sz` props → Tailwind classes at build time. The browser never sees `sz`.
55
+
56
+ ### Boolean shorthand
57
+
58
+ Many display/position properties accept `true`:
59
+
60
+ ```tsx
61
+ <div sz={{ flex: true, relative: true, hidden: true }} />
62
+ // → className="flex relative hidden"
63
+ ```
64
+
65
+ ### Arbitrary values
66
+
67
+ ```tsx
68
+ <div sz={{ w: "333px", top: "-1px", bg: "#316ff6" }} />
69
+ // → className="w-[333px] top-[-1px] bg-[#316ff6]"
70
+ // Note: compiler auto-wraps in [] — no need to add them yourself
71
+ ```
72
+
73
+ ### CSS variables
74
+
75
+ ```tsx
76
+ <div sz={{ color: "--ds-primary", p: "--spacing-4" }} />
77
+ // → className="text-(--ds-primary) p-(--spacing-4)"
78
+ // Sugar: any value starting with -- is auto-wrapped in ()
79
+ ```
80
+
81
+ ### Color with opacity
82
+
83
+ ```tsx
84
+ <div sz={{ bg: { color: 'blue-500', op: 50 } }} />
85
+ // → className="bg-blue-500/50"
86
+
87
+ // Hex/rgb/hsl values are auto-wrapped in brackets
88
+ <div sz={{ bg: { color: '#0d0d12', op: 90 } }} />
89
+ // → className="bg-[#0d0d12]/90"
90
+
91
+ // Sub-half-step decimals use arbitrary brackets
92
+ <div sz={{ bg: { color: 'black', op: 0.05 } }} />
93
+ // → className="bg-black/[0.05]"
94
+ ```
95
+
96
+ ## Variants
97
+
98
+ Variants are nested objects:
99
+
100
+ ```tsx
101
+ <div
102
+ sz={{
103
+ bg: "white",
104
+ hover: { bg: "blue-100" },
105
+ dark: { bg: "gray-800" },
106
+ md: { p: 8 },
107
+ focus: { outline: "none", ring: 2 },
108
+ }}
109
+ />
110
+ ```
111
+
112
+ ### Responsive
113
+
114
+ ```tsx
115
+ sz={{ w: 'full', md: { w: '1/2' }, lg: { w: '1/3' } }}
116
+ // → className="w-full md:w-1/2 lg:w-1/3"
117
+ ```
118
+
119
+ ### State modifiers
120
+
121
+ ```tsx
122
+ sz={{
123
+ hover: { bg: 'sky-700' },
124
+ focus: { outline: 'none' },
125
+ active: { opacity: 80 },
126
+ disabled: { opacity: 50 },
127
+ focusVisible: { ring: 2 },
128
+ }}
129
+ ```
130
+
131
+ ### Dark mode
132
+
133
+ ```tsx
134
+ sz={{ bg: 'white', dark: { bg: 'gray-900' } }}
135
+ ```
136
+
137
+ ### Group / Peer
138
+
139
+ ```tsx
140
+ sz={{ group: { hover: { color: 'white' } } }}
141
+ // → className="group-hover:text-white"
142
+
143
+ sz={{ peer: { checked: { bg: 'blue-500' } } }}
144
+ // → className="peer-checked:bg-blue-500"
145
+ ```
146
+
147
+ ### Group Data / ARIA (parent data-_and aria-_ attributes)
148
+
149
+ ```tsx
150
+ // group-data: style children based on data-* attr on group parent
151
+ sz={{ group: { data: { active: { color: 'blue-600' } } } }}
152
+ // → className="group-data-[active]:text-blue-600"
153
+
154
+ sz={{ group: { data: { 'state=open': { bg: 'green-50' } } } }}
155
+ // → className="group-data-[state=open]:bg-green-50"
156
+
157
+ // named group + data
158
+ sz={{ group: { card: { data: { active: { color: 'blue-600' } } } } }}
159
+ // → className="group-data-[active]/card:text-blue-600"
160
+
161
+ // group-aria: standard states use bare form, non-standard use brackets
162
+ sz={{ group: { aria: { expanded: { color: 'blue-600' } } } }}
163
+ // → className="group-aria-expanded:text-blue-600"
164
+
165
+ sz={{ group: { aria: { 'current=page': { fontWeight: 'bold' } } } }}
166
+ // → className="group-aria-[current=page]:font-bold"
167
+
168
+ // peer-data / peer-aria work the same way
169
+ sz={{ peer: { data: { error: { color: 'red-600' } } } }}
170
+ // → className="peer-data-[error]:text-red-600"
171
+
172
+ sz={{ peer: { aria: { checked: { bg: 'blue-100' } } } }}
173
+ // → className="peer-aria-checked:bg-blue-100"
174
+ ```
175
+
176
+ ### Data / ARIA attributes
177
+
178
+ ```tsx
179
+ sz={{ data: { active: { bg: 'blue' } } }}
180
+ // → className="data-[active]:bg-blue"
181
+
182
+ sz={{ aria: { expanded: { color: 'blue' } } }}
183
+ // → className="aria-expanded:text-blue"
184
+ ```
185
+
186
+ ### Pseudo-elements
187
+
188
+ ```tsx
189
+ sz={{ before: { content: '""' }, after: { bg: 'blue-500' } }}
190
+ // content: '""' → content-[''] (compiler normalizes double-quote form to single-quote)
191
+ // content: "''" also works → content-[''] (same output)
192
+ sz={{ placeholder: { color: 'gray-400' } }}
193
+ ```
194
+
195
+ ### Container queries
196
+
197
+ ```tsx
198
+ sz={{ '@container': true, '@md': { flex: true } }}
199
+ // → className="@container @md:flex"
200
+ ```
201
+
202
+ ## Critical Rules — Common Mistakes
203
+
204
+ ```tsx
205
+ // ❌ CSS property names as keys — use sz keys
206
+ { padding: 4 } // Wrong → { p: 4 }
207
+ { backgroundColor: 'blue' } // Wrong → { bg: 'blue' }
208
+ { flexDirection: 'col' } // Wrong → { flexDir: 'col' }
209
+ { marginTop: 4 } // Wrong → { mt: 4 }
210
+ { fontSize: 'lg' } // Wrong → { text: 'lg' }
211
+
212
+ // ❌ Manual brackets — compiler auto-wraps arbitrary values
213
+ { w: '[333px]' } // Wrong → { w: '333px' }
214
+ { top: '[-1px]' } // Wrong → { top: '-1px' }
215
+
216
+ // ❌ Tailwind class strings as values
217
+ { p: 'p-4' } // Wrong → { p: 4 }
218
+ { bg: 'bg-blue-500' } // Wrong → { bg: 'blue-500' }
219
+
220
+ // ❌ Mixing className= and sz= on the same element
221
+ <div className="p-4" sz={{ m: 2 }} /> // Wrong — use sz only
222
+
223
+ // ✅ Correct
224
+ { p: 4, bg: 'blue-500', flex: true, flexDir: 'col', w: '333px', mt: 4, text: 'lg' }
225
+ ```
226
+
227
+ ## Full Snippets Reference
228
+
229
+ # Core Concepts
230
+
231
+ ## Styling with Utility Classes
232
+
233
+ ## Basic Utilities
234
+
235
+ Simple property-value mappings.
236
+
237
+ | Concept | CSS Property | Tailwind v4 Class | `sz` Prop (Canonical) |
238
+ | :------------------- | :--------------------------------------- | :---------------- | :-------------------- |
239
+ | **Padding** | `padding: 1.5rem` | `p-6` | `{ p: 6 }` |
240
+ | **Background Color** | `background-color: var(--color-sky-500)` | `bg-sky-500` | `{ bg: 'sky-500' }` |
241
+ | **Text Color** | `color: white` | `text-white` | `{ color: 'white' }` |
242
+ | **Border Radius** | `border-radius: var(--radius-lg)` | `rounded-lg` | `{ rounded: 'lg' }` |
243
+ | **Box Shadow** | `box-shadow: var(--shadow-xl)` | `shadow-xl` | `{ shadow: 'xl' }` |
244
+ | **Flex Container** | `display: flex` | `flex` | `{ flex: true }` |
245
+
246
+ ## State Modifiers (Hover, Focus)
247
+
248
+ Handling pseudo-classes using nested objects or string prefixes.
249
+
250
+ | Concept | CSS Rule (Simplified) | Tailwind v4 Class | `sz` Prop (Canonical) | `sz` Prop (Object Syntax) |
251
+ | :------------------- | :------------------------------------ | :-------------------------- | :-------------------------- | :------------------------------------------- |
252
+ | **Hover State** | `&:hover { background-color: (etc) }` | `hover:bg-sky-700` | `{ hover: 'bg-sky-700' }` | `{ hover: { bg: 'sky-700' } }` |
253
+ | **Focus State** | `&:focus { outline: (etc) }` | `focus:outline-none` | `{ focus: 'outline-none' }` | `{ focus: { outline: 'none' } }` |
254
+ | **Active State** | `&:active { opacity: 0.8 }` | `active:opacity-80` | `{ active: 'opacity-80' }` | `{ active: { opacity: 80 } }` |
255
+ | **Disabled + Hover** | `&:disabled:hover { (etc) }` | `disabled:hover:bg-sky-500` | N/A (Complex string) | `{ disabled: { hover: { bg: 'sky-500' } } }` |
256
+
257
+ ## Responsive Design (Breakpoints)
258
+
259
+ Handling media queries via properties.
260
+
261
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) |
262
+ | :------------------- | :---------------------------------- | :---------------- | :------------------------ |
263
+ | **Small Breakpoint** | `@media (width >= 40rem) { (etc) }` | `sm:grid-cols-3` | `{ sm: { gridCols: 3 } }` |
264
+ | **Medium Layout** | `@media (width >= 48rem) { (etc) }` | `md:flex` | `{ md: { flex: true } }` |
265
+ | **Large Spacing** | `@media (width >= 64rem) { (etc) }` | `lg:px-8` | `{ lg: { px: 8 } }` |
266
+
267
+ ## Dark Mode
268
+
269
+ Handling `prefers-color-scheme` or class-based dark mode.
270
+
271
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) |
272
+ | :------------------ | :---------------------------------------------- | :----------------- | :----------------------------- |
273
+ | **Dark Background** | `@media (prefers-color-scheme: dark) { (etc) }` | `dark:bg-gray-800` | `{ dark: { bg: 'gray-800' } }` |
274
+ | **Dark Text** | `(etc) { color: white }` | `dark:text-white` | `{ dark: { color: 'white' } }` |
275
+
276
+ ## Composition (Filters & Transforms)
277
+
278
+ Composing multiple classes for a single effect.
279
+
280
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) |
281
+ | :------------------- | :------------------------------- | :------------------ | :-------------------------------- |
282
+ | **Filter Blur** | `filter: blur((etc)) (etc)` | `blur-sm` | `{ blur: 'sm' }` |
283
+ | **Filter Grayscale** | `filter: grayscale((etc)) (etc)` | `grayscale` | `{ grayscale: true }` |
284
+ | **Combined** | `filter: (etc)` | `blur-sm grayscale` | `{ blur: 'sm', grayscale: true }` |
285
+
286
+ ## Arbitrary Values
287
+
288
+ Mapping precise, non-theme values to JIT syntax (Arbitrary Properties or Values).
289
+
290
+ | Concept | CSS Property | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
291
+ | :------------------ | :---------------------------- | :----------------------------- | :---------------------------------- | :---------------------------------------- |
292
+ | **Arbitrary Color** | `background-color: #316ff6` | `bg-[#316ff6]` | `{ bg: '#316ff6' }` | Preferred over inline styles for caching. |
293
+ | **Arbitrary Size** | `width: 333px` | `w-[333px]` | `{ w: '333px' }` | Explicit unit required string. |
294
+ | **Data Prop** | `content: attr(data-content)` | `content-[attr(data-content)]` | `{ content: 'attr(data-content)' }` | Complex arbitrary strings. |
295
+
296
+ **Global Parsing Rule**: The compiler **MUST normalize whitespace** in arbitrary variant _keys_ before generation.
297
+
298
+ - `{ '[ & > span ]': (etc) }` -> `[&>span]:(etc)` — whitespace in arbitrary selector keys is stripped
299
+ - Values never need brackets: `{ w: 'calc(100% - 20px)' }` -> `w-[calc(100%_-_20px)]` — the compiler auto-wraps arbitrary values
300
+ - This ensures robust matching regardless of user formatting.
301
+
302
+ ## Complex Selectors & Modifiers
303
+
304
+ Handling `group-*`, `peer-*`, and arbitrary variants.
305
+
306
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
307
+ | :--------------------- | :------------------------------------ | :------------------------ | :------------------------------------------ | :------------------------------------------------------------ |
308
+ | **Group Hover** | `.group:hover .group-hover:text-blue` | `group-hover:text-blue` | `{ group: { hover: { color: 'blue' } } }` | **Sugar**: Nested `group` key acts as modifier scope. |
309
+ | **Peer Focus** | `.peer:focus ~ .peer-focus:text-blue` | `peer-focus:text-blue` | `{ peer: { focus: { color: 'blue' } } }` | **Sugar**: Nested `peer` key. |
310
+ | **Data Attribute** | `&[data-active] (etc)` | `data-[active]:text-blue` | `{ data: { active: { color: 'blue' } } }` | **Sugar**: Maps to `data-[key]`. |
311
+ | **ARIA Attribute** | `&[aria-expanded="true"] (etc)` | `aria-expanded:text-blue` | `{ aria: { expanded: { color: 'blue' } } }` | **Sugar**: Maps to `aria-[key]`. |
312
+ | **Arbitrary Variant** | `& > span` | `[&>span]:text-blue` | `{ '[& > span]': { color: 'blue' } }` | |
313
+ | **Important Modifier** | `color: red !important` | `text-red-500!` | `{ color: 'red-500!' }` | **New**: Trailing `!` in value maps to trailing `!` in class. |
314
+
315
+ ## Style Conflict Management
316
+
317
+ Inherently solved by the `sz` object model.
318
+
319
+ | Concept | Traditional Class Issue | `sz` Solution | Explanation |
320
+ | :------------------------ | :--------------------------------------------------- | :------------------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------- |
321
+ | **Duplicate Properties** | `class="p-4 p-8"` (Last one wins based on CSS order) | `{ p: 4, p: 8 }` (Syntax Error or Override) | JS objects cannot have duplicate keys. Last key wins _at source_, predictable. |
322
+ | **Longhand vs Shorthand** | `px-4 p-8` (Conflict) | `{ px: 4, p: 8 }` | The compiler must handle logical ordering (e.g. general `p` before specific `px`). **Implementation details** in compiler strategy. |
323
+
324
+ ## Prefix Option
325
+
326
+ Handling global configuration prefixes.
327
+
328
+ | Concept | Config | Tailwind v4 Output | `sz` Prop Input |
329
+ | :----------------- | :-------------- | :----------------- | :---------------------------------------------------------------------- |
330
+ | **Utility Prefix** | `prefix: 'tw-'` | `tw-text-center` | `{ textAlign: 'center' }` |
331
+ | **Result** | | | Compiler prepends `tw-` to all generated utility classes if configured. |
332
+
333
+ ## Hover, Focus, and Other States
334
+
335
+ ## Pseudo-classes
336
+
337
+ Standard interactive states.
338
+
339
+ | Concept | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
340
+ | :----------------------- | :------------------------------------------- | :------------------------------------------------------------------------- | :-------------------------- |
341
+ | **Hover, Focus, Active** | `hover:bg-red focus:bg-blue active:bg-green` | `{ hover: { bg: 'red' }, focus: { bg: 'blue' }, active: { bg: 'green' } }` | |
342
+ | **First/Last Child** | `first:pt-0 last:pb-0` | `{ first: { pt: 0 }, last: { pb: 0 } }` | |
343
+ | **Odd/Even Child** | `odd:bg-white even:bg-gray` | `{ odd: { bg: 'white' }, even: { bg: 'gray' } }` | |
344
+ | **First of Type** | `first-of-type:block` | `{ firstOfType: { block: true } }` | **Sugar**: CamelCase alias. |
345
+ | **Only Child** | `only:block` | `{ only: { block: true } }` | |
346
+ | **Empty** | `empty:hidden` | `{ empty: { hidden: true } }` | |
347
+ | **Visited** | `visited:text-purple` | `{ visited: { color: 'purple' } }` | |
348
+ | **Focus Within** | `focus-within:ring` | `{ focusWithin: { ring: true } }` | **Sugar**: CamelCase alias. |
349
+ | **Focus Visible** | `focus-visible:ring` | `{ focusVisible: { ring: true } }` | **Sugar**: CamelCase alias. |
350
+ | **Target** | `target:shadow` | `{ target: { shadow: true } }` | |
351
+
352
+ ## :has()
353
+
354
+ Styling based on descendants.
355
+
356
+ | Concept | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
357
+ | :----------------- | :-------------------------- | :---------------------------------------------- | :------------------------------------ |
358
+ | **Has Descendant** | `has-[img]:bg-blue` | `{ has: { img: { bg: 'blue' } } }` | **Sugar**: Nested selector. |
359
+ | **Has State** | `has-[:checked]:bg-blue` | `{ has: { checked: { bg: 'blue' } } }` | **Sugar**: Auto-detects pseudo-class. |
360
+ | **Arbitrary Has** | `has-[.custom-class]:block` | `{ has: { '.custom-class': { block: true } } }` | |
361
+
362
+ ## Styling based on parent state (Groups)
363
+
364
+ Styling children based on parent `group` class.
365
+
366
+ | Concept | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
367
+ | :--------------------------- | :------------------------------------ | :---------------------------------------------------------------- | :----------------------------------- |
368
+ | **Group Hover** | `group-hover:text-white` | `{ group: { hover: { color: 'white' } } }` | **Sugar**: Nested scope. |
369
+ | **Group Focus** | `group-focus:text-white` | `{ group: { focus: { color: 'white' } } }` | |
370
+ | **Group Active** | `group-active:text-white` | `{ group: { active: { color: 'white' } } }` | |
371
+ | **Nested Groups** | `group-hover/name:text-white` | `{ group: { name: { hover: { color: 'white' } } } }` | **Sugar**: Scope name as nested key. |
372
+ | **Arbitrary Groups** | `group-[.is-published]:block` | `{ group: { '.is-published': { block: true } } }` | |
373
+ | **Group Has** | `group-has-[a]:block` | `{ group: { has: { a: { block: true } } } }` | |
374
+ | **Group Data** | `group-data-[active]:text-blue` | `{ group: { data: { active: { color: 'blue' } } } }` | **Sugar**: Nested `data` key. |
375
+ | **Group Data (named)** | `group-data-[active]/card:text-blue` | `{ group: { card: { data: { active: { color: 'blue' } } } } }` | Name before `data` key. |
376
+ | **Group Data (value match)** | `group-data-[state=open]:block` | `{ group: { data: { 'state=open': { block: true } } } }` | `=` in key → bracket form always. |
377
+ | **Group ARIA** | `group-aria-expanded:block` | `{ group: { aria: { expanded: { block: true } } } }` | Standard states: bare form. |
378
+ | **Group ARIA (arbitrary)** | `group-aria-[current=page]:font-bold` | `{ group: { aria: { 'current=page': { fontWeight: 'bold' } } } }` | Non-standard: bracket form. |
379
+
380
+ ## Styling based on sibling state (Peers)
381
+
382
+ Styling based on previous sibling `peer` class.
383
+
384
+ | Concept | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
385
+ | :-------------------------- | :---------------------------------- | :--------------------------------------------------------- | :----------------------------------- |
386
+ | **Peer Hover** | `peer-hover:text-white` | `{ peer: { hover: { color: 'white' } } }` | **Sugar**: Nested scope. |
387
+ | **Peer Checked** | `peer-checked:bg-blue` | `{ peer: { checked: { bg: 'blue' } } }` | |
388
+ | **Differentiating Peers** | `peer-checked/name:bg-blue` | `{ peer: { name: { checked: { bg: 'blue' } } } }` | **Sugar**: Scope name as nested key. |
389
+ | **Arbitrary Peers** | `peer-[.is-dirty]:block` | `{ peer: { '.is-dirty': { block: true } } }` | |
390
+ | **Peer Data** | `peer-data-[active]:text-blue` | `{ peer: { data: { active: { color: 'blue' } } } }` | **Sugar**: Nested `data` key. |
391
+ | **Peer Data (value match)** | `peer-data-[state=open]:block` | `{ peer: { data: { 'state=open': { block: true } } } }` | `=` in key → bracket form always. |
392
+ | **Peer ARIA** | `peer-aria-checked:bg-blue` | `{ peer: { aria: { checked: { bg: 'blue' } } } }` | Standard states: bare form. |
393
+ | **Peer ARIA (arbitrary)** | `peer-aria-[invalid=true]:text-red` | `{ peer: { aria: { 'invalid=true': { color: 'red' } } } }` | Non-standard: bracket form. |
394
+
395
+ ## :not()
396
+
397
+ Inverse conditions.
398
+
399
+ | Concept | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
400
+ | :--------------- | :---------------------------------- | :----------------------------------------------------------- | :--- |
401
+ | **Not Hover** | `not-hover:opacity-75` | `{ not: { hover: { opacity: 75 } } }` | |
402
+ | **Not First** | `not-first:mt-4` | `{ not: { first: { mt: 4 } } }` | |
403
+ | **Not Supports** | `not-supports-[display:grid]:block` | `{ not: { supports: { 'display:grid': { block: true } } } }` | |
404
+
405
+ ## Pseudo-elements
406
+
407
+ Advanced content styling.
408
+
409
+ | Concept | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
410
+ | :--------------- | :---------------------- | :----------------------------------- | :-------------------- |
411
+ | **Before/After** | `before:content-['']` | `{ before: { (etc) } }` | Defaults used. |
412
+ | **Placeholder** | `placeholder:text-gray` | `{ placeholder: { color: 'gray' } }` | |
413
+ | **File** | `file:border` | `{ file: { border: true } }` | |
414
+ | **Marker** | `marker:text-blue` | `{ marker: { color: 'blue' } }` | |
415
+ | **Selection** | `selection:bg-pink` | `{ selection: { bg: 'pink' } }` | |
416
+ | **First Line** | `first-line:uppercase` | `{ firstLine: { uppercase: true } }` | **Sugar**: CamelCase. |
417
+ | **First Letter** | `first-letter:text-7xl` | `{ firstLetter: { text: '7xl' } }` | **Sugar**: CamelCase. |
418
+ | **Backdrop** | `backdrop:blur` | `{ backdrop: { blur: true } }` | |
419
+
420
+ ## Media & Feature Queries
421
+
422
+ Environment-based styling.
423
+
424
+ | Concept | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
425
+ | :-------------------- | :-------------------------------- | :-------------------------------------------------- | :---------------------------- |
426
+ | **Breakpoints** | `md:block lg:flex` | `{ md: { block: true }, lg: { flex: true } }` | |
427
+ | **Container Queries** | `@md:block @lg:flex` | `{ '@md': { block: true }, '@lg': { flex: true } }` | **Note**: String key for `@`. |
428
+ | **Reduced Motion** | `motion-reduce:hidden` | `{ motionReduce: { hidden: true } }` | **Sugar**: CamelCase. |
429
+ | **Prefers Contrast** | `contrast-more:border` | `{ contrastMore: { border: true } }` | |
430
+ | **Forced Colors** | `forced-colors:border-gray` | `{ forcedColors: { borderColor: 'gray' } }` | **Sugar**: CamelCase. |
431
+ | **Inverted Colors** | `inverted-colors:invert` | `{ invertedColors: { invert: true } }` | **Sugar**: CamelCase. |
432
+ | **Pointer** | `pointer-coarse:p-4` | `{ pointerCoarse: { p: 4 } }` | **Sugar**: CamelCase. |
433
+ | **Any-Pointer** | `any-pointer-fine:cursor-pointer` | `{ anyPointerFine: { cursor: 'pointer' } }` | v4.1. **Sugar**: CamelCase. |
434
+ | **User Valid** | `user-valid:border-green-500` | `{ userValid: { borderColor: 'green-500' } }` | v4.1. Form validation state. |
435
+ | **User Invalid** | `user-invalid:border-red-500` | `{ userInvalid: { borderColor: 'red-500' } }` | v4.1. Form validation state. |
436
+ | **Details Content** | `details-content:block` | `{ detailsContent: { block: true } }` | v4.1. **Sugar**: CamelCase. |
437
+ | **Print** | `print:hidden` | `{ print: { hidden: true } }` | |
438
+ | **Orientation** | `portrait:hidden` | `{ portrait: { hidden: true } }` | |
439
+ | **Scripting** | `noscript:block` | `{ noscript: { block: true } }` | |
440
+ | **Supports** | `supports-[display:grid]:grid` | `{ supports: { 'display:grid': { grid: true } } }` | |
441
+ | **Starting Style** | `starting:opacity-0` | `{ starting: { opacity: 0 } }` | |
442
+
443
+ ## Attribute Selectors
444
+
445
+ Data and state attributes.
446
+
447
+ | Concept | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
448
+ | :------------------ | :---------------------- | :-------------------------------------- | :--- |
449
+ | **Data Attributes** | `data-[active]:bg-blue` | `{ data: { active: { bg: 'blue' } } }` | |
450
+ | **ARIA States** | `aria-checked:bg-blue` | `{ aria: { checked: { bg: 'blue' } } }` | |
451
+ | **RTL/LTR** | `rtl:mr-2` | `{ rtl: { mr: 2 } }` | |
452
+ | **Open** | `open:bg-white` | `{ open: { bg: 'white' } }` | |
453
+ | **Inert** | `inert:opacity-50` | `{ inert: { opacity: 50 } }` | |
454
+
455
+ ## Helper Variants (Child/Descendants)
456
+
457
+ Mapping for common descendant patterns.
458
+
459
+ | Concept | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
460
+ | :------------------ | :---------------- | :------------------------ | :---------------------- |
461
+ | **Direct Children** | `*:p-4` | `{ '*': { p: 4 } }` | Map `*` to `*` variant. |
462
+ | **Descendants** | `[&_*]:p-4` | `{ '[&_*]': { p: 4 } }` | Raw selector fallback. |
463
+
464
+ ## Custom Variants
465
+
466
+ Extensibility.
467
+
468
+ | Concept | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
469
+ | :-------------- | :---------------- | :------------------------ | :----------------------------------------------------------------- |
470
+ | **Custom Name** | `my-variant:p-4` | `{ myVariant: { p: 4 } }` | **Rule**: Users can use CamelCase key matching registered variant. |
471
+
472
+ ## Responsive design
473
+
474
+ Targeting specific screen sizes and container states.
475
+
476
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
477
+ | :----------------------- | :-------------------------- | :------------------------ | :------------------------------------------------ | :---------------------------------- |
478
+ | **Mobile First** | `min-width: (etc)` | `w-full md:w-1/2` | `{ w: 'full', md: { w: '1/2' } }` | Unprefixed utilities target mobile. |
479
+ | **Breakpoint Range** | `768px <= width < 1280px` | `md:max-xl:flex` | `{ md: { maxXl: { flex: true } } }` | **Sugar**: CamelCase for `max-xl`. |
480
+ | **Single Breakpoint** | `md only` | `md:max-lg:flex` | `{ md: { maxLg: { flex: true } } }` | Target specific range. |
481
+ | **Custom Breakpoint** | `@media (min-width: 320px)` | `min-[320px]:text-center` | `{ min: { '[320px]': { textAlign: 'center' } } }` | Arbitrary one-off breakpoint. |
482
+ | **Max-Width Breakpoint** | `@media (max-width: 600px)` | `max-[600px]:bg-sky-300` | `{ max: { '[600px]': { bg: 'sky-300' } } }` | |
483
+
484
+ ## Container Query Disambiguation
485
+
486
+ > ⚠️ **IMPORTANT:** `container` and `@container` are **different** Tailwind classes!
487
+
488
+ ## Container Utility (max-width responsive)
489
+
490
+ The `container` class sets `width: 100%` and applies responsive max-widths.
491
+
492
+ | CSS | Tailwind | sz Prop |
493
+ | ------------- | ----------- | --------------------- |
494
+ | `width: 100%` | `container` | `{ container: true }` |
495
+
496
+ ## Container Query Rule
497
+
498
+ The `@container` class enables CSS container queries.
499
+
500
+ | Concept | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
501
+ | :----------------------- | :------------------- | :------------------------------------------ | :---------------------------------------- |
502
+ | **Mark Container** | `@container` | `{ '@container': true }` | |
503
+ | **Named Container** | `@container/sidebar` | `{ '@container': 'sidebar' }` | **Sugar**: Value string = container name. |
504
+ | **Container Breakpoint** | `@md:flex` | `{ '@md': { flex: true } }` | **Note**: `@` prefix in key. |
505
+ | **Named Query** | `@md/sidebar:block` | `{ '@md': { sidebar: { block: true } } }` | **Sugar**: Nest name inside query key. |
506
+ | **Container Range** | `@sm:@max-md:block` | `{ '@sm': { '@maxMd': { block: true } } }` | |
507
+ | **Arbitrary Query** | `@min-[475px]:flex` | `{ '@min': { '[475px]': { flex: true } } }` | |
508
+ | **Container Units** | `w-[50cqw]` | `{ w: '50cqw' }` | |
509
+
510
+ ## Dark mode
511
+
512
+ Styling for dark color schemes.
513
+
514
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
515
+ | :-------------------- | :------------------------------------ | :---------------- | :--------------------------- | :----------------------------------------- |
516
+ | **Media Strategy** | `@media (prefers-color-scheme: dark)` | `dark:bg-black` | `{ dark: { bg: 'black' } }` | Default behavior. |
517
+ | **Selector Strategy** | `.dark &` | `dark:bg-black` | `{ dark: { bg: 'black' } }` | Enabled via config `darkMode: 'selector'`. |
518
+ | **Variant** | `[data-mode="dark"] &` | `dark:bg-black` | `{ dark: { bg: 'black' } }` | Custom selector config. |
519
+ | **Force Light** | N/A | `light:bg-white` | `{ light: { bg: 'white' } }` | Override dark mode. |
520
+
521
+ ## Theme variables
522
+
523
+ Using design tokens.
524
+
525
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
526
+ | :------------------- | :----------------------------- | :------------------ | :------------------------ | :----------------------------------------------------- |
527
+ | **Using Theme Var** | `color: var(--color-mint-500)` | `text-mint-500` | `{ color: 'mint-500' }` | **Rule**: Use the utility name derived from variable. |
528
+ | **Arbitrary Var** | `width: var(--spacing-4)` | `w-(--spacing-4)` | `{ w: '--spacing-4' }` | **Sugar**: Auto-detects `--` prefix and wraps in `()`. |
529
+ | **Var In Arbitrary** | `padding: var(--my-pad)` | `p-[var(--my-pad)]` | `{ p: 'var(--my-pad)' }` | |
530
+
531
+ ## Colors
532
+
533
+ Palette and opacity.
534
+
535
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
536
+ | --------------------- | ------------------------- | ----------------------- | ---------------------------------------------- | ------------------------------------------------ |
537
+ | **Standard Color** | `background-color: (etc)` | `bg-blue-500` | `{ bg: 'blue-500' }` | |
538
+ | **Opacity Modifier** | `(etc) / 0.5` | `bg-blue-500/50` | `{ bg: { color: 'blue-500', op: 50 } }` | v4: any integer is bare. |
539
+ | **Opacity 0.5-step** | `(etc) / 0.755` | `bg-black/75.5` | `{ bg: { color: 'black', op: 75.5 } }` | Decimals with 0.5 step are bare. |
540
+ | **Arbitrary Opacity** | `(etc) / 0.73` | `bg-pink-500/[78%]` | `{ bg: { color: 'pink-500', op: '78%' } }` | `%`, leading `.`, non-0.5 decimals go to `[]`. |
541
+ | **Variable Opacity** | `(etc) / var(--alpha)` | `bg-blue-500/(--alpha)` | `{ bg: { color: 'blue-500', op: '--alpha' } }` | Color opacity modifiers use `()` for CSS vars. |
542
+ | **Inherited Opacity** | `color-mix((etc))` | `text-current/50` | `{ color: { color: 'current', op: 50 } }` | Use `current` color to modify inherited opacity. |
543
+
544
+ ## Adding custom styles
545
+
546
+ Extending the framework.
547
+
548
+ ## Using arbitrary values
549
+
550
+ One-off values without configuration.
551
+
552
+ | Concept | CSS Property | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
553
+ | :------------------ | :----------------------- | :-------------------- | :-------------------------- | :------------------------------ |
554
+ | **Arbitrary Value** | `mask-image: url((etc))` | `mask-[url((etc))]` | `{ mask: 'url((etc))' }` | Auto-detects custom value. |
555
+ | **Arbitrary Prop** | `mask-type: luminance` | `mask-type-luminance` | `{ maskType: 'luminance' }` | Maps known props automatically. |
556
+ | **CSS Variable** | `--my-var: 10px` | `[--my-var:10px]` | `{ '--my-var': '10px' }` | String key for unknowns. |
557
+
558
+ ## Using custom CSS & Plugins
559
+
560
+ Integrating external styles.
561
+
562
+ | Concept | Tailwind v4 Approach | `sz` Equivalent | Note |
563
+ | :------------- | :--------------------- | :---------------------- | :-------------------------------- |
564
+ | **CSS Import** | `@import "custom.css"` | `import './custom.css'` | Standard module bundler behavior. |
565
+ | **Plugin** | `@plugin "my-plugin"` | Config `plugins: []` | Compiler configuration. |
566
+
567
+ ## Functions & directives
568
+
569
+ Configuration and logic.
570
+
571
+ | Concept | Config | Tailwind v4 Output | `sz` Prop Input | Note |
572
+ | :----------------- | :-------------------- | :----------------- | :------------------------ | :---------------------------------------------- |
573
+ | **Utility Prefix** | `prefix: 'tw-'` | `tw-text-center` | `{ textAlign: 'center' }` | |
574
+ | **@apply** | `@apply items-center` | N/A | `{ (etc)commonOps }` | **Discouraged**: Use JS Object Spread. |
575
+ | **theme()** | `theme('spacing.4')` | `w-(--spacing-4)` | `{ w: '--spacing-4' }` | **Rule**: Use CSS Variable sugar (no parens). |
576
+ | **@utility** | `@utility tab-active` | `tab-active` | `{ tabActive: true }` | **Blind Support**: CamelCase maps to ClassName. |
577
+ | **@theme** | `@theme { (etc) }` | N/A | N/A | Configured in CSS, used via Vars/Classes. |
578
+
579
+ ## Detecting classes in source files
580
+
581
+ Strategy for static analysis vs runtime generation.
582
+
583
+ **Core Decision**: `CSSzyx` uses **AST Parsing**, not Regex Scanning. This allows for smarter static extraction and shake-tree logic.
584
+
585
+ | Concept | Tailwind Scanner (Regex) | `sz` Compiler (AST) | Note |
586
+ | :---------------------------- | :----------------------- | :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
587
+ | **String Interpolation** | ❌ Fails `bg-${color}` | ✅ **Runtime Support** | Compiler marks as dynamic, handled at runtime via variable injection. |
588
+ | **Conditionals** | ❌ Fails logic | ✅ **Static Extraction** | `{ bg: active ? 'blue' : 'gray' }` and `{ scale: shrunk ? 75 : 100 }` → both branches compiled to static Tailwind classes at build time. CSS variable fallback only when a branch is a runtime expression (not a literal). |
589
+ | **Variable reference** | ❌ Not applicable | ✅ **Build time** | `sz={myVar}` — pass variable directly when no override needed. Compiler resolves the binding to its object literal initializer (incl. `as const`, `satisfies`, explicit type annotation). |
590
+ | **Object Spread** | ❌ Fails spread | ✅ **Static Analysis** | `sz={{ ...baseProps, key: val }}` — use spread only when overriding/adding; last key wins. Resolved at build time for local literals. Multiple/nested spreads supported. Imported vars fall back to `_sz()` — no crash. |
591
+ | **Array variable items** | ❌ Not applicable | ✅ **Build time** | `sz={[varA, varB]}` and `sz={[varA, cond && varB]}` — variable array elements resolved at build time. Static elements merged to single string; conditional elements use `_szMerge` at runtime. |
592
+ | **Ternary variable branches** | ❌ Not applicable | ✅ **Build time** | `sz={cond ? varA : varB}` — both branches compiled to static strings when variables are local literals. |
593
+ | **Chained variables** | ❌ Not applicable | ✅ **Build time** | `const b = { ...a, key: val }; <div sz={b} />` — compiler resolves the chain recursively. |
594
+ | **Safelist** | Required for dynamic | **Not Required** | Auto-detected for static logic; Auto-injected for runtime values. |
595
+
596
+ **Performance Rule**: Prefer **Static Strings** in `sz` objects.
597
+
598
+ - ✅ `sz({ color: isErr ? 'red-500' : 'green-500' })` (Zero Runtime)
599
+ - ⚠️ `sz({ color:`red-${shade}`})` (Runtime injection overhead)
600
+
601
+
602
+ # Backgrounds
603
+
604
+ Controlling the background of an element.
605
+
606
+ ## Background Color
607
+
608
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
609
+ | :-------------------- | :---------------------------------------- | :------------------- | :----------------------------------------- | :----------------------------------------------- |
610
+ | **Color** | `background-color: ...` | `bg-blue-500` | `{ bg: 'blue-500' }` | |
611
+ | **Inherit** | `background-color: inherit` | `bg-inherit` | `{ bg: 'inherit' }` | |
612
+ | **Current** | `background-color: currentColor` | `bg-current` | `{ bg: 'current' }` | |
613
+ | **Transparent** | `background-color: transparent` | `bg-transparent` | `{ bg: 'transparent' }` | |
614
+ | **Arbitrary** | `background-color: #333` | `bg-[#333]` | `{ bg: '#333' }` | |
615
+ | **CSS Variable** | `background-color: var(--my-color)` | `bg-(--my-color)` | `{ bg: '--my-color' }` | **Sugar**: Auto-detects `--`. |
616
+ | **With Opacity** | `background-color: rgb(59 130 246 / 20%)` | `bg-blue-500/20` | `{ bg: { color: 'blue-500', op: 20 } }` | String slash (`'blue-500/20'`) is not supported. |
617
+ | **CSS Var + Opacity** | `background-color: var(--c) / 50%` | `bg-(--my-color)/50` | `{ bg: { color: '--my-color', op: 50 } }` | CSS variables are auto-wrapped in `(...)`. |
618
+ | **Hex + Opacity** | `background-color: #0d0d12` at 90% | `bg-[#0d0d12]/90` | `{ bg: { color: '#0d0d12', op: 90 } }` | Hex/rgb/hsl values are auto-wrapped in `[...]`. |
619
+ | **Decimal Opacity** | `background-color: black / 5%` | `bg-black/[0.05]` | `{ bg: { color: 'black', op: 0.05 } }` | Non-half-step decimals use arbitrary `/[0.05]`. |
620
+ | **Percent Opacity** | `background-color: pink-500 / 78%` | `bg-pink-500/[78%]` | `{ bg: { color: 'pink-500', op: '78%' } }` | String with `%` stays arbitrary. |
621
+
622
+ ## Background Image
623
+
624
+ ### String Patterns (Simple Cases)
625
+
626
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
627
+ | :------------------- | :------------------------------------------------- | :------------------------------------ | :------------------------------------------------------------------------------------------------------------- | :--------------------------------- |
628
+ | **URL** | `background-image: url(...)` | `bg-[url(...)]` | `{ bgImg: 'url(...)' }` | |
629
+ | **None** | `background-image: none` | `bg-none` | `{ bgImg: 'none' }` | |
630
+ | **CSS Variable** | `background-image: var(--my-image)` | `bg-(image:--my-image)` | `{ bgImg: '--my-image' }` | **Sugar**: Auto-detects `--`. |
631
+ | **Repeating Linear** | `background-image: repeating-linear-gradient(...)` | `bg-[repeating-linear-gradient(...)]` | `{ bgImg: 'repeating-linear-gradient(315deg,currentColor 0,currentColor 1px,transparent 0,transparent 50%)' }` | Spaces normalised to `_` in class. |
632
+ | **Repeating Radial** | `background-image: repeating-radial-gradient(...)` | `bg-[repeating-radial-gradient(...)]` | `{ bgImg: 'repeating-radial-gradient(circle, red 0, blue 10px)' }` | |
633
+
634
+ ### Object Patterns (Gradients)
635
+
636
+ **TypeScript Interface:**
637
+
638
+ ```typescript
639
+ type BgImgValue = string | BgImgGradient;
640
+ type BgImgGradient = {
641
+ gradient: "linear" | "radial" | "conic";
642
+ dir?: string | number; // OPTIONAL
643
+ in?: ColorInterpolation;
644
+ };
645
+ type ColorInterpolation =
646
+ | "srgb"
647
+ | "hsl"
648
+ | "oklab"
649
+ | "oklch"
650
+ | "longer"
651
+ | "shorter"
652
+ | "increasing"
653
+ | "decreasing";
654
+ ```
655
+
656
+ #### Linear Gradient
657
+
658
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
659
+ | :--------------------- | :--------------------------------------- | :----------------------------- | :----------------------------------------------------------- | :-------------------------------------------------------- |
660
+ | **Default** | `linear-gradient(to right, ...)` | `bg-linear-to-r` | `{ bgImg: { gradient: 'linear' } }` | Default: `dir='to-r'` |
661
+ | **Direction Keyword** | `linear-gradient(to right, ...)` | `bg-linear-to-r` | `{ bgImg: { gradient: 'linear', dir: 'to-r' } }` | All 8: to-t, to-tr, to-r, to-br, to-b, to-bl, to-l, to-tl |
662
+ | **Positive Angle** | `linear-gradient(<number>deg, ...)` | `bg-linear-<number>` | `{ bgImg: { gradient: 'linear', dir: <number> } }` | v4: any integer bare |
663
+ | **Negative Angle** | `linear-gradient(-<number>deg, ...)` | `-bg-linear-<number>` | `{ bgImg: { gradient: 'linear', dir: -<number> } }` | v4: any integer bare |
664
+ | **Arbitrary** | `linear-gradient(25deg, red 5%...)` | `bg-linear-[25deg,_red_5%...]` | `{ bgImg: { gradient: 'linear', dir: '25deg, red 5%...' } }` | |
665
+ | **CSS Variable** | `linear-gradient(var(--my-gradient))` | `bg-linear-(--var)` | `{ bgImg: { gradient: 'linear', dir: '--var' } }` | **Sugar**: Auto-detects `--`. |
666
+ | **With Interpolation** | `linear-gradient(in hsl, to right, ...)` | `bg-linear-to-r/hsl` | `{ bgImg: { gradient: 'linear', dir: 'to-r', in: 'hsl' } }` | Appends `/method` suffix |
667
+
668
+ #### Radial Gradient
669
+
670
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
671
+ | :--------------------- | :---------------------------------- | :----------------------- | :----------------------------------------------------- | :----------------------------- |
672
+ | **Default** | `radial-gradient(...)` | `bg-radial` | `{ bgImg: { gradient: 'radial' } }` | `dir` optional, default center |
673
+ | **Position** | `radial-gradient(at 50% 75%, ...)` | `bg-radial-[at_50%_75%]` | `{ bgImg: { gradient: 'radial', dir: 'at 50% 75%' } }` | |
674
+ | **CSS Variable** | `radial-gradient(var(--my-radial))` | `bg-radial-(--var)` | `{ bgImg: { gradient: 'radial', dir: '--var' } }` | **Sugar**: Auto-detects `--`. |
675
+ | **With Interpolation** | `radial-gradient(in oklab, ...)` | `bg-radial/oklab` | `{ bgImg: { gradient: 'radial', in: 'oklab' } }` | Appends `/method` suffix |
676
+
677
+ #### Conic Gradient
678
+
679
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
680
+ | :----------------- | :---------------------------------------- | :----------------------------------------- | :----------------------------------------------------------------------- | :---------------------------- |
681
+ | **Default** | `conic-gradient(...)` | `bg-conic` | `{ bgImg: { gradient: 'conic' } }` | No dir → `bg-conic` |
682
+ | **Positive Angle** | `conic-gradient(from <number>deg, ...)` | `bg-conic-<number>` | `{ bgImg: { gradient: 'conic', dir: <number> } }` | v4: any integer bare |
683
+ | **Negative Angle** | `conic-gradient(from -<number>deg, ...)` | `-bg-conic-<number>` | `{ bgImg: { gradient: 'conic', dir: -<number> } }` | v4: any integer bare |
684
+ | **Arbitrary** | `conic-gradient(in hsl shorter hue, ...)` | `bg-conic-[in_hsl_shorter_hue,_red,_blue]` | `{ bgImg: { gradient: 'conic', dir: 'in hsl shorter hue, red, blue' } }` | |
685
+ | **CSS Variable** | `conic-gradient(var(--my-conic))` | `bg-conic-(--var)` | `{ bgImg: { gradient: 'conic', dir: '--var' } }` | **Sugar**: Auto-detects `--`. |
686
+
687
+ ### Color Interpolation (`in` key)
688
+
689
+ Appends `/method` suffix to gradient class:
690
+
691
+ | `in` value | Suffix | Example Output |
692
+ | :----------- | :------------ | :-------------------------- |
693
+ | `srgb` | `/srgb` | `bg-linear-to-r/srgb` |
694
+ | `hsl` | `/hsl` | `bg-linear-to-r/hsl` |
695
+ | `oklab` | `/oklab` | `bg-linear-to-r/oklab` |
696
+ | `oklch` | `/oklch` | `bg-linear-to-r/oklch` |
697
+ | `longer` | `/longer` | `bg-linear-to-r/longer` |
698
+ | `shorter` | `/shorter` | `bg-linear-to-r/shorter` |
699
+ | `increasing` | `/increasing` | `bg-linear-to-r/increasing` |
700
+ | `decreasing` | `/decreasing` | `bg-linear-to-r/decreasing` |
701
+
702
+ ## Gradient Color Stops
703
+
704
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
705
+ | :----------------------------- | :------------------------ | :------------------ | :-------------------------- | :---------------------------------------------------------- |
706
+ | **From** | `--tw-gradient-from: ...` | `from-blue-500` | `{ from: 'blue-500' }` | |
707
+ | **Via** | `--tw-gradient-via: ...` | `via-blue-500` | `{ via: 'blue-500' }` | |
708
+ | **To** | `--tw-gradient-to: ...` | `to-blue-500` | `{ to: 'blue-500' }` | |
709
+ | **From Position** | `... <number>%` | `from-<number>%` | `{ fromPos: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
710
+ | **From Position Arbitrary** | `... <decimal>%` | `from-[<decimal>%]` | `{ fromPos: <decimal> }` | |
711
+ | **From Position Arbitrary** | `... 300px` | `from-[300px]` | `{ fromPos: '300px' }` | |
712
+ | **From Position CSS Variable** | `... var(--from-pos)` | `from-(--from-pos)` | `{ fromPos: '--from-pos' }` | **Sugar**: Auto-detects `--`. |
713
+ | **Via Position** | `... <number>%` | `via-<number>%` | `{ viaPos: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
714
+ | **Via Position Arbitrary** | `... <decimal>%` | `via-[<decimal>%]` | `{ viaPos: <decimal> }` | |
715
+ | **Via Position Arbitrary** | `... 300px` | `via-[300px]` | `{ viaPos: '300px' }` | |
716
+ | **Via Position CSS Variable** | `... var(--via-pos)` | `via-(--via-pos)` | `{ viaPos: '--via-pos' }` | **Sugar**: Auto-detects `--`. |
717
+ | **To Position** | `... <number>%` | `to-<number>%` | `{ toPos: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
718
+ | **To Position Arbitrary** | `... <decimal>%` | `to-[<decimal>%]` | `{ toPos: <decimal> }` | |
719
+ | **To Position Arbitrary** | `... 300px` | `to-[300px]` | `{ toPos: '300px' }` | |
720
+ | **To Position CSS Variable** | `... var(--to-pos)` | `to-(--to-pos)` | `{ toPos: '--to-pos' }` | **Sugar**: Auto-detects `--`. |
721
+
722
+ ## Background Position
723
+
724
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
725
+ | :--------------- | :------------------------------------- | :--------------------- | :----------------------------- | :---------------------------- |
726
+ | **Top Left** | `background-position: top left` | `bg-top-left` | `{ bgPos: 'top-left' }` | |
727
+ | **Top** | `background-position: top` | `bg-top` | `{ bgPos: 'top' }` | |
728
+ | **Top Right** | `background-position: top right` | `bg-top-right` | `{ bgPos: 'top-right' }` | |
729
+ | **Left** | `background-position: left` | `bg-left` | `{ bgPos: 'left' }` | |
730
+ | **Center** | `background-position: center` | `bg-center` | `{ bgPos: 'center' }` | |
731
+ | **Right** | `background-position: right` | `bg-right` | `{ bgPos: 'right' }` | |
732
+ | **Bottom Left** | `background-position: bottom left` | `bg-bottom-left` | `{ bgPos: 'bottom-left' }` | |
733
+ | **Bottom** | `background-position: bottom` | `bg-bottom` | `{ bgPos: 'bottom' }` | |
734
+ | **Bottom Right** | `background-position: bottom right` | `bg-bottom-right` | `{ bgPos: 'bottom-right' }` | |
735
+ | **Arbitrary** | `background-position: center top 1rem` | `bg-[center_top_1rem]` | `{ bgPos: 'center top 1rem' }` | |
736
+ | **CSS Variable** | `background-position: var(--bg-pos)` | `bg-(--bg-pos)` | `{ bgPos: '--bg-pos' }` | **Sugar**: Auto-detects `--`. |
737
+
738
+ ## Background Size
739
+
740
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
741
+ | :--------------- | :-------------------------------- | :--------------------- | :------------------------- | :---------------------------- |
742
+ | **Auto** | `background-size: auto` | `bg-auto` | `{ bgSize: 'auto' }` | |
743
+ | **Cover** | `background-size: cover` | `bg-cover` | `{ bgSize: 'cover' }` | |
744
+ | **Contain** | `background-size: contain` | `bg-contain` | `{ bgSize: 'contain' }` | |
745
+ | **Arbitrary** | `background-size: auto 100px` | `bg-size-[auto_100px]` | `{ bgSize: 'auto 100px' }` | |
746
+ | **CSS Variable** | `background-size: var(--bg-size)` | `bg-size-(--bg-size)` | `{ bgSize: '--bg-size' }` | **Sugar**: Auto-detects `--`. |
747
+
748
+ ## Background Attachment
749
+
750
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
751
+ | :--------- | :------------------------------ | :---------------- | :------------------------ | :--- |
752
+ | **Fixed** | `background-attachment: fixed` | `bg-fixed` | `{ bgAttach: 'fixed' }` | |
753
+ | **Local** | `background-attachment: local` | `bg-local` | `{ bgAttach: 'local' }` | |
754
+ | **Scroll** | `background-attachment: scroll` | `bg-scroll` | `{ bgAttach: 'scroll' }` | |
755
+
756
+ ## Background Clip
757
+
758
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
759
+ | :---------- | :----------------------------- | :---------------- | :------------------------ | :--- |
760
+ | **Border** | `background-clip: border-box` | `bg-clip-border` | `{ bgClip: 'border' }` | |
761
+ | **Padding** | `background-clip: padding-box` | `bg-clip-padding` | `{ bgClip: 'padding' }` | |
762
+ | **Content** | `background-clip: content-box` | `bg-clip-content` | `{ bgClip: 'content' }` | |
763
+ | **Text** | `background-clip: text` | `bg-clip-text` | `{ bgClip: 'text' }` | |
764
+
765
+ ## Background Repeat
766
+
767
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
768
+ | :------------ | :----------------------------- | :---------------- | :-------------------------- | :--- |
769
+ | **Repeat** | `background-repeat: repeat` | `bg-repeat` | `{ bgRepeat: 'repeat' }` | |
770
+ | **No Repeat** | `background-repeat: no-repeat` | `bg-no-repeat` | `{ bgRepeat: 'no-repeat' }` | |
771
+ | **Repeat X** | `background-repeat: repeat-x` | `bg-repeat-x` | `{ bgRepeat: 'repeat-x' }` | |
772
+ | **Repeat Y** | `background-repeat: repeat-y` | `bg-repeat-y` | `{ bgRepeat: 'repeat-y' }` | |
773
+ | **Round** | `background-repeat: round` | `bg-repeat-round` | `{ bgRepeat: 'round' }` | |
774
+ | **Space** | `background-repeat: space` | `bg-repeat-space` | `{ bgRepeat: 'space' }` | |
775
+
776
+ ## Background Origin
777
+
778
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
779
+ | :---------- | :------------------------------- | :------------------ | :------------------------ | :--- |
780
+ | **Border** | `background-origin: border-box` | `bg-origin-border` | `{ bgOrigin: 'border' }` | |
781
+ | **Padding** | `background-origin: padding-box` | `bg-origin-padding` | `{ bgOrigin: 'padding' }` | |
782
+ | **Content** | `background-origin: content-box` | `bg-origin-content` | `{ bgOrigin: 'content' }` | |
783
+
784
+
785
+ # Borders
786
+
787
+ Controlling borders, outlines, rings, and dividers.
788
+
789
+ ## Border Radius
790
+
791
+ Controlling the border radius of an element.
792
+
793
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
794
+ | :------------------ | :-------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------- | :------------------------ | :---------------------------- |
795
+ | **All Sides** | `border-radius: 0.25rem` | `rounded`, `rounded-sm`, `rounded-md`, `rounded-lg`, `rounded-xl`, `rounded-2xl`, `rounded-3xl`, `rounded-full` | `{ rounded: 'sm' }` | |
796
+ | **None** | `border-radius: 0px` | `rounded-none` | `{ rounded: 'none' }` | |
797
+ | **Top** | `border-top-left-radius: 0.125rem; border-top-right-radius: 0.125rem` | `rounded-t-sm` | `{ roundedT: 'sm' }` | |
798
+ | **Right** | `border-top-right-radius: 0.125rem; border-bottom-right-radius: 0.125rem` | `rounded-r-sm` | `{ roundedR: 'sm' }` | |
799
+ | **Bottom** | `border-bottom-right-radius: 0.125rem; border-bottom-left-radius: 0.125rem` | `rounded-b-sm` | `{ roundedB: 'sm' }` | |
800
+ | **Left** | `border-top-left-radius: 0.125rem; border-bottom-left-radius: 0.125rem` | `rounded-l-sm` | `{ roundedL: 'sm' }` | |
801
+ | **Top Left** | `border-top-left-radius` | `rounded-tl-sm` | `{ roundedTl: 'sm' }` | |
802
+ | **Top Right** | `border-top-right-radius` | `rounded-tr-sm` | `{ roundedTr: 'sm' }` | |
803
+ | **Bottom Right** | `border-bottom-right-radius` | `rounded-br-sm` | `{ roundedBr: 'sm' }` | |
804
+ | **Bottom Left** | `border-bottom-left-radius` | `rounded-bl-sm` | `{ roundedBl: 'sm' }` | |
805
+ | **Start (Logical)** | `border-start-start-radius` | `rounded-s-sm` | `{ roundedS: 'sm' }` | |
806
+ | **End (Logical)** | `border-end-end-radius` | `rounded-e-sm` | `{ roundedE: 'sm' }` | |
807
+ | **Start-Start** | `border-start-start-radius` | `rounded-ss-sm` | `{ roundedSs: 'sm' }` | |
808
+ | **Start-End** | `border-start-end-radius` | `rounded-se-sm` | `{ roundedSe: 'sm' }` | |
809
+ | **End-Start** | `border-end-start-radius` | `rounded-es-sm` | `{ roundedEs: 'sm' }` | |
810
+ | **End-End** | `border-end-end-radius` | `rounded-ee-sm` | `{ roundedEe: 'sm' }` | |
811
+ | **Arbitrary** | `border-radius: 5px` | `rounded-[5px]` | `{ rounded: '5px' }` | |
812
+ | **CSS Variable** | `border-radius: var(--r)` | `rounded-(--r)` | `{ rounded: '--r' }` | **Sugar**: Auto-detects `--`. |
813
+
814
+ ## Border Width
815
+
816
+ Controlling the width of an element's borders.
817
+
818
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
819
+ | :-------------- | :-------------------------- | :--------------------------------------------- | :------------------------------- | :------------------------ |
820
+ | **All Sides** | `border-width: 1px` | `border` | `{ border: true }` | **Default**: 1px. |
821
+ | **Width Scale** | `border-width: 2px` | `border-0`, `border-2`, `border-4`, `border-8` | `{ border: 0 }`, `{ border: 2 }` | |
822
+ | **X Axis** | `border-inline-width: 2px` | `border-x-2` | `{ borderX: 2 }` | |
823
+ | **Y Axis** | `border-block-width: 2px` | `border-y-2` | `{ borderY: 2 }` | |
824
+ | **Top** | `border-top-width: 2px` | `border-t-2` | `{ borderT: 2 }` | |
825
+ | **Right** | `border-right-width: 2px` | `border-r-2` | `{ borderR: 2 }` | |
826
+ | **Bottom** | `border-bottom-width: 2px` | `border-b-2` | `{ borderB: 2 }` | |
827
+ | **Left** | `border-left-width: 2px` | `border-l-2` | `{ borderL: 2 }` | |
828
+ | **Start** | `border-inline-start-width` | `border-s-2` | `{ borderS: 2 }` | |
829
+ | **End** | `border-inline-end-width` | `border-e-2` | `{ borderE: 2 }` | |
830
+ | **Block Start** | `border-block-start-width` | `border-bs-2` | `{ borderBs: 2 }` | v4.2: logical block-side. |
831
+ | **Block End** | `border-block-end-width` | `border-be-2` | `{ borderBe: 2 }` | v4.2: logical block-side. |
832
+ | **Arbitrary** | `border-width: 3px` | `border-[3px]` | `{ border: '3px' }` | |
833
+ | **Variable** | `border-width: var(--w)` | `border-(--w)` | `{ border: '--w' }` | |
834
+
835
+ ## Border Color
836
+
837
+ Controlling the color of an element's borders.
838
+
839
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
840
+ | :-------------------- | :---------------------------- | :------------------ | :---------------------------------------------- | :----------------------------------------- |
841
+ | **Color** | `border-color: currentColor` | `border-red-500` | `{ borderColor: 'red-500' }` | |
842
+ | **Opacity** | `border-color: currentColor` | `border-red-500/50` | `{ borderColor: { color: 'red-500', op: 50 } }` | |
843
+ | **CSS Var + Opacity** | `border-color: var(--c) / 50` | `border-(--c)/50` | `{ borderColor: { color: '--c', op: 50 } }` | CSS variables are auto-wrapped in `(...)`. |
844
+ | **X/Y/T/R/B/L** | `border-color: currentColor` | `border-t-red-500` | `{ borderTColor: 'red-500' }` | Verbose keys to avoid conflict with Width. |
845
+ | **Arbitrary** | `border-color: currentColor` | `border-[#50d71e]` | `{ borderColor: '#50d71e' }` | |
846
+ | **Variable** | `border-color: var(--c)` | `border-(--c)` | `{ borderColor: '--c' }` | |
847
+
848
+ ## Border Style
849
+
850
+ Controlling the style of an element's borders.
851
+
852
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
853
+ | :--------- | :--------------------- | :---------------- | :-------------------------- | :--- |
854
+ | **Solid** | `border-style: solid` | `border-solid` | `{ borderStyle: 'solid' }` | |
855
+ | **Dashed** | `border-style: dashed` | `border-dashed` | `{ borderStyle: 'dashed' }` | |
856
+ | **Dotted** | `border-style: dotted` | `border-dotted` | `{ borderStyle: 'dotted' }` | |
857
+ | **Double** | `border-style: double` | `border-double` | `{ borderStyle: 'double' }` | |
858
+ | **Hidden** | `border-style: hidden` | `border-hidden` | `{ borderStyle: 'hidden' }` | |
859
+ | **None** | `border-style: none` | `border-none` | `{ borderStyle: 'none' }` | |
860
+
861
+ ## Divide Width
862
+
863
+ Utilities for controlling the border width between elements.
864
+
865
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
866
+ | :------------ | :------------------------------------------------------------- | :----------------------------------------------------- | :------------------------- | :------------------- |
867
+ | **X** | `border-inline-start-width: 0px; border-inline-end-width: 1px` | `divide-x` | `{ divideX: true }` | Applied to children. |
868
+ | **X Scale** | `border-inline-end-width: 1px` | `divide-x-0`, `divide-x-2`, `divide-x-4`, `divide-x-8` | `{ divideX: 2 }` | |
869
+ | **X Reverse** | `--tw-divide-x-reverse: 1` | `divide-x-reverse` | `{ divideXReverse: true }` | |
870
+ | **Y** | `border-top-width: 0px; border-bottom-width: 1px` | `divide-y` | `{ divideY: true }` | |
871
+ | **Y Scale** | `border-bottom-width: 1px` | `divide-y-0`, `divide-y-2`, `divide-y-4`, `divide-y-8` | `{ divideY: 2 }` | |
872
+ | **Y Reverse** | `--tw-divide-y-reverse: 1` | `divide-y-reverse` | `{ divideYReverse: true }` | |
873
+ | **Arbitrary** | `border-inline-end-width: 3px` | `divide-x-[3px]` | `{ divideX: '3px' }` | |
874
+ | **Variable** | `border-inline-end-width: var(--w)` | `divide-x-(--w)` | `{ divideX: '--w' }` | |
875
+
876
+ ## Divide Color
877
+
878
+ Utilities for controlling the border color between elements.
879
+
880
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
881
+ | :-------------------- | :---------------------------- | :------------------ | :---------------------------------------------- | :----------------------------------------- |
882
+ | **Color** | `border-color: currentColor` | `divide-red-500` | `{ divideColor: 'red-500' }` | |
883
+ | **Opacity** | `border-color: currentColor` | `divide-red-500/50` | `{ divideColor: { color: 'red-500', op: 50 } }` | |
884
+ | **CSS Var + Opacity** | `border-color: var(--c) / 50` | `divide-(--c)/50` | `{ divideColor: { color: '--c', op: 50 } }` | CSS variables are auto-wrapped in `(...)`. |
885
+ | **Arbitrary** | `border-color: currentColor` | `divide-[#50d71e]` | `{ divideColor: '#50d71e' }` | |
886
+ | **Variable** | `border-color: var(--c)` | `divide-(--c)` | `{ divideColor: '--c' }` | |
887
+
888
+ ## Divide Style
889
+
890
+ Utilities for controlling the border style between elements.
891
+
892
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
893
+ | :--------- | :--------------------- | :---------------- | :-------------------------- | :--- |
894
+ | **Solid** | `border-style: solid` | `divide-solid` | `{ divideStyle: 'solid' }` | |
895
+ | **Dashed** | `border-style: dashed` | `divide-dashed` | `{ divideStyle: 'dashed' }` | |
896
+ | **Dotted** | `border-style: dotted` | `divide-dotted` | `{ divideStyle: 'dotted' }` | |
897
+ | **Double** | `border-style: double` | `divide-double` | `{ divideStyle: 'double' }` | |
898
+ | **None** | `border-style: none` | `divide-none` | `{ divideStyle: 'none' }` | |
899
+
900
+ ## Outline Width
901
+
902
+ Controlling the width of an element's outline.
903
+
904
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
905
+ | :------------ | :------------------------ | :------------------------------------------------------------------------- | :------------------------ | :--- |
906
+ | **Width** | `outline-width: 1px` | `outline`, `outline-0`, `outline-1`, `outline-2`, `outline-4`, `outline-8` | `{ outline: 1 }` | |
907
+ | **Arbitrary** | `outline-width: 3px` | `outline-[3px]` | `{ outline: '3px' }` | |
908
+ | **Variable** | `outline-width: var(--w)` | `outline-(--w)` | `{ outline: '--w' }` | |
909
+
910
+ ## Outline Color
911
+
912
+ Controlling the color of an element's outline.
913
+
914
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
915
+ | :------------ | :---------------------------- | :------------------ | :---------------------------- | :--- |
916
+ | **Color** | `outline-color: currentColor` | `outline-red-500` | `{ outlineColor: 'red-500' }` | |
917
+ | **Arbitrary** | `outline-color: currentColor` | `outline-[#50d71e]` | `{ outlineColor: '#50d71e' }` | |
918
+ | **Variable** | `outline-color: var(--c)` | `outline-(--c)` | `{ outlineColor: '--c' }` | |
919
+
920
+ ## Outline Style
921
+
922
+ Controlling the style of an element's outline.
923
+
924
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
925
+ | :--------- | :----------------------------------------------------- | :---------------- | :--------------------------- | :-------------------------------- |
926
+ | **None** | `outline: 2px solid transparent; outline-offset: 2px;` | `outline-none` | `{ outline: 'none' }` | **Reset**: Resets outline styles. |
927
+ | **Solid** | `outline-style: solid` | `outline-solid` | `{ outlineStyle: 'solid' }` | |
928
+ | **Dashed** | `outline-style: dashed` | `outline-dashed` | `{ outlineStyle: 'dashed' }` | |
929
+ | **Dotted** | `outline-style: dotted` | `outline-dotted` | `{ outlineStyle: 'dotted' }` | |
930
+ | **Double** | `outline-style: double` | `outline-double` | `{ outlineStyle: 'double' }` | |
931
+ | **Hidden** | `outline-style: hidden` | `outline-hidden` | `{ outlineStyle: 'hidden' }` | |
932
+
933
+ ## Outline Offset
934
+
935
+ Controlling the offset of an element's outline.
936
+
937
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
938
+ | :------------ | :------------------------- | :------------------------------------------------------------------------------------------------- | :------------------------- | :--- |
939
+ | **Offset** | `outline-offset: 0px` | `outline-offset-0`, `outline-offset-1`, `outline-offset-2`, `outline-offset-4`, `outline-offset-8` | `{ outlineOffset: 0 }` | |
940
+ | **Arbitrary** | `outline-offset: 3px` | `outline-offset-[3px]` | `{ outlineOffset: '3px' }` | |
941
+ | **Variable** | `outline-offset: var(--o)` | `outline-offset-(--o)` | `{ outlineOffset: '--o' }` | |
942
+
943
+
944
+ # Effects
945
+
946
+ Controlling effects like shadows, opacity, and blends.
947
+
948
+ ## Box Shadow
949
+
950
+ Controlling the box shadow of an element.
951
+
952
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
953
+ | :--------------------- | :------------------------------------------ | :---------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------- |
954
+ | **Shadow** | `box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05)` | `shadow-2xs`, `shadow-xs`, `shadow-sm`, `shadow`, `shadow-md`, `shadow-lg`, `shadow-xl`, `shadow-2xl` | `{ shadow: '2xs' }`, `{ shadow: 'xs' }`, `{ shadow: 'sm' }`, `{ shadow: 'md' }`, `{ shadow: 'lg' }`, `{ shadow: 'xl' }`, `{ shadow: '2xl' }` | **v4.1**: `2xs`, `xs`. |
955
+ | **Inset Shadow** | `box-shadow: inset (etc)` | `inset-shadow-2xs`, `inset-shadow-xs`, `inset-shadow-sm`, `inset-shadow-md`, `inset-shadow-lg`, `inset-shadow-xl` | `{ insetShadow: '2xs' }` | **New in v4**: Distinct from `shadow-inner`. |
956
+ | **Ring** | `box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05)` | `ring`, `ring-1` | `{ ring: 1 }` | |
957
+ | **Inset Ring** | `box-shadow: inset (etc)` | `inset-ring`, `inset-ring-1` | `{ insetRing: 1 }` | |
958
+ | **None** | `box-shadow: 0 0 #0000` | `shadow-none` | `{ shadow: 'none' }` | |
959
+ | **Inset None** | `box-shadow: inset 0 0 #0000` | `inset-shadow-none` | `{ insetShadow: 'none' }` | |
960
+ | **Ring None** | `box-shadow: 0 0 #0000` | `ring-none` | `{ ring: 'none' }` | |
961
+ | **Color** | `box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05)` | `shadow-blue-500`, `inset-shadow-blue-500`, `ring-blue-500` | `{ shadowColor: 'blue-500' }` | |
962
+ | **Color + Opacity** | `--tw-shadow-color: (value) / 50%` | `shadow-blue-500/50` | `{ shadowColor: { color: 'blue-500', op: 50 } }` | |
963
+ | **CSS Var + Opacity** | `--tw-shadow-color: var(--c) / 50%` | `shadow-(--c)/50` | `{ shadowColor: { color: '--c', op: 50 } }` | CSS variables are auto-wrapped in `(...)`. |
964
+ | **Inset Sh Color** | `--tw-inset-shadow-color: (value)` | `inset-shadow-blue-500` | `{ insetShadowColor: 'blue-500' }` | Separate key for inset shadow color. |
965
+ | **Inset Sh Var** | `--tw-inset-shadow-color: var(--c)` | `inset-shadow-(color:--c)` | `{ insetShadowColor: '--c' }` | CSS variable with `color:` type hint. |
966
+ | **Inset Sh + Opacity** | `--tw-inset-shadow-color: (value) / 30%` | `inset-shadow-black/30` | `{ insetShadowColor: { color: 'black', op: 30 } }` | |
967
+ | **Inset Sh Var + Op** | `--tw-inset-shadow-color: var(--c) / 30%` | `inset-shadow-(--c)/30` | `{ insetShadowColor: { color: '--c', op: 30 } }` | CSS variables are auto-wrapped in `(...)`. |
968
+ | **Inherit/Custom** | `box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05)` | `shadow-inherit`, `shadow-current`, `shadow-black`, `shadow-white`, `shadow-transparent` | `{ shadowColor: 'inherit' }` etc. | |
969
+ | **Custom Var** | `--tw-shadow-color: var(--value)` | `shadow-(color:--my-color)` | `{ shadowColor: '--my-color' }` | **New in v4**: Sets variable explicitly. |
970
+ | **Arbitrary** | `box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05)` | `shadow-[0_35px_60px_-15px_rgba(0,0,0,0.3)]` | `{ shadow: '0 35px 60px -15px rgba(0,0,0,0.3)' }` | |
971
+ | **Var** | `box-shadow: var(--s)` | `shadow-(--s)` | `{ shadow: '--s' }` | **Sugar**: Auto-detects `--`. |
972
+
973
+ ## Text Shadow
974
+
975
+ Controlling the shadow of a text element.
976
+
977
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
978
+ | :------------ | :------------------- | :------------------------------------------------------------------ | :----------------------------------------------------- | :------------- |
979
+ | **Shadow** | `text-shadow: (etc)` | `text-shadow`, `text-shadow-sm`, `text-shadow-md`, `text-shadow-lg` | `{ textShadow: 'sm' }` | **New in v4**. |
980
+ | **None** | `text-shadow: none` | `text-shadow-none` | `{ textShadow: 'none' }` | |
981
+ | **Color** | `text-shadow: (etc)` | `text-shadow-blue-500` | `{ textShadowColor: 'blue-500' }` | |
982
+ | **Arbitrary** | `text-shadow: (etc)` | `text-shadow-[2px_2px_4px_var(--tw-shadow-color)]` | `{ textShadow: '2px 2px 4px var(--tw-shadow-color)' }` | |
983
+
984
+ ## Opacity
985
+
986
+ Controlling the opacity of an element.
987
+
988
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
989
+ | :------------ | :------------------ | :------------------------------- | :------------------------------------------------------- | :---------------------------------- |
990
+ | **Dynamic** | `opacity: 0 to 1` | `opacity-<number>` (any integer) | `{ opacity: 50 }`, `{ opacity: 88 }`, `{ opacity: 999 }` | v4: fully dynamic, no static scale. |
991
+ | **Arbitrary** | `opacity: .33` | `opacity-[.33]` | `{ opacity: '.33' }` | |
992
+ | **Var** | `opacity: var(--o)` | `opacity-(--o)` | `{ opacity: '--o' }` | |
993
+
994
+ ## Mix Blend Mode
995
+
996
+ Controlling how an element's content should blend with the background.
997
+
998
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
999
+ | :--------------- | :----------------------------- | :----------------------- | :----------------------------- | :--- |
1000
+ | **Normal** | `mix-blend-mode: normal` | `mix-blend-normal` | `{ mixBlend: 'normal' }` | |
1001
+ | **Multiply** | `mix-blend-mode: multiply` | `mix-blend-multiply` | `{ mixBlend: 'multiply' }` | |
1002
+ | **Screen** | `mix-blend-mode: screen` | `mix-blend-screen` | `{ mixBlend: 'screen' }` | |
1003
+ | **Overlay** | `mix-blend-mode: overlay` | `mix-blend-overlay` | `{ mixBlend: 'overlay' }` | |
1004
+ | **Darken** | `mix-blend-mode: darken` | `mix-blend-darken` | `{ mixBlend: 'darken' }` | |
1005
+ | **Lighten** | `mix-blend-mode: lighten` | `mix-blend-lighten` | `{ mixBlend: 'lighten' }` | |
1006
+ | **Color Dodge** | `mix-blend-mode: color-dodge` | `mix-blend-color-dodge` | `{ mixBlend: 'color-dodge' }` | |
1007
+ | **Color Burn** | `mix-blend-mode: color-burn` | `mix-blend-color-burn` | `{ mixBlend: 'color-burn' }` | |
1008
+ | **Hard Light** | `mix-blend-mode: hard-light` | `mix-blend-hard-light` | `{ mixBlend: 'hard-light' }` | |
1009
+ | **Soft Light** | `mix-blend-mode: soft-light` | `mix-blend-soft-light` | `{ mixBlend: 'soft-light' }` | |
1010
+ | **Difference** | `mix-blend-mode: difference` | `mix-blend-difference` | `{ mixBlend: 'difference' }` | |
1011
+ | **Exclusion** | `mix-blend-mode: exclusion` | `mix-blend-exclusion` | `{ mixBlend: 'exclusion' }` | |
1012
+ | **Hue** | `mix-blend-mode: hue` | `mix-blend-hue` | `{ mixBlend: 'hue' }` | |
1013
+ | **Saturation** | `mix-blend-mode: saturation` | `mix-blend-saturation` | `{ mixBlend: 'saturation' }` | |
1014
+ | **Color** | `mix-blend-mode: color` | `mix-blend-color` | `{ mixBlend: 'color' }` | |
1015
+ | **Luminosity** | `mix-blend-mode: luminosity` | `mix-blend-luminosity` | `{ mixBlend: 'luminosity' }` | |
1016
+ | **Plus Lighter** | `mix-blend-mode: plus-lighter` | `mix-blend-plus-lighter` | `{ mixBlend: 'plus-lighter' }` | |
1017
+ | **Plus Darker** | `mix-blend-mode: plus-darker` | `mix-blend-plus-darker` | `{ mixBlend: 'plus-darker' }` | |
1018
+
1019
+ ## Background Blend Mode
1020
+
1021
+ Controlling how an element's background image should blend with its background color.
1022
+
1023
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1024
+ | :-------- | :----------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------- | :--- |
1025
+ | **Modes** | `background-blend-mode: (etc)` | `bg-blend-normal`, `bg-blend-multiply`, `bg-blend-screen`, `bg-blend-overlay`, `bg-blend-darken`, `bg-blend-lighten`, `bg-blend-color-dodge`, `bg-blend-color-burn`, `bg-blend-hard-light`, `bg-blend-soft-light`, `bg-blend-difference`, `bg-blend-exclusion`, `bg-blend-hue`, `bg-blend-saturation`, `bg-blend-color`, `bg-blend-luminosity` | `{ bgBlend: 'multiply' }` etc. | |
1026
+
1027
+ ## Masking (v4.1+)
1028
+
1029
+ Controlling the masking of an element with images, gradients, and CSS properties.
1030
+
1031
+ > **Source:** [Tailwind CSS v4.1 Documentation](https://tailwindcss.com/docs/mask-image)
1032
+
1033
+ ### mask-image: Gradient Masks
1034
+
1035
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1036
+ | :------------- | :-------------------------------------------- | :---------------- | :------------------------ | :------------------------- |
1037
+ | **None** | `mask-image: none` | `mask-none` | `{ mask: 'none' }` | |
1038
+ | **Linear** | `mask-image: linear-gradient(45deg, ...)` | `mask-linear-45` | `{ mask: 'linear-45' }` | Angle in degrees. |
1039
+ | **Linear Neg** | `mask-image: linear-gradient(-45deg, ...)` | `-mask-linear-45` | `{ mask: '-linear-45' }` | Negative angle prefix `-`. |
1040
+ | **Radial** | `mask-image: radial-gradient(...)` | `mask-radial` | `{ mask: 'radial' }` | |
1041
+ | **Conic** | `mask-image: conic-gradient(from 90deg, ...)` | `mask-conic-90` | `{ mask: 'conic-90' }` | |
1042
+
1043
+ ### mask-image: Direction Keywords
1044
+
1045
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1046
+ | :------------------ | :-------------------------------------------------- | :------------------ | :------------------------- | :--- |
1047
+ | **To Top** | `mask-image: linear-gradient(to top, ...)` | `mask-linear-to-t` | `{ mask: 'linear-to-t' }` | |
1048
+ | **To Top Right** | `mask-image: linear-gradient(to top right, ...)` | `mask-linear-to-tr` | `{ mask: 'linear-to-tr' }` | |
1049
+ | **To Right** | `mask-image: linear-gradient(to right, ...)` | `mask-linear-to-r` | `{ mask: 'linear-to-r' }` | |
1050
+ | **To Bottom Right** | `mask-image: linear-gradient(to bottom right, ...)` | `mask-linear-to-br` | `{ mask: 'linear-to-br' }` | |
1051
+ | **To Bottom** | `mask-image: linear-gradient(to bottom, ...)` | `mask-linear-to-b` | `{ mask: 'linear-to-b' }` | |
1052
+ | **To Bottom Left** | `mask-image: linear-gradient(to bottom left, ...)` | `mask-linear-to-bl` | `{ mask: 'linear-to-bl' }` | |
1053
+ | **To Left** | `mask-image: linear-gradient(to left, ...)` | `mask-linear-to-l` | `{ mask: 'linear-to-l' }` | |
1054
+ | **To Top Left** | `mask-image: linear-gradient(to top left, ...)` | `mask-linear-to-tl` | `{ mask: 'linear-to-tl' }` | |
1055
+
1056
+ ### mask-image: Shape Modifiers (Radial)
1057
+
1058
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1059
+ | :---------- | :-------------------------------- | :---------------- | :------------------------- | :-------------------- |
1060
+ | **Circle** | `--tw-mask-radial-shape: circle` | `mask-circle` | `{ maskShape: 'circle' }` | For radial gradients. |
1061
+ | **Ellipse** | `--tw-mask-radial-shape: ellipse` | `mask-ellipse` | `{ maskShape: 'ellipse' }` | Default shape. |
1062
+
1063
+ ### mask-image: Arbitrary Values
1064
+
1065
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1066
+ | :----------- | :--------------------------------- | :---------------------------- | :--------------------------------- | :----------------- |
1067
+ | **URL** | `mask-image: url(/img.png)` | `mask-[url(/img.png)]` | `{ mask: "url('/img.png')" }` | Arbitrary syntax. |
1068
+ | **Gradient** | `mask-image: linear-gradient(...)` | `mask-[linear-gradient(...)]` | `{ mask: 'linear-gradient(...)' }` | Spaces become `_`. |
1069
+ | **Variable** | `mask-image: var(--my-mask)` | `mask-(--my-mask)` | `{ mask: '--my-mask' }` | CSS variable. |
1070
+
1071
+ ### mask-size
1072
+
1073
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1074
+ | :------------ | :-------------------- | :---------------- | :------------------------ | :--------------- |
1075
+ | **Auto** | `mask-size: auto` | `mask-auto` | `{ maskSize: 'auto' }` | |
1076
+ | **Cover** | `mask-size: cover` | `mask-cover` | `{ maskSize: 'cover' }` | |
1077
+ | **Contain** | `mask-size: contain` | `mask-contain` | `{ maskSize: 'contain' }` | |
1078
+ | **Arbitrary** | `mask-size: 50%` | `mask-size-[50%]` | `{ maskSize: '50%' }` | Arbitrary value. |
1079
+ | **Variable** | `mask-size: var(--s)` | `mask-size-(--s)` | `{ maskSize: '--s' }` | CSS variable. |
1080
+
1081
+ ### mask-position
1082
+
1083
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1084
+ | :--------------- | :------------------------------- | :-------------------------------- | :------------------------------- | :----------------- |
1085
+ | **Center** | `mask-position: center` | `mask-center` | `{ maskPos: 'center' }` | |
1086
+ | **Top** | `mask-position: top` | `mask-top` | `{ maskPos: 'top' }` | |
1087
+ | **Bottom** | `mask-position: bottom` | `mask-bottom` | `{ maskPos: 'bottom' }` | |
1088
+ | **Left** | `mask-position: left` | `mask-left` | `{ maskPos: 'left' }` | |
1089
+ | **Right** | `mask-position: right` | `mask-right` | `{ maskPos: 'right' }` | |
1090
+ | **Top Left** | `mask-position: top left` | `mask-top-left` | `{ maskPos: 'top-left' }` | |
1091
+ | **Top Right** | `mask-position: top right` | `mask-top-right` | `{ maskPos: 'top-right' }` | |
1092
+ | **Bottom Left** | `mask-position: bottom left` | `mask-bottom-left` | `{ maskPos: 'bottom-left' }` | |
1093
+ | **Bottom Right** | `mask-position: bottom right` | `mask-bottom-right` | `{ maskPos: 'bottom-right' }` | |
1094
+ | **Arbitrary** | `mask-position: center top 1rem` | `mask-position-[center_top_1rem]` | `{ maskPos: 'center_top_1rem' }` | Spaces become `_`. |
1095
+
1096
+ ### mask-repeat
1097
+
1098
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1099
+ | :------------ | :----------------------- | :------------------ | :---------------------------- | :------- |
1100
+ | **Repeat** | `mask-repeat: repeat` | `mask-repeat` | `{ maskRepeat: 'repeat' }` | Default. |
1101
+ | **No Repeat** | `mask-repeat: no-repeat` | `mask-no-repeat` | `{ maskRepeat: 'no-repeat' }` | |
1102
+ | **Repeat X** | `mask-repeat: repeat-x` | `mask-repeat-x` | `{ maskRepeat: 'repeat-x' }` | |
1103
+ | **Repeat Y** | `mask-repeat: repeat-y` | `mask-repeat-y` | `{ maskRepeat: 'repeat-y' }` | |
1104
+ | **Space** | `mask-repeat: space` | `mask-repeat-space` | `{ maskRepeat: 'space' }` | |
1105
+ | **Round** | `mask-repeat: round` | `mask-repeat-round` | `{ maskRepeat: 'round' }` | |
1106
+
1107
+ ### mask-origin
1108
+
1109
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1110
+ | :-------------- | :------------------------- | :-------------------- | :-------------------------- | :-------- |
1111
+ | **Border Box** | `mask-origin: border-box` | `mask-origin-border` | `{ maskOrigin: 'border' }` | |
1112
+ | **Padding Box** | `mask-origin: padding-box` | `mask-origin-padding` | `{ maskOrigin: 'padding' }` | |
1113
+ | **Content Box** | `mask-origin: content-box` | `mask-origin-content` | `{ maskOrigin: 'content' }` | |
1114
+ | **Fill Box** | `mask-origin: fill-box` | `mask-origin-fill` | `{ maskOrigin: 'fill' }` | SVG only. |
1115
+ | **Stroke Box** | `mask-origin: stroke-box` | `mask-origin-stroke` | `{ maskOrigin: 'stroke' }` | SVG only. |
1116
+ | **View Box** | `mask-origin: view-box` | `mask-origin-view` | `{ maskOrigin: 'view' }` | SVG only. |
1117
+
1118
+ ### mask-clip
1119
+
1120
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1121
+ | :-------------- | :----------------------- | :------------------ | :------------------------ | :-------- |
1122
+ | **Border Box** | `mask-clip: border-box` | `mask-clip-border` | `{ maskClip: 'border' }` | |
1123
+ | **Padding Box** | `mask-clip: padding-box` | `mask-clip-padding` | `{ maskClip: 'padding' }` | |
1124
+ | **Content Box** | `mask-clip: content-box` | `mask-clip-content` | `{ maskClip: 'content' }` | |
1125
+ | **Fill Box** | `mask-clip: fill-box` | `mask-clip-fill` | `{ maskClip: 'fill' }` | SVG only. |
1126
+ | **Stroke Box** | `mask-clip: stroke-box` | `mask-clip-stroke` | `{ maskClip: 'stroke' }` | SVG only. |
1127
+ | **View Box** | `mask-clip: view-box` | `mask-clip-view` | `{ maskClip: 'view' }` | SVG only. |
1128
+ | **No Clip** | `mask-clip: no-clip` | `mask-no-clip` | `{ maskClip: 'no-clip' }` | |
1129
+
1130
+ ### mask-mode
1131
+
1132
+ Controls how element masks are interpreted.
1133
+
1134
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1135
+ | :--------------- | :------------------------ | :---------------- | :----------------------------- | :------------------ |
1136
+ | **Alpha** | `mask-mode: alpha` | `mask-alpha` | `{ maskMode: 'alpha' }` | Uses alpha channel. |
1137
+ | **Luminance** | `mask-mode: luminance` | `mask-luminance` | `{ maskMode: 'luminance' }` | Uses luminance. |
1138
+ | **Match Source** | `mask-mode: match-source` | `mask-match` | `{ maskMode: 'match-source' }` | Auto-detect. |
1139
+
1140
+ ### mask-type
1141
+
1142
+ Controls how SVG masks are interpreted. **Note:** Uses `mask-type-` prefix (different from `mask-mode`).
1143
+
1144
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1145
+ | :------------ | :--------------------- | :-------------------- | :-------------------------- | :---------------- |
1146
+ | **Alpha** | `mask-type: alpha` | `mask-type-alpha` | `{ maskType: 'alpha' }` | For SVG `<mask>`. |
1147
+ | **Luminance** | `mask-type: luminance` | `mask-type-luminance` | `{ maskType: 'luminance' }` | For SVG `<mask>`. |
1148
+
1149
+ ### mask-composite
1150
+
1151
+ Controls how multiple masks are combined.
1152
+
1153
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1154
+ | :------------ | :-------------------------- | :---------------- | :------------------------------- | :-------------- |
1155
+ | **Add** | `mask-composite: add` | `mask-add` | `{ maskComposite: 'add' }` | Union of masks. |
1156
+ | **Subtract** | `mask-composite: subtract` | `mask-subtract` | `{ maskComposite: 'subtract' }` | Difference. |
1157
+ | **Intersect** | `mask-composite: intersect` | `mask-intersect` | `{ maskComposite: 'intersect' }` | Intersection. |
1158
+ | **Exclude** | `mask-composite: exclude` | `mask-exclude` | `{ maskComposite: 'exclude' }` | XOR. |
1159
+
1160
+ ### Compiler Mappings
1161
+
1162
+ ```typescript
1163
+ // mask-mode: direct mapping (no prefix)
1164
+ {
1165
+ maskMode: "alpha";
1166
+ } // → mask-alpha
1167
+ {
1168
+ maskMode: "luminance";
1169
+ } // → mask-luminance
1170
+ {
1171
+ maskMode: "match-source";
1172
+ } // → mask-match
1173
+
1174
+ // mask-type: uses mask-type- prefix
1175
+ {
1176
+ maskType: "alpha";
1177
+ } // → mask-type-alpha
1178
+ {
1179
+ maskType: "luminance";
1180
+ } // → mask-type-luminance
1181
+
1182
+ // mask-composite: direct mapping (no prefix)
1183
+ {
1184
+ maskComposite: "add";
1185
+ } // → mask-add
1186
+ {
1187
+ maskComposite: "subtract";
1188
+ } // → mask-subtract
1189
+
1190
+ // mask-size: direct mapping
1191
+ {
1192
+ maskSize: "cover";
1193
+ } // → mask-cover
1194
+ {
1195
+ maskSize: "contain";
1196
+ } // → mask-contain
1197
+ {
1198
+ maskSize: "auto";
1199
+ } // → mask-auto
1200
+
1201
+ // mask-position: mask- prefix
1202
+ {
1203
+ maskPos: "center";
1204
+ } // → mask-center
1205
+ {
1206
+ maskPos: "top-left";
1207
+ } // → mask-top-left
1208
+
1209
+ // mask-repeat: special handling
1210
+ {
1211
+ maskRepeat: "repeat";
1212
+ } // → mask-repeat (not mask-repeat-repeat)
1213
+ {
1214
+ maskRepeat: "no-repeat";
1215
+ } // → mask-no-repeat
1216
+ {
1217
+ maskRepeat: "repeat-x";
1218
+ } // → mask-repeat-x
1219
+
1220
+ // mask-origin/clip: uses -origin-/-clip- infix
1221
+ {
1222
+ maskOrigin: "border";
1223
+ } // → mask-origin-border
1224
+ {
1225
+ maskClip: "content";
1226
+ } // → mask-clip-content
1227
+
1228
+ // mask-image: arbitrary values are auto-wrapped by compiler — no brackets needed in sz
1229
+ {
1230
+ mask: "linear-gradient(...)";
1231
+ } // → mask-[linear-gradient(...)]
1232
+ {
1233
+ mask: "url(/img.png)";
1234
+ } // → mask-[url(/img.png)]
1235
+ ```
1236
+
1237
+ ### Key Differences
1238
+
1239
+ | Property | Format | Example |
1240
+ | ---------------- | ------------------------------------- | ------------------------------ |
1241
+ | `mask-mode` | `mask-{value}` | `mask-alpha` |
1242
+ | `mask-type` | `mask-type-{value}` | `mask-type-alpha` |
1243
+ | `mask-composite` | `mask-{value}` | `mask-add` |
1244
+ | `mask-size` | `mask-{value}` | `mask-cover` |
1245
+ | `mask-position` | `mask-{value}` | `mask-center` |
1246
+ | `mask-repeat` | `mask-{value}` / `mask-repeat-{x\|y}` | `mask-repeat`, `mask-repeat-x` |
1247
+ | `mask-origin` | `mask-origin-{value}` | `mask-origin-border` |
1248
+ | `mask-clip` | `mask-clip-{value}` | `mask-clip-content` |
1249
+
1250
+ ### Mask Gradient Color Stops (v4.1)
1251
+
1252
+ Control the color stops used in mask gradient functions.
1253
+
1254
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1255
+ | :----------- | :-------------------- | :------------------ | :------------------------ | :--- |
1256
+ | **From** | mask gradient start | `mask-from-<color>` | `{ maskFrom: '<color>' }` | |
1257
+ | **Via** | mask gradient middle | `mask-via-<color>` | `{ maskVia: '<color>' }` | |
1258
+ | **To** | mask gradient end | `mask-to-<color>` | `{ maskTo: '<color>' }` | |
1259
+ | **Variable** | `mask-from: var(--c)` | `mask-from-(--c)` | `{ maskFrom: '--c' }` | |
1260
+
1261
+
1262
+ # Filters
1263
+
1264
+ Applying graphical effects like blur or color shifts.
1265
+
1266
+ ## Filter
1267
+
1268
+ Utilities for controlling the overall filter property.
1269
+
1270
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1271
+ | :---------------- | :----------------------- | :--------------------- | :--------------------------- | :--------------------------------- |
1272
+ | **Filter None** | `filter: none;` | `filter-none` | `{ filter: 'none' }` | |
1273
+ | **Filter Var** | `filter: var(--c);` | `filter-(--c)` | `{ filter: '--c' }` | |
1274
+ | **Filter Arb** | `filter: blur(5px);` | `filter-[blur(5px)]` | `{ filter: 'blur(5px)' }` | |
1275
+ | **Backdrop None** | `backdrop-filter: none;` | `backdrop-filter-none` | `{ backdropFilter: 'none' }` | |
1276
+ | **Defaults** | `filter: blur(8px)` | `blur` | `{ blur: true }` | **Boolean**: Sets default effects. |
1277
+
1278
+ | Filter Item | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1279
+ | :------------------------ | :---------------------------------------------------- | :--------------------------------------------------------------------------- | :----------------------------------------------------------- | :---------------------------- |
1280
+ | **Blur Scale** | `filter: blur(var(--blur-xs))` to `3xl` | `blur-xs` to `blur-3xl` | `{ blur: 'xs' }` to `{ blur: '3xl' }` | |
1281
+ | **Blur None** | `filter: blur(0);` | `blur-none` | `{ blur: 'none' }` | |
1282
+ | **Blur Var** | `filter: blur(var(--c))` | `blur-(--c)` | `{ blur: '--c' }` | |
1283
+ | **Blur Arb** | `filter: var(--c)` | `blur-[4px]` | `{ blur: '4px' }` | |
1284
+ | **Brightness** | `filter: brightness(0%)` to `200%` | `brightness-0` to `brightness-200` | `{ brightness: 0 }` to `{ brightness: 200 }` | |
1285
+ | **Brightness Var** | `filter: brightness(var(--c))` | `brightness-(--c)` | `{ brightness: '--c' }` | |
1286
+ | **Brightness Arb** | `filter: brightness(1.25)` | `brightness-[1.25]` | `{ brightness: '1.25' }` | |
1287
+ | **Contrast** | `filter: contrast(0%)` to `200%` | `contrast-0` to `contrast-200` | `{ contrast: 0 }` to `{ contrast: 200 }` | |
1288
+ | **Contrast Var** | `filter: contrast(var(--c))` | `contrast-(--c)` | `{ contrast: '--c' }` | |
1289
+ | **Contrast Arb** | `filter: contrast(1.5)` | `contrast-[1.5]` | `{ contrast: '1.5' }` | |
1290
+ | **Drop Shadow** | `filter: drop-shadow(var(--drop-shadow-xs))` to `2xl` | `drop-shadow-xs` to `drop-shadow-2xl` | `{ dropShadow: 'xs' }` to `{ dropShadow: '2xl' }` | |
1291
+ | **Drop Shadow None** | `filter: drop-shadow(0 0 #0000)` | `drop-shadow-none` | `{ dropShadow: 'none' }` | |
1292
+ | **Drop Shadow Var** | `filter: drop-shadow(var(--c))` | `drop-shadow-(--c)` | `{ dropShadow: '--c' }` | |
1293
+ | **Drop Shadow Arb** | `filter: drop-shadow(0 25px 25px rgb(0 0 0/0.15))` | `drop-shadow-[0_25px_25px_rgb(0_0_0/0.15)]` | `{ dropShadow: '0 25px 25px rgb(0 0 0/0.15)' }` | Spaces auto-encoded to `_`. |
1294
+ | **Drop Shadow + Variant** | (hover state) | `hover:drop-shadow-[0_0_15px_rgba(45,213,151,0.5)]` | `{ hover: { dropShadow: '0 0 15px rgba(45,213,151,0.5)' } }` | Works in any variant context. |
1295
+ | **Drop Shadow Color** | `--tw-drop-shadow-color: (etc)` | `drop-shadow-slate-500`, `drop-shadow-red-500`, `drop-shadow-blue-500`, etc. | `{ dropShadowColor: 'red-500' }` | Full palette support. |
1296
+ | **Drop Shadow Var Col** | `--tw-drop-shadow-color: var(--c)` | `drop-shadow-(color:--c)` | `{ dropShadowColor: '--c' }` | **New in v4**. |
1297
+ | **Grayscale** | `filter: grayscale(100%)` | `grayscale` | `{ grayscale: true }` | |
1298
+ | **Grayscale Scale** | `filter: grayscale(0%)` to `100%` | `grayscale-0` to `grayscale-100` | `{ grayscale: 0 }` to `{ grayscale: 100 }` | |
1299
+ | **Grayscale Var** | `filter: grayscale(var(--c))` | `grayscale-(--c)` | `{ grayscale: '--c' }` | |
1300
+ | **Grayscale Arb** | `filter: grayscale(50%)` | `grayscale-[50%]` | `{ grayscale: '50%' }` | |
1301
+ | **Hue Rotate** | `filter: hue-rotate(0deg)` to `180deg` | `hue-rotate-0` to `hue-rotate-180` | `{ hueRotate: 0 }` to `{ hueRotate: 180 }` | |
1302
+ | **Hue Rotate Neg** | `filter: hue-rotate(calc(ndeg * -1))` | `-hue-rotate-15` | `{ hueRotate: -15 }` | |
1303
+ | **Hue Rotate Var** | `filter: hue-rotate(var(--c))` | `hue-rotate-(--c)` | `{ hueRotate: '--c' }` | |
1304
+ | **Hue Rotate Arb** | `filter: hue-rotate(90deg)` | `hue-rotate-[90deg]` | `{ hueRotate: '90deg' }` | |
1305
+ | **Invert** | `filter: invert(100%)` | `invert` | `{ invert: true }` | |
1306
+ | **Invert Scale** | `filter: invert(0%)` to `100%` | `invert-0` to `invert-100` | `{ invert: 0 }` to `{ invert: 100 }` | |
1307
+ | **Invert Var** | `filter: invert(var(--c))` | `invert-(--c)` | `{ invert: '--c' }` | |
1308
+ | **Invert Arb** | `filter: invert(25%)` | `invert-[25%]` | `{ invert: '25%' }` | |
1309
+ | **Saturate** | `filter: saturate(0%)` to `200%` | `saturate-0` to `saturate-200` | `{ saturate: 0 }` to `{ saturate: 200 }` | |
1310
+ | **Saturate Var** | `filter: saturate(var(--c))` | `saturate-(--c)` | `{ saturate: '--c' }` | |
1311
+ | **Saturate Arb** | `filter: saturate(1.5)` | `saturate-[1.5]` | `{ saturate: '1.5' }` | |
1312
+ | **Sepia** | `filter: sepia(100%)` | `sepia` | `{ sepia: true }` | |
1313
+ | **Sepia Scale** | `filter: sepia(0%)` to `100%` | `sepia-0` to `sepia-100` | `{ sepia: 0 }` to `{ sepia: 100 }` | |
1314
+ | **Sepia Var** | `filter: sepia(var(--c))` | `sepia-(--c)` | `{ sepia: '--c' }` | |
1315
+ | **Sepia Arb** | `filter: sepia(50%)` | `sepia-[50%]` | `{ sepia: '50%' }` | |
1316
+
1317
+ ## Backdrop Filter
1318
+
1319
+ Utilities for controlling the backdrop-filter property.
1320
+
1321
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1322
+ | :------------ | :---------------------------- | :---------------------------- | :-------------------------------- | :--- |
1323
+ | **None** | `backdrop-filter: none;` | `backdrop-filter-none` | `{ backdropFilter: 'none' }` | |
1324
+ | **Variable** | `backdrop-filter: var(--c);` | `backdrop-filter-(--c)` | `{ backdropFilter: '--c' }` | |
1325
+ | **Arbitrary** | `backdrop-filter: blur(5px);` | `backdrop-filter-[blur(5px)]` | `{ backdropFilter: 'blur(5px)' }` | |
1326
+
1327
+ | Filter Item | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1328
+ | :------------------ | :---------------------------------------------- | :------------------------------- | :----------------------------------- | :--- |
1329
+ | **Blur Scale** | `backdrop-filter: blur(var(--b))` | `backdrop-blur-xs` to `3xl` | `{ backdropBlur: 'xs' }` to `3xl` | |
1330
+ | **Blur None** | `backdrop-filter: blur(0);` | `backdrop-blur-none` | `{ backdropBlur: 'none' }` | |
1331
+ | **Blur Var** | `backdrop-filter: blur(var(--c))` | `backdrop-blur-(--c)` | `{ backdropBlur: '--c' }` | |
1332
+ | **Blur Arb** | `backdrop-filter: var(--c)` | `backdrop-blur-[4px]` | `{ backdropBlur: '4px' }` | |
1333
+ | **Brightness** | `backdrop-filter: brightness(0%)` to `200%` | `backdrop-brightness-0` to `200` | `{ backdropBrightness: 0 }` to `200` | |
1334
+ | **Brightness Var** | `backdrop-filter: var(--c)` | `backdrop-brightness-(--c)` | `{ backdropBrightness: '--c' }` | |
1335
+ | **Brightness Arb** | `backdrop-filter: brightness(1.25)` | `backdrop-brightness-[1.25]` | `{ backdropBrightness: '1.25' }` | |
1336
+ | **Contrast** | `backdrop-filter: contrast(0%)` to `200%` | `backdrop-contrast-0` to `200` | `{ backdropContrast: 0 }` to `200` | |
1337
+ | **Contrast Var** | `backdrop-filter: var(--c)` | `backdrop-contrast-(--c)` | `{ backdropContrast: '--c' }` | |
1338
+ | **Contrast Arb** | `backdrop-filter: contrast(1.5)` | `backdrop-contrast-[1.5]` | `{ backdropContrast: '1.5' }` | |
1339
+ | **Grayscale** | `backdrop-filter: grayscale(100%)` | `backdrop-grayscale` | `{ backdropGrayscale: true }` | |
1340
+ | **Grayscale Scale** | `backdrop-filter: grayscale(0%)` to `100%` | `backdrop-grayscale-0` to `100` | `{ backdropGrayscale: 0 }` to `100` | |
1341
+ | **Grayscale Var** | `backdrop-filter: var(--c)` | `backdrop-grayscale-(--c)` | `{ backdropGrayscale: '--c' }` | |
1342
+ | **Grayscale Arb** | `backdrop-filter: grayscale(50%)` | `backdrop-grayscale-[50%]` | `{ backdropGrayscale: '50%' }` | |
1343
+ | **Hue Rotate** | `backdrop-filter: hue-rotate(0deg)` to `180deg` | `backdrop-hue-rotate-0` to `180` | `{ backdropHueRotate: 0 }` to `180` | |
1344
+ | **Hue Rotate Neg** | `backdrop-filter: var(--c)` | `-backdrop-hue-rotate-15` | `{ backdropHueRotate: -15 }` | |
1345
+ | **Hue Rotate Var** | `backdrop-filter: var(--c)` | `backdrop-hue-rotate-(--c)` | `{ backdropHueRotate: '--c' }` | |
1346
+ | **Hue Rotate Arb** | `backdrop-filter: hue-rotate(90deg)` | `backdrop-hue-rotate-[90deg]` | `{ backdropHueRotate: '90deg' }` | |
1347
+ | **Invert** | `backdrop-filter: invert(100%)` | `backdrop-invert` | `{ backdropInvert: true }` | |
1348
+ | **Invert Scale** | `backdrop-filter: invert(0%)` to `100%` | `backdrop-invert-0` to `100` | `{ backdropInvert: 0 }` to `100` | |
1349
+ | **Invert Var** | `backdrop-filter: var(--c)` | `backdrop-invert-(--c)` | `{ backdropInvert: '--c' }` | |
1350
+ | **Invert Arb** | `backdrop-filter: invert(25%)` | `backdrop-invert-[25%]` | `{ backdropInvert: '25%' }` | |
1351
+ | **Opacity** | `backdrop-filter: opacity(0%)` to `100%` | `backdrop-opacity-0` to `100` | `{ backdropOpacity: 0 }` to `100` | |
1352
+ | **Opacity Var** | `backdrop-filter: var(--c)` | `backdrop-opacity-(--c)` | `{ backdropOpacity: '--c' }` | |
1353
+ | **Opacity Arb** | `backdrop-filter: opacity(75%)` | `backdrop-opacity-[75%]` | `{ backdropOpacity: '75%' }` | |
1354
+ | **Saturate** | `backdrop-filter: saturate(0%)` to `200%` | `backdrop-saturate-0` to `200` | `{ backdropSaturate: 0 }` to `200` | |
1355
+ | **Saturate Var** | `backdrop-filter: var(--c)` | `backdrop-saturate-(--c)` | `{ backdropSaturate: '--c' }` | |
1356
+ | **Saturate Arb** | `backdrop-filter: saturate(1.5)` | `backdrop-saturate-[1.5]` | `{ backdropSaturate: '1.5' }` | |
1357
+ | **Sepia** | `backdrop-filter: sepia(100%)` | `backdrop-sepia` | `{ backdropSepia: true }` | |
1358
+ | **Sepia Scale** | `backdrop-filter: sepia(0%)` to `100%` | `backdrop-sepia-0` to `100` | `{ backdropSepia: 0 }` to `100` | |
1359
+ | **Sepia Var** | `backdrop-filter: var(--c)` | `backdrop-sepia-(--c)` | `{ backdropSepia: '--c' }` | |
1360
+ | **Sepia Arb** | `backdrop-filter: sepia(50%)` | `backdrop-sepia-[50%]` | `{ backdropSepia: '50%' }` | |
1361
+
1362
+
1363
+ # Flexbox & Grid
1364
+
1365
+ Controlling flex and grid layouts.
1366
+
1367
+ ## Flex Basis
1368
+
1369
+ Controlling initial size of flex items.
1370
+
1371
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1372
+ | :------------------ | :--------------------------------------------- | :----------------------------- | :------------------------ | :------------------------------------------------------------------------------- |
1373
+ | **Auto** | `flex-basis: auto` | `basis-auto` | `{ basis: 'auto' }` | |
1374
+ | **Full** | `flex-basis: 100%` | `basis-full` | `{ basis: 'full' }` | |
1375
+ | **Spacing Scale** | `flex-basis: calc(var(--spacing) * <number>);` | `basis-<number>` (any integer) | `{ basis: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
1376
+ | **Fraction** | `flex-basis: calc(<fraction> * 100%)` | `basis-<fraction>` | `{ basis: '<fraction>' }` | v4: accept any integer/integer fraction (string) bare. |
1377
+ | **Container (3XS)** | `flex-basis: 16rem` | `basis-3xs` | `{ basis: '3xs' }` | |
1378
+ | **Container (2XS)** | `flex-basis: 18rem` | `basis-2xs` | `{ basis: '2xs' }` | |
1379
+ | **Container (XS)** | `flex-basis: 20rem` | `basis-xs` | `{ basis: 'xs' }` | |
1380
+ | **Container (SM)** | `flex-basis: 24rem` | `basis-sm` | `{ basis: 'sm' }` | |
1381
+ | **Container (MD)** | `flex-basis: 28rem` | `basis-md` | `{ basis: 'md' }` | |
1382
+ | **Container (LG)** | `flex-basis: 32rem` | `basis-lg` | `{ basis: 'lg' }` | |
1383
+ | **Container (XL)** | `flex-basis: 36rem` | `basis-xl` | `{ basis: 'xl' }` | |
1384
+ | **Container (2XL)** | `flex-basis: 42rem` | `basis-2xl` | `{ basis: '2xl' }` | |
1385
+ | **Container (3XL)** | `flex-basis: 48rem` | `basis-3xl` | `{ basis: '3xl' }` | |
1386
+ | **Container (4XL)** | `flex-basis: 56rem` | `basis-4xl` | `{ basis: '4xl' }` | |
1387
+ | **Container (5XL)** | `flex-basis: 64rem` | `basis-5xl` | `{ basis: '5xl' }` | |
1388
+ | **Container (6XL)** | `flex-basis: 72rem` | `basis-6xl` | `{ basis: '6xl' }` | |
1389
+ | **Container (7XL)** | `flex-basis: 80rem` | `basis-7xl` | `{ basis: '7xl' }` | |
1390
+ | **Zero** | `flex-basis: 0px` | `basis-0` | `{ basis: 0 }` | |
1391
+ | **Px** | `flex-basis: 1px` | `basis-px` | `{ basis: 'px' }` | |
1392
+ | **Arbitrary** | `flex-basis: 14.28%` | `basis-[14.28%]` | `{ basis: '14.28%' }` | |
1393
+ | **Arbitrary** | `flex-basis: 2.5/4` | `basis-[2.5/4]` | `{ basis: '2.5/4' }` | |
1394
+ | **CSS Variable** | `flex-basis: var(--basis)` | `basis-(--basis)` | `{ basis: '--basis' }` | **Sugar**: Auto-detects `--`. |
1395
+
1396
+ ## Flex Direction
1397
+
1398
+ Controlling direction of flex items.
1399
+
1400
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) |
1401
+ | :----------------- | :------------------------------- | :----------------- | :--------------------------- |
1402
+ | **Row** | `flex-direction: row` | `flex-row` | `{ flexDir: 'row' }` |
1403
+ | **Row Reverse** | `flex-direction: row-reverse` | `flex-row-reverse` | `{ flexDir: 'row-reverse' }` |
1404
+ | **Column** | `flex-direction: column` | `flex-col` | `{ flexDir: 'col' }` |
1405
+ | **Column Reverse** | `flex-direction: column-reverse` | `flex-col-reverse` | `{ flexDir: 'col-reverse' }` |
1406
+
1407
+ ## Flex Wrap
1408
+
1409
+ Controlling wrapping of flex items.
1410
+
1411
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) |
1412
+ | :--------------- | :------------------------ | :------------------ | :----------------------------- |
1413
+ | **Wrap** | `flex-wrap: wrap` | `flex-wrap` | `{ flexWrap: 'wrap' }` |
1414
+ | **Wrap Reverse** | `flex-wrap: wrap-reverse` | `flex-wrap-reverse` | `{ flexWrap: 'wrap-reverse' }` |
1415
+ | **No Wrap** | `flex-wrap: nowrap` | `flex-nowrap` | `{ flexWrap: 'nowrap' }` |
1416
+
1417
+ ## Flex Grow
1418
+
1419
+ Controlling flex item growth.
1420
+
1421
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | Note |
1422
+ | :--------------- | :---------------------------- | :------------------------ | :----------------------------- | :---------------------------------------------------------- |
1423
+ | **Grow** | `flex-grow: 1` | `grow` | `{ grow: true }` | |
1424
+ | **Grow 0** | `flex-grow: <number>` | `grow-<number>` | `{ grow: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
1425
+ | **Arbitrary** | `flex-grow: 2.5` | `grow-[2.5]` | `{ grow: 2.5 }` | decimal |
1426
+ | **Arbitrary** | `flex-grow: calc(1rem + 2px)` | `grow-[calc(1rem_+_2px)]` | `{ grow: 'calc(1rem + 2px)' }` | string |
1427
+ | **CSS Variable** | `flex-grow: var(--grow)` | `grow-(--grow)` | `{ grow: '--grow' }` | **Sugar**: Auto-detects `--`. |
1428
+
1429
+ ## Flex Shrink
1430
+
1431
+ Controlling flex item shrinking.
1432
+
1433
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | Note |
1434
+ | :--------------- | :------------------------------ | :-------------------------- | :------------------------------- | :---------------------------------------------------------- |
1435
+ | **Shrink** | `flex-shrink: 1` | `shrink` | `{ shrink: true }` | |
1436
+ | **Shrink 0** | `flex-shrink: <number>` | `shrink-<number>` | `{ shrink: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
1437
+ | **Arbitrary** | `flex-shrink: 2.5` | `shrink-[2.5]` | `{ shrink: 2.5 }` | decimal |
1438
+ | **Arbitrary** | `flex-shrink: calc(1rem + 2px)` | `shrink-[calc(1rem_+_2px)]` | `{ shrink: 'calc(1rem + 2px)' }` | string |
1439
+ | **CSS Variable** | `flex-shrink: var(--shrink)` | `shrink-(--shrink)` | `{ shrink: '--shrink' }` | **Sugar**: Auto-detects `--`. |
1440
+
1441
+ ## Flex
1442
+
1443
+ Controlling flex item resizing behaviour.
1444
+
1445
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1446
+ | :--------------- | :------------------------------ | :---------------- | :------------------------ | :---------------------------------------------------------- |
1447
+ | **1** | `flex: <number> 1 0%` | `flex-<number>` | `{ flex: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
1448
+ | **Fraction** | `flex: calc(<fraction> * 100%)` | `flex-<fraction>` | `{ flex: '<fraction>' }` | v4: accept any integer/integer fraction (string) bare. |
1449
+ | **Auto** | `flex: auto` | `flex-auto` | `{ flex: 'auto' }` | |
1450
+ | **Initial** | `flex: 0 auto` | `flex-initial` | `{ flex: 'initial' }` | |
1451
+ | **None** | `flex: none` | `flex-none` | `{ flex: 'none' }` | |
1452
+ | **Arbitrary** | `flex: 3.5` | `flex-[3.5]` | `{ flex: 3.5 }` | decimal |
1453
+ | **Arbitrary** | `flex: 3.5/4` (not working) | `flex-[3.5/4]` | `{ flex: '3.5/4' }` | not integer/integer fraction |
1454
+ | **Arbitrary** | `flex: 2 2 0%` | `flex-[2_2_0%]` | `{ flex: '2 2 0%' }` | |
1455
+ | **CSS Variable** | `flex: var(--flex)` | `flex-(--flex)` | `{ flex: '--flex' }` | **Sugar**: Auto-detects `--`. |
1456
+
1457
+ ## Order
1458
+
1459
+ Controlling flex/grid item order.
1460
+
1461
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1462
+ | :--------------- | :-------------------- | :-------------------- | :------------------------- | :---------------------------------------------------------- |
1463
+ | **1-12** | `order: <number>` | `order-<number>` | `{ order: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
1464
+ | **First** | `order: -9999` | `order-first` | `{ order: 'first' }` | |
1465
+ | **Last** | `order: 9999` | `order-last` | `{ order: 'last' }` | |
1466
+ | **None** | `order: 0` | `order-none` | `{ order: 'none' }` | |
1467
+ | **Negative** | `order: -<number>` | `-order-<number>` | `{ order: -<number> }` | |
1468
+ | **Arbitrary** | `order: calc(100/5)` | `order-[calc(100/5)]` | `{ order: 'calc(100/5)' }` | |
1469
+ | **CSS Variable** | `order: var(--order)` | `order-(--order)` | `{ order: '--order' }` | **Sugar**: Auto-detects `--`. |
1470
+
1471
+ ## Grid Template Columns
1472
+
1473
+ Specifying the columns in a grid layout.
1474
+
1475
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | `sz` Prop (Alias) | Note |
1476
+ | :--------------- | :-------------------------------------------------------- | :------------------------ | :---------------------------- | :---------------- | :---------------------------------------------------------- |
1477
+ | **1-12** | `grid-template-columns: repeat(<number>, minmax(0, 1fr))` | `grid-cols-<number>` | `{ gridCols: <number> }` | | v4: fully dynamic, no static scale, accept any integer bare |
1478
+ | **None** | `grid-template-columns: none` | `grid-cols-none` | `{ gridCols: 'none' }` | | |
1479
+ | **Subgrid** | `grid-template-columns: subgrid` | `grid-cols-subgrid` | `{ gridCols: 'subgrid' }` | | |
1480
+ | **Arbitrary** | `grid-template-columns: 200px` | `grid-cols-[200px]` | `{ gridCols: '200px' }` | | |
1481
+ | **CSS Variable** | `grid-template-columns: var(--grid-cols)` | `grid-cols-(--grid-cols)` | `{ gridCols: '--grid-cols' }` | | **Sugar**: Auto-detects `--`. |
1482
+
1483
+ ## Grid Template Rows
1484
+
1485
+ Specifying the rows in a grid layout.
1486
+
1487
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | `sz` Prop (Alias) | Note |
1488
+ | :--------------- | :----------------------------------------------------- | :------------------------ | :---------------------------- | :---------------- | :---------------------------------------------------------- |
1489
+ | **1-12** | `grid-template-rows: repeat(<number>, minmax(0, 1fr))` | `grid-rows-<number>` | `{ gridRows: <number> }` | | v4: fully dynamic, no static scale, accept any integer bare |
1490
+ | **None** | `grid-template-rows: none` | `grid-rows-none` | `{ gridRows: 'none' }` | | |
1491
+ | **Subgrid** | `grid-template-rows: subgrid` | `grid-rows-subgrid` | `{ gridRows: 'subgrid' }` | | |
1492
+ | **Arbitrary** | `grid-template-rows: 200px` | `grid-rows-[200px]` | `{ gridRows: '200px' }` | | |
1493
+ | **CSS Variable** | `grid-template-rows: var(--grid-rows)` | `grid-rows-(--grid-rows)` | `{ gridRows: '--grid-rows' }` | | **Sugar**: Auto-detects `--`. |
1494
+
1495
+ ## Grid Column (Start/End/Span)
1496
+
1497
+ Controlling column sizing and placement.
1498
+
1499
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | Note |
1500
+ | :--------------------- | :--------------------------------------------------------- | :------------------------ | :---------------------------- | :---------------------------------------------------------- |
1501
+ | **Auto** | `grid-column: auto` | `col-auto` | `{ col: 'auto' }` | |
1502
+ | **Span** | `grid-column: span <number> / span <number>` | `col-span-<number>` | `{ colSpan: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
1503
+ | **Span Full** | `grid-column: 1 / -1` | `col-span-full` | `{ colSpan: 'full' }` | |
1504
+ | **Span Arbitrary** | `grid-column: span 50px / span 50px` | `col-span-[50px]` | `{ colSpan: '50px' }` | |
1505
+ | **Span CSS Variable** | `grid-column: span var(--col-span) / span var(--col-span)` | `col-span-(--col-span)` | `{ colSpan: '--col-span' }` | **Sugar**: Auto-detects `--`. |
1506
+ | **Start** | `grid-column-start: <number>` | `col-start-<number>` | `{ colStart: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
1507
+ | **Start Negative** | `grid-column-start: calc(<number> * -1)` | `-col-start-<number>` | `{ colStart: -<number> }` | |
1508
+ | **Start Auto** | `grid-column-start: auto` | `col-start-auto` | `{ colStart: 'auto' }` | |
1509
+ | **Start Arbitrary** | `grid-column-start: calc(100/5)` | `col-start-[calc(100/5)]` | `{ colStart: 'calc(100/5)' }` | |
1510
+ | **Start CSS Variable** | `grid-column-start: var(--col-start)` | `col-start-(--col-start)` | `{ colStart: '--col-start' }` | **Sugar**: Auto-detects `--`. |
1511
+ | **End** | `grid-column-end: <number>` | `col-end-<number>` | `{ colEnd: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
1512
+ | **End Negative** | `grid-column-end: calc(<number> * -1)` | `-col-end-<number>` | `{ colEnd: -<number> }` | |
1513
+ | **End Auto** | `grid-column-end: auto` | `col-end-auto` | `{ colEnd: 'auto' }` | |
1514
+ | **End Arbitrary** | `grid-column-end: calc(100/5)` | `col-end-[calc(100/5)]` | `{ colEnd: 'calc(100/5)' }` | |
1515
+ | **End CSS Variable** | `grid-column-end: var(--col-end)` | `col-end-(--col-end)` | `{ colEnd: '--col-end' }` | **Sugar**: Auto-detects `--`. |
1516
+ | **Short** | `grid-column: <number>` | `col-<number>` | `{ col: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
1517
+ | **Short Negative** | `grid-column: calc(<number> * -1)` | `-col-<number>` | `{ col: -<number> }` | |
1518
+ | **Short Arbitrary** | `grid-column: calc(100/5)` | `col-[calc(100/5)]` | `{ col: 'calc(100/5)' }` | |
1519
+ | **Short CSS Variable** | `grid-column: var(--col)` | `col-(--col)` | `{ col: '--col' }` | **Sugar**: Auto-detects `--`. |
1520
+
1521
+ ## Grid Row (Start/End/Span)
1522
+
1523
+ Controlling row sizing and placement.
1524
+
1525
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | Note |
1526
+ | :--------------------- | :------------------------------------------------------ | :------------------------ | :---------------------------- | :---------------------------------------------------------- |
1527
+ | **Auto** | `grid-row: auto` | `row-auto` | `{ row: 'auto' }` | |
1528
+ | **Span** | `grid-row: span <number> / span <number>` | `row-span-<number>` | `{ rowSpan: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
1529
+ | **Span Full** | `grid-row: 1 / -1` | `row-span-full` | `{ rowSpan: 'full' }` | |
1530
+ | **Span Arbitrary** | `grid-row: span 50px / span 50px` | `row-span-[50px]` | `{ rowSpan: '50px' }` | |
1531
+ | **Span CSS Variable** | `grid-row: span var(--row-span) / span var(--row-span)` | `row-span-(--row-span)` | `{ rowSpan: '--row-span' }` | **Sugar**: Auto-detects `--`. |
1532
+ | **Start** | `grid-row-start: <number>` | `row-start-<number>` | `{ rowStart: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
1533
+ | **Start Negative** | `grid-row-start: calc(<number> * -1)` | `-row-start-<number>` | `{ rowStart: -<number> }` | |
1534
+ | **Start Auto** | `grid-row-start: auto` | `row-start-auto` | `{ rowStart: 'auto' }` | |
1535
+ | **Start Arbitrary** | `grid-row-start: calc(100/5)` | `row-start-[calc(100/5)]` | `{ rowStart: 'calc(100/5)' }` | |
1536
+ | **Start CSS Variable** | `grid-row-start: var(--row-start)` | `row-start-(--row-start)` | `{ rowStart: '--row-start' }` | **Sugar**: Auto-detects `--`. |
1537
+ | **End** | `grid-row-end: <number>` | `row-end-<number>` | `{ rowEnd: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
1538
+ | **End Negative** | `grid-row-end: calc(<number> * -1)` | `-row-end-<number>` | `{ rowEnd: -<number> }` | |
1539
+ | **End Auto** | `grid-row-end: auto` | `row-end-auto` | `{ rowEnd: 'auto' }` | |
1540
+ | **End Arbitrary** | `grid-row-end: calc(100/5)` | `row-end-[calc(100/5)]` | `{ rowEnd: 'calc(100/5)' }` | |
1541
+ | **End CSS Variable** | `grid-row-end: var(--row-end)` | `row-end-(--row-end)` | `{ rowEnd: '--row-end' }` | **Sugar**: Auto-detects `--`. |
1542
+ | **Short** | `grid-row: <number>` | `row-<number>` | `{ row: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
1543
+ | **Short Negative** | `grid-row: calc(<number> * -1)` | `-row-<number>` | `{ row: -<number> }` | |
1544
+ | **Short Arbitrary** | `grid-row: calc(100/5)` | `row-[calc(100/5)]` | `{ row: 'calc(100/5)' }` | |
1545
+ | **Short CSS Variable** | `grid-row: var(--row)` | `row-(--row)` | `{ row: '--row' }` | **Sugar**: Auto-detects `--`. |
1546
+
1547
+ ## Grid Auto Flow
1548
+
1549
+ Controlling auto-placement algorithm.
1550
+
1551
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) |
1552
+ | :------------ | :----------------------------- | :-------------------- | :-------------------------- |
1553
+ | **Row** | `grid-auto-flow: row` | `grid-flow-row` | `{ gridFlow: 'row' }` |
1554
+ | **Col** | `grid-auto-flow: column` | `grid-flow-col` | `{ gridFlow: 'col' }` |
1555
+ | **Dense** | `grid-auto-flow: dense` | `grid-flow-dense` | `{ gridFlow: 'dense' }` |
1556
+ | **Row Dense** | `grid-auto-flow: row dense` | `grid-flow-row-dense` | `{ gridFlow: 'row-dense' }` |
1557
+ | **Col Dense** | `grid-auto-flow: column dense` | `grid-flow-col-dense` | `{ gridFlow: 'col-dense' }` |
1558
+
1559
+ ## Grid Auto Columns
1560
+
1561
+ Controlling implicit column sizing.
1562
+
1563
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) |
1564
+ | :--------------- | :------------------------------------ | :-------------------------- | :------------------------------ |
1565
+ | **Auto** | `grid-auto-columns: auto` | `auto-cols-auto` | `{ autoCols: 'auto' }` |
1566
+ | **Min** | `grid-auto-columns: min-content` | `auto-cols-min` | `{ autoCols: 'min' }` |
1567
+ | **Max** | `grid-auto-columns: max-content` | `auto-cols-max` | `{ autoCols: 'max' }` |
1568
+ | **Fr** | `grid-auto-columns: minmax(0, 1fr)` | `auto-cols-fr` | `{ autoCols: 'fr' }` |
1569
+ | **Arbitrary** | `grid-auto-columns: minmax(0, 2fr)` | `auto-cols-[minmax(0,2fr)]` | `{ autoCols: 'minmax(0,2fr)' }` |
1570
+ | **CSS Variable** | `grid-auto-columns: var(--auto-cols)` | `auto-cols-(--auto-cols)` | `{ autoCols: '--auto-cols' }` |
1571
+
1572
+ ## Grid Auto Rows
1573
+
1574
+ Controlling implicit row sizing.
1575
+
1576
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) |
1577
+ | :--------------- | :--------------------------------- | :-------------------------- | :------------------------------ |
1578
+ | **Auto** | `grid-auto-rows: auto` | `auto-rows-auto` | `{ autoRows: 'auto' }` |
1579
+ | **Min** | `grid-auto-rows: min-content` | `auto-rows-min` | `{ autoRows: 'min' }` |
1580
+ | **Max** | `grid-auto-rows: max-content` | `auto-rows-max` | `{ autoRows: 'max' }` |
1581
+ | **Fr** | `grid-auto-rows: minmax(0, 1fr)` | `auto-rows-fr` | `{ autoRows: 'fr' }` |
1582
+ | **Arbitrary** | `grid-auto-rows: minmax(0, 2fr)` | `auto-rows-[minmax(0,2fr)]` | `{ autoRows: 'minmax(0,2fr)' }` |
1583
+ | **CSS Variable** | `grid-auto-rows: var(--auto-rows)` | `auto-rows-(--auto-rows)` | `{ autoRows: '--auto-rows' }` |
1584
+
1585
+ ## Gap
1586
+
1587
+ Controlling gutters.
1588
+
1589
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | Note |
1590
+ | :--------------------- | :-------------------------------------------- | :---------------- | :-------------------- | :------------------------------------------------------------------------------- |
1591
+ | **Gap** | `gap: calc(var(--spacing) * <number>)` | `gap-<number>` | `{ gap: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
1592
+ | **Gap Arbitrary** | `gap: 24px` | `gap-[24px]` | `{ gap: '24px' }` | |
1593
+ | **Gap CSS Variable** | `gap: var(--gap)` | `gap-(--gap)` | `{ gap: '--gap' }` | **Sugar**: Auto-detects `--`. |
1594
+ | **Gap X** | `column-gap: calc(var(--spacing) * <number>)` | `gap-x-<number>` | `{ gapX: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
1595
+ | **Gap X Arbitrary** | `column-gap: 24px` | `gap-x-[24px]` | `{ gapX: '24px' }` | |
1596
+ | **Gap X CSS Variable** | `column-gap: var(--gap-x)` | `gap-x-(--gap-x)` | `{ gapX: '--gap-x' }` | **Sugar**: Auto-detects `--`. |
1597
+ | **Gap Y** | `row-gap: calc(var(--spacing) * <number>)` | `gap-y-<number>` | `{ gapY: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
1598
+ | **Gap Y Arbitrary** | `row-gap: 24px` | `gap-y-[24px]` | `{ gapY: '24px' }` | |
1599
+ | **Gap Y CSS Variable** | `row-gap: var(--gap-y)` | `gap-y-(--gap-y)` | `{ gapY: '--gap-y' }` | **Sugar**: Auto-detects `--`. |
1600
+
1601
+ ## Justify Content
1602
+
1603
+ Controlling placement along the main axis.
1604
+
1605
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) |
1606
+ | :-------------- | :------------------------------- | :-------------------- | :--------------------------- |
1607
+ | **Normal** | `justify-content: normal` | `justify-normal` | `{ justify: 'normal' }` |
1608
+ | **Start** | `justify-content: flex-start` | `justify-start` | `{ justify: 'start' }` |
1609
+ | **End** | `justify-content: flex-end` | `justify-end` | `{ justify: 'end' }` |
1610
+ | **End Safe** | `justify-content: safe flex-end` | `justify-end-safe` | `{ justify: 'end-safe' }` |
1611
+ | **Center** | `justify-content: center` | `justify-center` | `{ justify: 'center' }` |
1612
+ | **Center Safe** | `justify-content: safe center` | `justify-center-safe` | `{ justify: 'center-safe' }` |
1613
+ | **Between** | `justify-content: space-between` | `justify-between` | `{ justify: 'between' }` |
1614
+ | **Around** | `justify-content: space-around` | `justify-around` | `{ justify: 'around' }` |
1615
+ | **Evenly** | `justify-content: space-evenly` | `justify-evenly` | `{ justify: 'evenly' }` |
1616
+ | **Stretch** | `justify-content: stretch` | `justify-stretch` | `{ justify: 'stretch' }` |
1617
+ | **Baseline** | `justify-content: baseline` | `justify-baseline` | `{ justify: 'baseline' }` |
1618
+
1619
+ ## Justify Items
1620
+
1621
+ Controlling grid item alignment inline axis.
1622
+
1623
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) |
1624
+ | :-------------- | :--------------------------- | :-------------------------- | :-------------------------------- |
1625
+ | **Start** | `justify-items: start` | `justify-items-start` | `{ justifyItems: 'start' }` |
1626
+ | **End** | `justify-items: end` | `justify-items-end` | `{ justifyItems: 'end' }` |
1627
+ | **End Safe** | `justify-items: safe end` | `justify-items-end-safe` | `{ justifyItems: 'end-safe' }` |
1628
+ | **Center** | `justify-items: center` | `justify-items-center` | `{ justifyItems: 'center' }` |
1629
+ | **Center Safe** | `justify-items: safe center` | `justify-items-center-safe` | `{ justifyItems: 'center-safe' }` |
1630
+ | **Stretch** | `justify-items: stretch` | `justify-items-stretch` | `{ justifyItems: 'stretch' }` |
1631
+ | **Normal** | `justify-items: normal` | `justify-items-normal` | `{ justifyItems: 'normal' }` |
1632
+
1633
+ ## Justify Self
1634
+
1635
+ Controlling individual item alignment.
1636
+
1637
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | `sz` Prop (Alias) |
1638
+ | :-------------- | :-------------------------- | :------------------------- | :------------------------------- | :---------------- |
1639
+ | **Auto** | `justify-self: auto` | `justify-self-auto` | `{ justifySelf: 'auto' }` | |
1640
+ | **Start** | `justify-self: start` | `justify-self-start` | `{ justifySelf: 'start' }` | |
1641
+ | **End** | `justify-self: end` | `justify-self-end` | `{ justifySelf: 'end' }` | |
1642
+ | **End Safe** | `justify-self: safe end` | `justify-self-end-safe` | `{ justifySelf: 'end-safe' }` | |
1643
+ | **Center** | `justify-self: center` | `justify-self-center` | `{ justifySelf: 'center' }` | |
1644
+ | **Center Safe** | `justify-self: safe center` | `justify-self-center-safe` | `{ justifySelf: 'center-safe' }` | |
1645
+ | **Stretch** | `justify-self: stretch` | `justify-self-stretch` | `{ justifySelf: 'stretch' }` | |
1646
+
1647
+ ## Align Content
1648
+
1649
+ Controlling placement along the cross axis.
1650
+
1651
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) |
1652
+ | :----------- | :----------------------------- | :----------------- | :----------------------------- |
1653
+ | **Normal** | `align-content: normal` | `content-normal` | `{ alignContent: 'normal' }` |
1654
+ | **Start** | `align-content: flex-start` | `content-start` | `{ alignContent: 'start' }` |
1655
+ | **End** | `align-content: flex-end` | `content-end` | `{ alignContent: 'end' }` |
1656
+ | **Center** | `align-content: center` | `content-center` | `{ alignContent: 'center' }` |
1657
+ | **Between** | `align-content: space-between` | `content-between` | `{ alignContent: 'between' }` |
1658
+ | **Around** | `align-content: space-around` | `content-around` | `{ alignContent: 'around' }` |
1659
+ | **Evenly** | `align-content: space-evenly` | `content-evenly` | `{ alignContent: 'evenly' }` |
1660
+ | **Stretch** | `align-content: stretch` | `content-stretch` | `{ alignContent: 'stretch' }` |
1661
+ | **Baseline** | `align-content: baseline` | `content-baseline` | `{ alignContent: 'baseline' }` |
1662
+
1663
+ ## Align Items
1664
+
1665
+ Controlling flex item alignment cross axis.
1666
+
1667
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | `sz` Prop (Alias) |
1668
+ | :---------------- | :--------------------------- | :-------------------- | :--------------------------- | :------------------------ |
1669
+ | **Start** | `align-items: flex-start` | `items-start` | `{ items: 'start' }` | `{ alignItems: 'start' }` |
1670
+ | **End** | `align-items: flex-end` | `items-end` | `{ items: 'end' }` | |
1671
+ | **End Safe** | `align-items: safe end` | `items-end-safe` | `{ items: 'end-safe' }` | |
1672
+ | **Center** | `align-items: center` | `items-center` | `{ items: 'center' }` | |
1673
+ | **Center Safe** | `align-items: safe center` | `items-center-safe` | `{ items: 'center-safe' }` | |
1674
+ | **Baseline** | `align-items: baseline` | `items-baseline` | `{ items: 'baseline' }` | |
1675
+ | **Baseline Last** | `align-items: last baseline` | `items-baseline-last` | `{ items: 'baseline-last' }` | |
1676
+ | **Stretch** | `align-items: stretch` | `items-stretch` | `{ items: 'stretch' }` | |
1677
+
1678
+ ## Align Self
1679
+
1680
+ Controlling individual item alignment.
1681
+
1682
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) |
1683
+ | :---------------- | :-------------------------- | :------------------- | :-------------------------- |
1684
+ | **Auto** | `align-self: auto` | `self-auto` | `{ self: 'auto' }` |
1685
+ | **Start** | `align-self: flex-start` | `self-start` | `{ self: 'start' }` |
1686
+ | **End** | `align-self: flex-end` | `self-end` | `{ self: 'end' }` |
1687
+ | **End Safe** | `align-self: safe end` | `self-end-safe` | `{ self: 'end-safe' }` |
1688
+ | **Center** | `align-self: center` | `self-center` | `{ self: 'center' }` |
1689
+ | **Center Safe** | `align-self: safe center` | `self-center-safe` | `{ self: 'center-safe' }` |
1690
+ | **Stretch** | `align-self: stretch` | `self-stretch` | `{ self: 'stretch' }` |
1691
+ | **Baseline** | `align-self: baseline` | `self-baseline` | `{ self: 'baseline' }` |
1692
+ | **Baseline Last** | `align-self: last baseline` | `self-baseline-last` | `{ self: 'baseline-last' }` |
1693
+
1694
+ ## Place Content
1695
+
1696
+ Shorthand for align-content and justify-content.
1697
+
1698
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | `sz` Prop (Alias) |
1699
+ | :-------------- | :----------------------------- | :-------------------------- | :-------------------------------- | :---------------- |
1700
+ | **Center** | `place-content: center` | `place-content-center` | `{ placeContent: 'center' }` | |
1701
+ | **Center Safe** | `place-content: safe center` | `place-content-center-safe` | `{ placeContent: 'center-safe' }` | |
1702
+ | **Start** | `place-content: start` | `place-content-start` | `{ placeContent: 'start' }` | |
1703
+ | **End** | `place-content: end` | `place-content-end` | `{ placeContent: 'end' }` | |
1704
+ | **End Safe** | `place-content: safe end` | `place-content-end-safe` | `{ placeContent: 'end-safe' }` | |
1705
+ | **Between** | `place-content: space-between` | `place-content-between` | `{ placeContent: 'between' }` | |
1706
+ | **Around** | `place-content: space-around` | `place-content-around` | `{ placeContent: 'around' }` | |
1707
+ | **Evenly** | `place-content: space-evenly` | `place-content-evenly` | `{ placeContent: 'evenly' }` | |
1708
+ | **Stretch** | `place-content: stretch` | `place-content-stretch` | `{ placeContent: 'stretch' }` | |
1709
+ | **Baseline** | `place-content: baseline` | `place-content-baseline` | `{ placeContent: 'baseline' }` | |
1710
+
1711
+ ## Place Items
1712
+
1713
+ Shorthand for align-items and justify-items.
1714
+
1715
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | `sz` Prop (Alias) |
1716
+ | :-------------- | :------------------------- | :------------------------ | :------------------------------ | :---------------- |
1717
+ | **Start** | `place-items: start` | `place-items-start` | `{ placeItems: 'start' }` | |
1718
+ | **End** | `place-items: end` | `place-items-end` | `{ placeItems: 'end' }` | |
1719
+ | **End Safe** | `place-items: safe end` | `place-items-end-safe` | `{ placeItems: 'end-safe' }` | |
1720
+ | **Center** | `place-items: center` | `place-items-center` | `{ placeItems: 'center' }` | |
1721
+ | **Center Safe** | `place-items: safe center` | `place-items-center-safe` | `{ placeItems: 'center-safe' }` | |
1722
+ | **Stretch** | `place-items: stretch` | `place-items-stretch` | `{ placeItems: 'stretch' }` | |
1723
+ | **Baseline** | `place-items: baseline` | `place-items-baseline` | `{ placeItems: 'baseline' }` | |
1724
+
1725
+ ## Place Self
1726
+
1727
+ Shorthand for align-self and justify-self.
1728
+
1729
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | `sz` Prop (Alias) |
1730
+ | :-------------- | :------------------------ | :----------------------- | :----------------------------- | :---------------- |
1731
+ | **Auto** | `place-self: auto` | `place-self-auto` | `{ placeSelf: 'auto' }` | |
1732
+ | **Start** | `place-self: start` | `place-self-start` | `{ placeSelf: 'start' }` | |
1733
+ | **End** | `place-self: end` | `place-self-end` | `{ placeSelf: 'end' }` | |
1734
+ | **End Safe** | `place-self: safe end` | `place-self-end-safe` | `{ placeSelf: 'end-safe' }` | |
1735
+ | **Center** | `place-self: center` | `place-self-center` | `{ placeSelf: 'center' }` | |
1736
+ | **Center Safe** | `place-self: safe center` | `place-self-center-safe` | `{ placeSelf: 'center-safe' }` | |
1737
+ | **Stretch** | `place-self: stretch` | `place-self-stretch` | `{ placeSelf: 'stretch' }` | |
1738
+
1739
+
1740
+ # Interactivity
1741
+
1742
+ Utilities for controlling how users interact with elements.
1743
+
1744
+ ## Accent Color
1745
+
1746
+ Utilities for controlling the accent color of a form control.
1747
+
1748
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1749
+ | :------------ | :----------------------- | :----------------- | :------------------------ | :--- |
1750
+ | **Color** | `accent-color: (etc)` | `accent-red-500` | `{ accent: 'red-500' }` | |
1751
+ | **Arbitrary** | `accent-color: (etc)` | `accent-[#50d71e]` | `{ accent: '#50d71e' }` | |
1752
+ | **Variable** | `accent-color: var(--c)` | `accent-(--c)` | `{ accent: '--c' }` | |
1753
+
1754
+ ## Appearance
1755
+
1756
+ Utilities for suppressing native form control styling.
1757
+
1758
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1759
+ | :------- | :------------------ | :---------------- | :------------------------ | :--- |
1760
+ | **None** | `appearance: none;` | `appearance-none` | `{ appearance: 'none' }` | |
1761
+ | **Auto** | `appearance: auto;` | `appearance-auto` | `{ appearance: 'auto' }` | |
1762
+
1763
+ ## Caret Color
1764
+
1765
+ Utilities for controlling the color of the text input cursor.
1766
+
1767
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1768
+ | :------------ | :---------------------- | :---------------- | :------------------------ | :--- |
1769
+ | **Color** | `caret-color: (etc)` | `caret-red-500` | `{ caret: 'red-500' }` | |
1770
+ | **Arbitrary** | `caret-color: (etc)` | `caret-[#50d71e]` | `{ caret: '#50d71e' }` | |
1771
+ | **Variable** | `caret-color: var(--c)` | `caret-(--c)` | `{ caret: '--c' }` | |
1772
+
1773
+ ## Color Scheme
1774
+
1775
+ Utilities for specifying the color scheme an element should be rendered with.
1776
+
1777
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1778
+ | :------------- | :------------------------- | :------------------ | :------------------------- | :--- |
1779
+ | **Dark** | `color-scheme: dark` | `scheme-dark` | `{ scheme: 'dark' }` | |
1780
+ | **Light** | `color-scheme: light` | `scheme-light` | `{ scheme: 'light' }` | |
1781
+ | **Normal** | `color-scheme: normal` | `scheme-normal` | `{ scheme: 'normal' }` | |
1782
+ | **Light-Dark** | `color-scheme: light dark` | `scheme-light-dark` | `{ scheme: 'light-dark' }` | |
1783
+ | **Only Dark** | `color-scheme: only dark` | `scheme-only-dark` | `{ scheme: 'only-dark' }` | |
1784
+ | **Only Light** | `color-scheme: only light` | `scheme-only-light` | `{ scheme: 'only-light' }` | |
1785
+
1786
+ ## Cursor
1787
+
1788
+ Utilities for controlling the cursor style when hovering over an element.
1789
+
1790
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1791
+ | :------------ | :----------------- | :----------------------------------- | :---------------------------------- | :--- |
1792
+ | **Keywords** | `cursor: (etc)` | `cursor-pointer`, `cursor-wait`(etc) | `{ cursor: 'pointer' }` | |
1793
+ | **Arbitrary** | `cursor: (etc)` | `cursor-[url(h.cur),_pointer]` | `{ cursor: 'url(h.cur),_pointer' }` | |
1794
+ | **Variable** | `cursor: var(--c)` | `cursor-(--c)` | `{ cursor: '--c' }` | |
1795
+
1796
+ ## Field Sizing
1797
+
1798
+ Utilities for controlling the sizing of form fields.
1799
+
1800
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1801
+ | :---------- | :----------------------- | :--------------------- | :--------------------------- | :--- |
1802
+ | **Fixed** | `field-sizing: fixed;` | `field-sizing-fixed` | `{ fieldSizing: 'fixed' }` | |
1803
+ | **Content** | `field-sizing: content;` | `field-sizing-content` | `{ fieldSizing: 'content' }` | |
1804
+
1805
+ ## Pointer Events
1806
+
1807
+ Utilities for controlling whether an element responds to pointer events.
1808
+
1809
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1810
+ | :------- | :---------------------- | :-------------------- | :-------------------------- | :--- |
1811
+ | **None** | `pointer-events: none;` | `pointer-events-none` | `{ pointerEvents: 'none' }` | |
1812
+ | **Auto** | `pointer-events: auto;` | `pointer-events-auto` | `{ pointerEvents: 'auto' }` | |
1813
+
1814
+ ## Resize
1815
+
1816
+ Utilities for controlling whether an element is resizable.
1817
+
1818
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1819
+ | :------------- | :-------------------- | :---------------- | :------------------------ | :--- |
1820
+ | **None** | `resize: none;` | `resize-none` | `{ resize: 'none' }` | |
1821
+ | **Both** | `resize: both;` | `resize` | `{ resize: true }` | |
1822
+ | **Vertical** | `resize: vertical;` | `resize-y` | `{ resize: 'y' }` | |
1823
+ | **Horizontal** | `resize: horizontal;` | `resize-x` | `{ resize: 'x' }` | |
1824
+
1825
+ ## Scroll Behavior
1826
+
1827
+ Utilities for controlling the scroll behavior of an element.
1828
+
1829
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1830
+ | :--------- | :------------------------- | :---------------- | :------------------------ | :--- |
1831
+ | **Auto** | `scroll-behavior: auto;` | `scroll-auto` | `{ scroll: 'auto' }` | |
1832
+ | **Smooth** | `scroll-behavior: smooth;` | `scroll-smooth` | `{ scroll: 'smooth' }` | |
1833
+
1834
+ ## Scroll Margin
1835
+
1836
+ Utilities for controlling the scroll offset of an element.
1837
+
1838
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1839
+ | :---------------- | :--------------------------------- | :---------------- | :------------------------ | :------------------- |
1840
+ | Scroll Margin 0 | `scroll-margin: 0px` | `scroll-m-0` | `{ scrollM: 0 }` | |
1841
+ | Scroll Margin px | `scroll-margin: 1px` | `scroll-m-px` | `{ scrollM: 'px' }` | |
1842
+ | Scroll Margin 0.5 | `scroll-margin: 0.125rem` | `scroll-m-0.5` | `{ scrollM: 0.5 }` | |
1843
+ | Scroll Margin 1 | `scroll-margin: 0.25rem` | `scroll-m-1` | `{ scrollM: 1 }` | |
1844
+ | Scroll Margin 1.5 | `scroll-margin: 0.375rem` | `scroll-m-1.5` | `{ scrollM: 1.5 }` | |
1845
+ | Scroll Margin 2 | `scroll-margin: 0.5rem` | `scroll-m-2` | `{ scrollM: 2 }` | |
1846
+ | Scroll Margin 2.5 | `scroll-margin: 0.625rem` | `scroll-m-2.5` | `{ scrollM: 2.5 }` | |
1847
+ | Scroll Margin 3 | `scroll-margin: 0.75rem` | `scroll-m-3` | `{ scrollM: 3 }` | |
1848
+ | Scroll Margin 3.5 | `scroll-margin: 0.875rem` | `scroll-m-3.5` | `{ scrollM: 3.5 }` | |
1849
+ | Scroll Margin 4 | `scroll-margin: 1rem` | `scroll-m-4` | `{ scrollM: 4 }` | |
1850
+ | Scroll Margin 5 | `scroll-margin: 1.25rem` | `scroll-m-5` | `{ scrollM: 5 }` | |
1851
+ | Scroll Margin 6 | `scroll-margin: 1.5rem` | `scroll-m-6` | `{ scrollM: 6 }` | |
1852
+ | Scroll Margin 7 | `scroll-margin: 1.75rem` | `scroll-m-7` | `{ scrollM: 7 }` | |
1853
+ | Scroll Margin 8 | `scroll-margin: 2rem` | `scroll-m-8` | `{ scrollM: 8 }` | |
1854
+ | Scroll Margin 9 | `scroll-margin: 2.25rem` | `scroll-m-9` | `{ scrollM: 9 }` | |
1855
+ | Scroll Margin 10 | `scroll-margin: 2.5rem` | `scroll-m-10` | `{ scrollM: 10 }` | |
1856
+ | Scroll Margin 11 | `scroll-margin: 2.75rem` | `scroll-m-11` | `{ scrollM: 11 }` | |
1857
+ | Scroll Margin 12 | `scroll-margin: 3rem` | `scroll-m-12` | `{ scrollM: 12 }` | |
1858
+ | Scroll Margin 14 | `scroll-margin: 3.5rem` | `scroll-m-14` | `{ scrollM: 14 }` | |
1859
+ | Scroll Margin 16 | `scroll-margin: 4rem` | `scroll-m-16` | `{ scrollM: 16 }` | |
1860
+ | Scroll Margin 20 | `scroll-margin: 5rem` | `scroll-m-20` | `{ scrollM: 20 }` | |
1861
+ | Scroll Margin 24 | `scroll-margin: 6rem` | `scroll-m-24` | `{ scrollM: 24 }` | |
1862
+ | Scroll Margin 28 | `scroll-margin: 7rem` | `scroll-m-28` | `{ scrollM: 28 }` | |
1863
+ | Scroll Margin 32 | `scroll-margin: 8rem` | `scroll-m-32` | `{ scrollM: 32 }` | |
1864
+ | Scroll Margin 36 | `scroll-margin: 9rem` | `scroll-m-36` | `{ scrollM: 36 }` | |
1865
+ | Scroll Margin 40 | `scroll-margin: 10rem` | `scroll-m-40` | `{ scrollM: 40 }` | |
1866
+ | Scroll Margin 44 | `scroll-margin: 11rem` | `scroll-m-44` | `{ scrollM: 44 }` | |
1867
+ | Scroll Margin 48 | `scroll-margin: 12rem` | `scroll-m-48` | `{ scrollM: 48 }` | |
1868
+ | Scroll Margin 52 | `scroll-margin: 13rem` | `scroll-m-52` | `{ scrollM: 52 }` | |
1869
+ | Scroll Margin 56 | `scroll-margin: 14rem` | `scroll-m-56` | `{ scrollM: 56 }` | |
1870
+ | Scroll Margin 60 | `scroll-margin: 15rem` | `scroll-m-60` | `{ scrollM: 60 }` | |
1871
+ | Scroll Margin 64 | `scroll-margin: 16rem` | `scroll-m-64` | `{ scrollM: 64 }` | |
1872
+ | Scroll Margin 72 | `scroll-margin: 18rem` | `scroll-m-72` | `{ scrollM: 72 }` | |
1873
+ | Scroll Margin 80 | `scroll-margin: 20rem` | `scroll-m-80` | `{ scrollM: 80 }` | |
1874
+ | Scroll Margin 96 | `scroll-margin: 24rem` | `scroll-m-96` | `{ scrollM: 96 }` | |
1875
+ | **X/Y/T/R/B/L** | `scroll-margin-top: (etc)` | `scroll-mt-4` | `{ scrollMt: 4 }` | |
1876
+ | **Block Start** | `scroll-margin-block-start: (etc)` | `scroll-mbs-4` | `{ scrollMbs: 4 }` | v4.2: logical block. |
1877
+ | **Block End** | `scroll-margin-block-end: (etc)` | `scroll-mbe-4` | `{ scrollMbe: 4 }` | v4.2: logical block. |
1878
+ | **Negative** | `scroll-margin: -(etc)` | `-scroll-m-4` | `{ scrollM: -4 }` | |
1879
+ | **Arbitrary** | `scroll-margin: 5px` | `scroll-m-[5px]` | `{ scrollM: '5px' }` | |
1880
+ | **Variable** | `scroll-margin: var(--m)` | `scroll-m-(--m)` | `{ scrollM: '--m' }` | |
1881
+
1882
+ ## Scroll Padding
1883
+
1884
+ Utilities for controlling an element's scroll padding.
1885
+
1886
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1887
+ | :----------------- | :---------------------------------- | :---------------- | :------------------------ | :------------------- |
1888
+ | Scroll Padding 0 | `scroll-padding: 0px` | `scroll-p-0` | `{ scrollP: 0 }` | |
1889
+ | Scroll Padding px | `scroll-padding: 1px` | `scroll-p-px` | `{ scrollP: 'px' }` | |
1890
+ | Scroll Padding 0.5 | `scroll-padding: 0.125rem` | `scroll-p-0.5` | `{ scrollP: 0.5 }` | |
1891
+ | Scroll Padding 1 | `scroll-padding: 0.25rem` | `scroll-p-1` | `{ scrollP: 1 }` | |
1892
+ | Scroll Padding 1.5 | `scroll-padding: 0.375rem` | `scroll-p-1.5` | `{ scrollP: 1.5 }` | |
1893
+ | Scroll Padding 2 | `scroll-padding: 0.5rem` | `scroll-p-2` | `{ scrollP: 2 }` | |
1894
+ | Scroll Padding 2.5 | `scroll-padding: 0.625rem` | `scroll-p-2.5` | `{ scrollP: 2.5 }` | |
1895
+ | Scroll Padding 3 | `scroll-padding: 0.75rem` | `scroll-p-3` | `{ scrollP: 3 }` | |
1896
+ | Scroll Padding 3.5 | `scroll-padding: 0.875rem` | `scroll-p-3.5` | `{ scrollP: 3.5 }` | |
1897
+ | Scroll Padding 4 | `scroll-padding: 1rem` | `scroll-p-4` | `{ scrollP: 4 }` | |
1898
+ | Scroll Padding 5 | `scroll-padding: 1.25rem` | `scroll-p-5` | `{ scrollP: 5 }` | |
1899
+ | Scroll Padding 6 | `scroll-padding: 1.5rem` | `scroll-p-6` | `{ scrollP: 6 }` | |
1900
+ | Scroll Padding 7 | `scroll-padding: 1.75rem` | `scroll-p-7` | `{ scrollP: 7 }` | |
1901
+ | Scroll Padding 8 | `scroll-padding: 2rem` | `scroll-p-8` | `{ scrollP: 8 }` | |
1902
+ | Scroll Padding 9 | `scroll-padding: 2.25rem` | `scroll-p-9` | `{ scrollP: 9 }` | |
1903
+ | Scroll Padding 10 | `scroll-padding: 2.5rem` | `scroll-p-10` | `{ scrollP: 10 }` | |
1904
+ | Scroll Padding 11 | `scroll-padding: 2.75rem` | `scroll-p-11` | `{ scrollP: 11 }` | |
1905
+ | Scroll Padding 12 | `scroll-padding: 3rem` | `scroll-p-12` | `{ scrollP: 12 }` | |
1906
+ | Scroll Padding 14 | `scroll-padding: 3.5rem` | `scroll-p-14` | `{ scrollP: 14 }` | |
1907
+ | Scroll Padding 16 | `scroll-padding: 4rem` | `scroll-p-16` | `{ scrollP: 16 }` | |
1908
+ | Scroll Padding 20 | `scroll-padding: 5rem` | `scroll-p-20` | `{ scrollP: 20 }` | |
1909
+ | Scroll Padding 24 | `scroll-padding: 6rem` | `scroll-p-24` | `{ scrollP: 24 }` | |
1910
+ | Scroll Padding 28 | `scroll-padding: 7rem` | `scroll-p-28` | `{ scrollP: 28 }` | |
1911
+ | Scroll Padding 32 | `scroll-padding: 8rem` | `scroll-p-32` | `{ scrollP: 32 }` | |
1912
+ | Scroll Padding 36 | `scroll-padding: 9rem` | `scroll-p-36` | `{ scrollP: 36 }` | |
1913
+ | Scroll Padding 40 | `scroll-padding: 10rem` | `scroll-p-40` | `{ scrollP: 40 }` | |
1914
+ | Scroll Padding 44 | `scroll-padding: 11rem` | `scroll-p-44` | `{ scrollP: 44 }` | |
1915
+ | Scroll Padding 48 | `scroll-padding: 12rem` | `scroll-p-48` | `{ scrollP: 48 }` | |
1916
+ | Scroll Padding 52 | `scroll-padding: 13rem` | `scroll-p-52` | `{ scrollP: 52 }` | |
1917
+ | Scroll Padding 56 | `scroll-padding: 14rem` | `scroll-p-56` | `{ scrollP: 56 }` | |
1918
+ | Scroll Padding 60 | `scroll-padding: 15rem` | `scroll-p-60` | `{ scrollP: 60 }` | |
1919
+ | Scroll Padding 64 | `scroll-padding: 16rem` | `scroll-p-64` | `{ scrollP: 64 }` | |
1920
+ | Scroll Padding 72 | `scroll-padding: 18rem` | `scroll-p-72` | `{ scrollP: 72 }` | |
1921
+ | Scroll Padding 80 | `scroll-padding: 20rem` | `scroll-p-80` | `{ scrollP: 80 }` | |
1922
+ | Scroll Padding 96 | `scroll-padding: 24rem` | `scroll-p-96` | `{ scrollP: 96 }` | |
1923
+ | **X/Y/T/R/B/L** | `scroll-padding-top: (etc)` | `scroll-pt-4` | `{ scrollPt: 4 }` | |
1924
+ | **Block Start** | `scroll-padding-block-start: (etc)` | `scroll-pbs-4` | `{ scrollPbs: 4 }` | v4.2: logical block. |
1925
+ | **Block End** | `scroll-padding-block-end: (etc)` | `scroll-pbe-4` | `{ scrollPbe: 4 }` | v4.2: logical block. |
1926
+ | **Arbitrary** | `scroll-padding: 5px` | `scroll-p-[5px]` | `{ scrollP: '5px' }` | |
1927
+ | **Variable** | `scroll-padding: var(--p)` | `scroll-p-(--p)` | `{ scrollP: '--p' }` | |
1928
+
1929
+ ## Scroll Snap Align
1930
+
1931
+ Utilities for controlling the snap alignment of an element within a snap container.
1932
+
1933
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1934
+ | :--------- | :-------------------------- | :---------------- | :------------------------ | :--- |
1935
+ | **Start** | `scroll-snap-align: start` | `snap-start` | `{ snapAlign: 'start' }` | |
1936
+ | **End** | `scroll-snap-align: end` | `snap-end` | `{ snapAlign: 'end' }` | |
1937
+ | **Center** | `scroll-snap-align: center` | `snap-center` | `{ snapAlign: 'center' }` | |
1938
+ | **None** | `scroll-snap-align: none` | `snap-align-none` | `{ snapAlign: 'none' }` | |
1939
+
1940
+ ## Scroll Snap Stop
1941
+
1942
+ Utilities for controlling whether an element's container stops on it.
1943
+
1944
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1945
+ | :--------- | :------------------------- | :---------------- | :------------------------ | :--- |
1946
+ | **Normal** | `scroll-snap-stop: normal` | `snap-normal` | `{ snapStop: 'normal' }` | |
1947
+ | **Always** | `scroll-snap-stop: always` | `snap-always` | `{ snapStop: 'always' }` | |
1948
+
1949
+ ## Scroll Snap Type
1950
+
1951
+ Utilities for controlling how strictly snap points are enforced.
1952
+
1953
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1954
+ | :------- | :----------------------- | :---------------- | :------------------------ | :--- |
1955
+ | **None** | `scroll-snap-type: none` | `snap-none` | `{ snapType: 'none' }` | |
1956
+ | **X** | `scroll-snap-type: x` | `snap-x` | `{ snapType: 'x' }` | |
1957
+ | **Y** | `scroll-snap-type: y` | `snap-y` | `{ snapType: 'y' }` | |
1958
+ | **Both** | `scroll-snap-type: both` | `snap-both` | `{ snapType: 'both' }` | |
1959
+
1960
+ ## Scroll Snap Strictness
1961
+
1962
+ Utilities for controlling the strictness of snap points.
1963
+
1964
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1965
+ | :------------ | :------------------------------ | :---------------- | :-------------------------------- | :--- |
1966
+ | **Mandatory** | `scroll-snap-type: * mandatory` | `snap-mandatory` | `{ snapStrictness: 'mandatory' }` | |
1967
+ | **Proximity** | `scroll-snap-type: * proximity` | `snap-proximity` | `{ snapStrictness: 'proximity' }` | |
1968
+
1969
+ ## Touch Action
1970
+
1971
+ Utilities for controlling how an element can be panned and zoomed by a user on a touchscreen.
1972
+
1973
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1974
+ | :----------- | :-------------------- | :--------------------------------------------- | :------------------------ | :--- |
1975
+ | **Keywords** | `touch-action: (etc)` | `touch-auto`, `touch-none`, `touch-pan-x`(etc) | `{ touch: 'auto' }` | |
1976
+
1977
+ ## User Select
1978
+
1979
+ Utilities for controlling whether the user can select text in an element.
1980
+
1981
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1982
+ | :------- | :------------------- | :---------------- | :------------------------ | :--- |
1983
+ | **None** | `user-select: none;` | `select-none` | `{ select: 'none' }` | |
1984
+ | **Auto** | `user-select: auto;` | `select-auto` | `{ select: 'auto' }` | |
1985
+ | **Text** | `user-select: text;` | `select-text` | `{ select: 'text' }` | |
1986
+ | **All** | `user-select: all;` | `select-all` | `{ select: 'all' }` | |
1987
+
1988
+ ## Will Change
1989
+
1990
+ Utilities for hinting to the browser how an element will change.
1991
+
1992
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
1993
+ | :------------ | :---------------------- | :-------------------------------------------- | :------------------------ | :--- |
1994
+ | **Keywords** | `will-change: (etc)` | `will-change-auto`, `will-change-scroll`(etc) | `{ willChange: 'auto' }` | |
1995
+ | **Arbitrary** | `will-change: <v>` | `will-change-[<v>]` | `{ willChange: '<v>' }` | |
1996
+ | **Variable** | `will-change: var(--c)` | `will-change-(--c)` | `{ willChange: '--c' }` | |
1997
+
1998
+ ## Scrollbar Width (v4.3)
1999
+
2000
+ Utilities for controlling the scrollbar width.
2001
+
2002
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2003
+ | :------- | :---------------------- | :---------------- | :------------------------ | :--- |
2004
+ | **Auto** | `scrollbar-width: auto` | `scrollbar-auto` | `{ scrollbar: 'auto' }` | |
2005
+ | **Thin** | `scrollbar-width: thin` | `scrollbar-thin` | `{ scrollbar: 'thin' }` | |
2006
+ | **None** | `scrollbar-width: none` | `scrollbar-none` | `{ scrollbar: 'none' }` | |
2007
+
2008
+ ## Scrollbar Color (v4.3)
2009
+
2010
+ Utilities for controlling the scrollbar thumb and track colors.
2011
+
2012
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2013
+ | :----------- | :------------------------------ | :----------------------- | :----------------------------- | :--- |
2014
+ | **Thumb** | `scrollbar-color: <color> ...` | `scrollbar-thumb-<name>` | `{ scrollbarThumb: '<name>' }` | |
2015
+ | **Track** | `scrollbar-color: ... <color>` | `scrollbar-track-<name>` | `{ scrollbarTrack: '<name>' }` | |
2016
+ | **Variable** | `scrollbar-color: var(--c) ...` | `scrollbar-thumb-(--c)` | `{ scrollbarThumb: '--c' }` | |
2017
+
2018
+ ## Scrollbar Gutter (v4.3)
2019
+
2020
+ Utilities for controlling the scrollbar gutter behavior.
2021
+
2022
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2023
+ | :--------- | :------------------------------------ | :------------------------ | :------------------------------ | :--- |
2024
+ | **Auto** | `scrollbar-gutter: auto` | `scrollbar-gutter-auto` | `{ scrollbarGutter: 'auto' }` | |
2025
+ | **Stable** | `scrollbar-gutter: stable` | `scrollbar-gutter-stable` | `{ scrollbarGutter: 'stable' }` | |
2026
+ | **Both** | `scrollbar-gutter: stable both-edges` | `scrollbar-gutter-both` | `{ scrollbarGutter: 'both' }` | |
2027
+
2028
+ ## Zoom (v4.3)
2029
+
2030
+ Utilities for controlling the zoom level of an element.
2031
+
2032
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2033
+ | :----------- | :--------------- | :---------------- | :------------------------ | :--- |
2034
+ | **Scale** | `zoom: <number>` | `zoom-<number>` | `{ zoom: <number> }` | |
2035
+ | **Variable** | `zoom: var(--z)` | `zoom-(--z)` | `{ zoom: '--z' }` | |
2036
+
2037
+ ## Tab Size (v4.3)
2038
+
2039
+ Utilities for controlling the width of tab characters.
2040
+
2041
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2042
+ | :------------ | :------------------- | :---------------- | :------------------------ | :--- |
2043
+ | **Number** | `tab-size: <number>` | `tab-<number>` | `{ tabSize: <number> }` | |
2044
+ | **Arbitrary** | `tab-size: <v>` | `tab-[<v>]` | `{ tabSize: '<v>' }` | |
2045
+ | **Variable** | `tab-size: var(--t)` | `tab-(--t)` | `{ tabSize: '--t' }` | |
2046
+
2047
+
2048
+ # Layout
2049
+
2050
+ Controlling element positioning and visibility.
2051
+
2052
+ ## Aspect Ratio
2053
+
2054
+ Setting aspect ratios.
2055
+
2056
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2057
+ | :--------------- | :---------------------------------- | :----------------------- | :---------------------------- | :----------------------------------------------------------- |
2058
+ | **Auto** | `aspect-ratio: auto` | `aspect-auto` | `{ aspect: 'auto' }` | |
2059
+ | **Square** | `aspect-ratio: 1 / 1` | `aspect-square` | `{ aspect: 'square' }` | |
2060
+ | **Video** | `aspect-ratio: 16 / 9` | `aspect-video` | `{ aspect: 'video' }` | |
2061
+ | **Arbitrary** | `aspect-ratio: 4 / 3` | `aspect-4/3` | `{ aspect: '4/3' }` | **Sugar**: Auto-detects fraction syntax only integer values. |
2062
+ | **Arbitrary** | `aspect-ratio: 4 / 2.5` | `aspect-[4/2.5]` | `{ aspect: '4/2.5' }` | Decimal values require brackets. |
2063
+ | **Arbitrary** | `aspect-ratio: calc(4 * 3 + 1) / 3` | `aspect-[calc(4*3+1)/3]` | `{ aspect: 'calc(4*3+1)/3' }` | |
2064
+ | **CSS Variable** | `aspect-ratio: var(--my-ratio)` | `aspect-(--my-ratio)` | `{ aspect: '--my-ratio' }` | **Sugar**: Auto-detects `--`. |
2065
+
2066
+ ## Columns
2067
+
2068
+ Multi-column layout.
2069
+
2070
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2071
+ | :--------------- | :---------------------- | :------------------ | :------------------------ | :---------------------------------------------------------- |
2072
+ | **Auto** | `columns: auto` | `columns-auto` | `{ columns: 'auto' }` | |
2073
+ | **Count (1-12)** | `columns: <number>` | `columns-<number>` | `{ columns: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
2074
+ | **Width (3xs)** | `columns: 16rem` | `columns-3xs` | `{ columns: '3xs' }` | |
2075
+ | **Width (2xs)** | `columns: 18rem` | `columns-2xs` | `{ columns: '2xs' }` | |
2076
+ | **Width (xs)** | `columns: 20rem` | `columns-xs` | `{ columns: 'xs' }` | |
2077
+ | **Width (sm)** | `columns: 24rem` | `columns-sm` | `{ columns: 'sm' }` | |
2078
+ | **Width (md)** | `columns: 28rem` | `columns-md` | `{ columns: 'md' }` | |
2079
+ | **Width (lg)** | `columns: 32rem` | `columns-lg` | `{ columns: 'lg' }` | |
2080
+ | **Width (xl)** | `columns: 36rem` | `columns-xl` | `{ columns: 'xl' }` | |
2081
+ | **Width (2xl)** | `columns: 42rem` | `columns-2xl` | `{ columns: '2xl' }` | |
2082
+ | **Width (3xl)** | `columns: 48rem` | `columns-3xl` | `{ columns: '3xl' }` | |
2083
+ | **Width (4xl)** | `columns: 56rem` | `columns-4xl` | `{ columns: '4xl' }` | |
2084
+ | **Width (5xl)** | `columns: 64rem` | `columns-5xl` | `{ columns: '5xl' }` | |
2085
+ | **Width (6xl)** | `columns: 72rem` | `columns-6xl` | `{ columns: '6xl' }` | |
2086
+ | **Width (7xl)** | `columns: 80rem` | `columns-7xl` | `{ columns: '7xl' }` | |
2087
+ | **Arbitrary** | `columns: 14rem` | `columns-[14rem]` | `{ columns: '14rem' }` | |
2088
+ | **CSS Variable** | `columns: var(--width)` | `columns-(--width)` | `{ columns: '--width' }` | **Sugar**: Auto-detects `--`. |
2089
+
2090
+ ## Break After
2091
+
2092
+ Controlling page/column breaks after an element.
2093
+
2094
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2095
+ | :------------- | :------------------------ | :----------------------- | :----------------------------- | :--- |
2096
+ | **Auto** | `break-after: auto` | `break-after-auto` | `{ breakAfter: 'auto' }` | |
2097
+ | **Avoid** | `break-after: avoid` | `break-after-avoid` | `{ breakAfter: 'avoid' }` | |
2098
+ | **All** | `break-after: all` | `break-after-all` | `{ breakAfter: 'all' }` | |
2099
+ | **Avoid Page** | `break-after: avoid-page` | `break-after-avoid-page` | `{ breakAfter: 'avoid-page' }` | |
2100
+ | **Page** | `break-after: page` | `break-after-page` | `{ breakAfter: 'page' }` | |
2101
+ | **Left** | `break-after: left` | `break-after-left` | `{ breakAfter: 'left' }` | |
2102
+ | **Right** | `break-after: right` | `break-after-right` | `{ breakAfter: 'right' }` | |
2103
+ | **Column** | `break-after: column` | `break-after-column` | `{ breakAfter: 'column' }` | |
2104
+
2105
+ ## Break Before
2106
+
2107
+ Controlling page/column breaks before an element.
2108
+
2109
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2110
+ | :------------- | :------------------------- | :------------------------ | :------------------------------ | :--- |
2111
+ | **Auto** | `break-before: auto` | `break-before-auto` | `{ breakBefore: 'auto' }` | |
2112
+ | **Avoid** | `break-before: avoid` | `break-before-avoid` | `{ breakBefore: 'avoid' }` | |
2113
+ | **All** | `break-before: all` | `break-before-all` | `{ breakBefore: 'all' }` | |
2114
+ | **Avoid Page** | `break-before: avoid-page` | `break-before-avoid-page` | `{ breakBefore: 'avoid-page' }` | |
2115
+ | **Page** | `break-before: page` | `break-before-page` | `{ breakBefore: 'page' }` | |
2116
+ | **Left** | `break-before: left` | `break-before-left` | `{ breakBefore: 'left' }` | |
2117
+ | **Right** | `break-before: right` | `break-before-right` | `{ breakBefore: 'right' }` | |
2118
+ | **Column** | `break-before: column` | `break-before-column` | `{ breakBefore: 'column' }` | |
2119
+
2120
+ ## Break Inside
2121
+
2122
+ Controlling page/column breaks within an element.
2123
+
2124
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2125
+ | :--------------- | :--------------------------- | :-------------------------- | :-------------------------------- | :--- |
2126
+ | **Auto** | `break-inside: auto` | `break-inside-auto` | `{ breakInside: 'auto' }` | |
2127
+ | **Avoid** | `break-inside: avoid` | `break-inside-avoid` | `{ breakInside: 'avoid' }` | |
2128
+ | **Avoid Page** | `break-inside: avoid-page` | `break-inside-avoid-page` | `{ breakInside: 'avoid-page' }` | |
2129
+ | **Avoid Column** | `break-inside: avoid-column` | `break-inside-avoid-column` | `{ breakInside: 'avoid-column' }` | |
2130
+
2131
+ ## Box Decoration Break
2132
+
2133
+ Controlling box decoration fragments.
2134
+
2135
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2136
+ | :-------- | :---------------------------- | :--------------------- | :--------------------------- | :------------------------------ |
2137
+ | **Slice** | `box-decoration-break: slice` | `box-decoration-slice` | `{ boxDecoration: 'slice' }` | **Sugar**: Shortened prop name. |
2138
+ | **Clone** | `box-decoration-break: clone` | `box-decoration-clone` | `{ boxDecoration: 'clone' }` | |
2139
+
2140
+ ## Box Sizing
2141
+
2142
+ Controlling box model sizing.
2143
+
2144
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2145
+ | :-------------- | :------------------------ | :---------------- | :------------------------ | :--- |
2146
+ | **Border Box** | `box-sizing: border-box` | `box-border` | `{ box: 'border' }` | |
2147
+ | **Content Box** | `box-sizing: content-box` | `box-content` | `{ box: 'content' }` | |
2148
+
2149
+ ## Display
2150
+
2151
+ Controlling display box type.
2152
+
2153
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | `sz` Prop (Boolean Sugar) |
2154
+ | :--------------------- | :---------------------------- | :------------------- | :---------------------------------- | :--------------------------- |
2155
+ | **Block** | `display: block` | `block` | `{ display: 'block' }` | `{ block: true }` |
2156
+ | **Inline Block** | `display: inline-block` | `inline-block` | `{ display: 'inline-block' }` | `{ inlineBlock: true }` |
2157
+ | **Inline** | `display: inline` | `inline` | `{ display: 'inline' }` | `{ inline: true }` |
2158
+ | **Flex** | `display: flex` | `flex` | `{ display: 'flex' }` | `{ flex: true }` |
2159
+ | **Inline Flex** | `display: inline-flex` | `inline-flex` | `{ display: 'inline-flex' }` | `{ inlineFlex: true }` |
2160
+ | **Grid** | `display: grid` | `grid` | `{ display: 'grid' }` | `{ grid: true }` |
2161
+ | **Inline Grid** | `display: inline-grid` | `inline-grid` | `{ display: 'inline-grid' }` | `{ inlineGrid: true }` |
2162
+ | **Contents** | `display: contents` | `contents` | `{ display: 'contents' }` | `{ contents: true }` |
2163
+ | **Table** | `display: table` | `table` | `{ display: 'table' }` | `{ table: true }` |
2164
+ | **Inline Table** | `display: inline-table` | `inline-table` | `{ display: 'inline-table' }` | `{ inlineTable: true }` |
2165
+ | **Table Caption** | `display: table-caption` | `table-caption` | `{ display: 'table-caption' }` | `{ tableCaption: true }` |
2166
+ | **Table Cell** | `display: table-cell` | `table-cell` | `{ display: 'table-cell' }` | `{ tableCell: true }` |
2167
+ | **Table Column** | `display: table-column` | `table-column` | `{ display: 'table-column' }` | `{ tableColumn: true }` |
2168
+ | **Table Column Group** | `display: table-column-group` | `table-column-group` | `{ display: 'table-column-group' }` | `{ tableColumnGroup: true }` |
2169
+ | **Table Footer Group** | `display: table-footer-group` | `table-footer-group` | `{ display: 'table-footer-group' }` | `{ tableFooterGroup: true }` |
2170
+ | **Table Header Group** | `display: table-header-group` | `table-header-group` | `{ display: 'table-header-group' }` | `{ tableHeaderGroup: true }` |
2171
+ | **Table Row Group** | `display: table-row-group` | `table-row-group` | `{ display: 'table-row-group' }` | `{ tableRowGroup: true }` |
2172
+ | **Table Row** | `display: table-row` | `table-row` | `{ display: 'table-row' }` | `{ tableRow: true }` |
2173
+ | **Flow Root** | `display: flow-root` | `flow-root` | `{ display: 'flow-root' }` | `{ flowRoot: true }` |
2174
+ | **List Item** | `display: list-item` | `list-item` | `{ display: 'list-item' }` | `{ listItem: true }` |
2175
+ | **Hidden** | `display: none` | `hidden` | `{ display: 'none' }` | `{ hidden: true }` |
2176
+ | **Screen Reader Only** | `position: absolute; ...` | `sr-only` | N/A | `{ srOnly: true }` |
2177
+ | **Not Screen Reader** | `position: static; ...` | `not-sr-only` | N/A | `{ notSrOnly: true }` |
2178
+
2179
+ ## Floats
2180
+
2181
+ Controlling floated elements.
2182
+
2183
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2184
+ | :-------- | :-------------------- | :---------------- | :------------------------ | :--- |
2185
+ | **Right** | `float: right` | `float-right` | `{ float: 'right' }` | |
2186
+ | **Left** | `float: left` | `float-left` | `{ float: 'left' }` | |
2187
+ | **Start** | `float: inline-start` | `float-start` | `{ float: 'start' }` | |
2188
+ | **End** | `float: inline-end` | `float-end` | `{ float: 'end' }` | |
2189
+ | **None** | `float: none` | `float-none` | `{ float: 'none' }` | |
2190
+
2191
+ ## Clear
2192
+
2193
+ Controlling flow relative to floats.
2194
+
2195
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2196
+ | :-------- | :-------------------- | :---------------- | :------------------------ | :--- |
2197
+ | **Left** | `clear: left` | `clear-left` | `{ clear: 'left' }` | |
2198
+ | **Right** | `clear: right` | `clear-right` | `{ clear: 'right' }` | |
2199
+ | **Both** | `clear: both` | `clear-both` | `{ clear: 'both' }` | |
2200
+ | **None** | `clear: none` | `clear-none` | `{ clear: 'none' }` | |
2201
+ | **Start** | `clear: inline-start` | `clear-start` | `{ clear: 'start' }` | |
2202
+ | **End** | `clear: inline-end` | `clear-end` | `{ clear: 'end' }` | |
2203
+
2204
+ ## Isolation
2205
+
2206
+ Controlling stacking contexts.
2207
+
2208
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2209
+ | :---------- | :------------------- | :---------------- | :------------------------- | :------------------------------ |
2210
+ | **Isolate** | `isolation: isolate` | `isolate` | `{ isolation: 'isolate' }` | **Sugar**: `{ isolate: true }`. |
2211
+ | **Auto** | `isolation: auto` | `isolation-auto` | `{ isolation: 'auto' }` | |
2212
+
2213
+ ## Object Fit
2214
+
2215
+ Controlling replaced element content.
2216
+
2217
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2218
+ | :------------- | :----------------------- | :------------------ | :---------------------------- | :--- |
2219
+ | **Contain** | `object-fit: contain` | `object-contain` | `{ objectFit: 'contain' }` | |
2220
+ | **Cover** | `object-fit: cover` | `object-cover` | `{ objectFit: 'cover' }` | |
2221
+ | **Fill** | `object-fit: fill` | `object-fill` | `{ objectFit: 'fill' }` | |
2222
+ | **None** | `object-fit: none` | `object-none` | `{ objectFit: 'none' }` | |
2223
+ | **Scale Down** | `object-fit: scale-down` | `object-scale-down` | `{ objectFit: 'scale-down' }` | |
2224
+
2225
+ ## Object Position
2226
+
2227
+ Controlling replaced element alignment.
2228
+
2229
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2230
+ | :--------------- | :------------------------------ | :-------------------- | :------------------------------ | :---------------------------- |
2231
+ | **Top Left** | `object-position: top-left` | `object-top-left` | `{ objectPos: 'top-left' }` | |
2232
+ | **Top** | `object-position: top` | `object-top` | `{ objectPos: 'top' }` | |
2233
+ | **Top Right** | `object-position: top-right` | `object-top-right` | `{ objectPos: 'top-right' }` | |
2234
+ | **Left** | `object-position: left` | `object-left` | `{ objectPos: 'left' }` | |
2235
+ | **Center** | `object-position: center` | `object-center` | `{ objectPos: 'center' }` | |
2236
+ | **Right** | `object-position: right` | `object-right` | `{ objectPos: 'right' }` | |
2237
+ | **Bottom Left** | `object-position: bottom-left` | `object-bottom-left` | `{ objectPos: 'bottom-left' }` | |
2238
+ | **Bottom** | `object-position: bottom` | `object-bottom` | `{ objectPos: 'bottom' }` | |
2239
+ | **Right Bottom** | `object-position: bottom-right` | `object-bottom-right` | `{ objectPos: 'bottom-right' }` | |
2240
+ | **Arbitrary** | `object-position: 50% 50%` | `object-[50%_50%]` | `{ objectPos: '50% 50%' }` | |
2241
+ | **CSS Variable** | `object-position: var(--pos)` | `object-(--pos)` | `{ objectPos: '--pos' }` | **Sugar**: Auto-detects `--`. |
2242
+
2243
+ ## Overflow
2244
+
2245
+ Controlling content overflow.
2246
+
2247
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2248
+ | :------------ | :-------------------- | :------------------- | :------------------------- | :--- |
2249
+ | **Auto** | `overflow: auto` | `overflow-auto` | `{ overflow: 'auto' }` | |
2250
+ | **Hidden** | `overflow: hidden` | `overflow-hidden` | `{ overflow: 'hidden' }` | |
2251
+ | **Clip** | `overflow: clip` | `overflow-clip` | `{ overflow: 'clip' }` | |
2252
+ | **Visible** | `overflow: visible` | `overflow-visible` | `{ overflow: 'visible' }` | |
2253
+ | **Scroll** | `overflow: scroll` | `overflow-scroll` | `{ overflow: 'scroll' }` | |
2254
+ | **X Auto** | `overflow-x: auto` | `overflow-x-auto` | `{ overflowX: 'auto' }` | |
2255
+ | **X Hidden** | `overflow-x: hidden` | `overflow-x-hidden` | `{ overflowX: 'hidden' }` | |
2256
+ | **X Clip** | `overflow-x: clip` | `overflow-x-clip` | `{ overflowX: 'clip' }` | |
2257
+ | **X Visible** | `overflow-x: visible` | `overflow-x-visible` | `{ overflowX: 'visible' }` | |
2258
+ | **X Scroll** | `overflow-x: scroll` | `overflow-x-scroll` | `{ overflowX: 'scroll' }` | |
2259
+ | **Y Auto** | `overflow-y: auto` | `overflow-y-auto` | `{ overflowY: 'auto' }` | |
2260
+ | **Y Hidden** | `overflow-y: hidden` | `overflow-y-hidden` | `{ overflowY: 'hidden' }` | |
2261
+ | **Y Clip** | `overflow-y: clip` | `overflow-y-clip` | `{ overflowY: 'clip' }` | |
2262
+ | **Y Visible** | `overflow-y: visible` | `overflow-y-visible` | `{ overflowY: 'visible' }` | |
2263
+ | **Y Scroll** | `overflow-y: scroll` | `overflow-y-scroll` | `{ overflowY: 'scroll' }` | |
2264
+
2265
+ ## Overscroll Behavior
2266
+
2267
+ Controlling scroll chaining.
2268
+
2269
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2270
+ | :------------ | :------------------------------- | :--------------------- | :--------------------------- | :--- |
2271
+ | **Auto** | `overscroll-behavior: auto` | `overscroll-auto` | `{ overscroll: 'auto' }` | |
2272
+ | **Contain** | `overscroll-behavior: contain` | `overscroll-contain` | `{ overscroll: 'contain' }` | |
2273
+ | **None** | `overscroll-behavior: none` | `overscroll-none` | `{ overscroll: 'none' }` | |
2274
+ | **X Auto** | `overscroll-behavior-x: auto` | `overscroll-x-auto` | `{ overscrollX: 'auto' }` | |
2275
+ | **X Contain** | `overscroll-behavior-x: contain` | `overscroll-x-contain` | `{ overscrollX: 'contain' }` | |
2276
+ | **X None** | `overscroll-behavior-x: none` | `overscroll-x-none` | `{ overscrollX: 'none' }` | |
2277
+ | **Y Auto** | `overscroll-behavior-y: auto` | `overscroll-y-auto` | `{ overscrollY: 'auto' }` | |
2278
+ | **Y Contain** | `overscroll-behavior-y: contain` | `overscroll-y-contain` | `{ overscrollY: 'contain' }` | |
2279
+ | **Y None** | `overscroll-behavior-y: none` | `overscroll-y-none` | `{ overscrollY: 'none' }` | |
2280
+
2281
+ ## Position
2282
+
2283
+ Controlling positioning.
2284
+
2285
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | `sz` Prop (Boolean Sugar) |
2286
+ | :----------- | :------------------- | :---------------- | :------------------------- | :------------------------ |
2287
+ | **Static** | `position: static` | `static` | `{ position: 'static' }` | `{ static: true }` |
2288
+ | **Fixed** | `position: fixed` | `fixed` | `{ position: 'fixed' }` | `{ fixed: true }` |
2289
+ | **Absolute** | `position: absolute` | `absolute` | `{ position: 'absolute' }` | `{ absolute: true }` |
2290
+ | **Relative** | `position: relative` | `relative` | `{ position: 'relative' }` | `{ relative: true }` |
2291
+ | **Sticky** | `position: sticky` | `sticky` | `{ position: 'sticky' }` | `{ sticky: true }` |
2292
+
2293
+ ## Top / Right / Bottom / Left (Placement)
2294
+
2295
+ Positioning mapped elements.
2296
+
2297
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2298
+ | :-------------------------- | :------------------------------------------------ | :------------------ | :------------------------- | :------------------------------------------------------------------------------- |
2299
+ | **Inset** | `inset: calc(var(--spacing) * <number>)` | `inset-<number>` | `{ inset: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2300
+ | **Inset Negative** | `inset: calc(var(--spacing) * -<number>)` | `-inset-<number>` | `{ inset: -<number> }` | v4: accept any negative integer or 0.5-step decimal bare. |
2301
+ | **Inset Fraction** | `inset: calc(<fraction> * 100%)` | `inset-<fraction>` | `{ inset: '<fraction>' }` | v4: accept any integer/integer fraction (string) bare. |
2302
+ | **Inset Fraction Negative** | `inset: calc(<fraction> * -100%)` | `-inset-<fraction>` | `{ inset: '-<fraction>' }` | v4: accept any negative integer/integer fraction (string) bare. |
2303
+ | **Inset Pixel** | `inset: 1px` | `inset-px` | `{ inset: 'px' }` | |
2304
+ | **Inset Pixel Negative** | `inset: -1px` | `-inset-px` | `{ inset: '-px' }` | |
2305
+ | **Inset Full** | `inset: 100%` | `inset-full` | `{ inset: 'full' }` | |
2306
+ | **Inset Full Negative** | `inset: -100%` | `-inset-full` | `{ inset: '-full' }` | |
2307
+ | **Inset Auto** | `inset: auto` | `inset-auto` | `{ inset: 'auto' }` | |
2308
+ | **Inset Arbitrary** | `inset: 27px` | `inset-[27px]` | `{ inset: '27px' }` | |
2309
+ | **Inset CSS Variable** | `inset: var(--inset)` | `inset-(--inset)` | `{ inset: '--inset' }` | |
2310
+ | **Inset X** | `inset-inline: calc(var(--spacing) * <number>);` | `inset-x-<number>` | `{ insetX: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2311
+ | **Inset X Negative** | `inset-inline: calc(var(--spacing) * -<number>);` | `-inset-x-<number>` | `{ insetX: -<number> }` | v4: accept any integer or 0.5-step decimal bare. |
2312
+
2313
+ | **Inset Y** | `inset-block: calc(var(--spacing) * <number>);` | `inset-y-<number>` | `{ insetY: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2314
+
2315
+ | **Start (L)** | `inset-inline-start: ...` | `inset-s-<number>` | `{ start: <number> }` | v4.2: emits `inset-s-*` (was `start-*`, same CSS, deprecated in TW v4.2). |
2316
+ | **End (R)** | `inset-inline-end: ...` | `inset-e-<number>` | `{ end: <number> }` | v4.2: emits `inset-e-*` (was `end-*`, same CSS, deprecated in TW v4.2). |
2317
+ | **Inset S** | `inset-inline-start: ...` | `inset-s-<number>` | `{ insetS: <number> }` | v4.2: explicit camelCase alias for `start`. |
2318
+ | **Inset E** | `inset-inline-end: ...` | `inset-e-<number>` | `{ insetE: <number> }` | v4.2: explicit camelCase alias for `end`. |
2319
+ | **Inset Block Start** | `inset-block-start: ...` | `inset-bs-<number>` | `{ insetBs: <number> }` | v4.2: logical block-start inset. |
2320
+ | **Inset Block End** | `inset-block-end: ...` | `inset-be-<number>` | `{ insetBe: <number> }` | v4.2: logical block-end inset. |
2321
+
2322
+ | **Top** | `top: calc(var(--spacing) * <number>)` | `top-<number>` | `{ top: <number> }` | |
2323
+ | **Top Negative** | `top: calc(var(--spacing) * -<number>)` | `-top-<number>` | `{ top: -<number> }` | |
2324
+ | **Top Arbitrary** | `top: -1px` | `top-[-1px]` | `{ top: '-1px' }` | No `[]` needed in sz — compiler auto-wraps. |
2325
+ | **Top CSS Variable** | `top: var(--offset)` | `top-(--offset)` | `{ top: '--offset' }` | |
2326
+
2327
+ | **Right** | `right: calc(var(--spacing) * <number>)` | `right-<number>` | `{ right: <number> }` | |
2328
+ | **Right Negative** | `right: calc(var(--spacing) * -<number>)` | `-right-<number>` | `{ right: -<number> }` | |
2329
+ | **Right Arbitrary** | `right: -1px` | `right-[-1px]` | `{ right: '-1px' }` | No `[]` needed in sz — compiler auto-wraps. |
2330
+ | **Right CSS Variable** | `right: var(--offset)` | `right-(--offset)` | `{ right: '--offset' }` | |
2331
+
2332
+ | **Bottom** | `bottom: calc(var(--spacing) * <number>)` | `bottom-<number>` | `{ bottom: <number> }` | |
2333
+ | **Bottom Negative** | `bottom: calc(var(--spacing) * -<number>)` | `-bottom-<number>` | `{ bottom: -<number> }` | |
2334
+ | **Bottom Arbitrary** | `bottom: -1px` | `bottom-[-1px]` | `{ bottom: '-1px' }` | No `[]` needed in sz — compiler auto-wraps. |
2335
+ | **Bottom CSS Variable** | `bottom: var(--offset)` | `bottom-(--offset)` | `{ bottom: '--offset' }` | |
2336
+
2337
+ | **Left** | `left: calc(var(--spacing) * <number>)` | `left-<number>` | `{ left: <number> }` | |
2338
+ | **Left Negative** | `left: calc(var(--spacing) * -<number>)` | `-left-<number>` | `{ left: -<number> }` | |
2339
+ | **Left Arbitrary** | `left: -1px` | `left-[-1px]` | `{ left: '-1px' }` | No `[]` needed in sz — compiler auto-wraps. |
2340
+ | **Left CSS Variable** | `left: var(--offset)` | `left-(--offset)` | `{ left: '--offset' }` | |
2341
+
2342
+ ## Visibility
2343
+
2344
+ Controlling visibility without layout change.
2345
+
2346
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Canonical) | `sz` Prop (Boolean) |
2347
+ | :------------ | :--------------------- | :---------------- | :--------------------------- | :-------------------- |
2348
+ | **Visible** | `visibility: visible` | `visible` | `{ visibility: 'visible' }` | `{ visible: true }` |
2349
+ | **Invisible** | `visibility: hidden` | `invisible` | `{ visibility: 'hidden' }` | `{ invisible: true }` |
2350
+ | **Collapse** | `visibility: collapse` | `collapse` | `{ visibility: 'collapse' }` | `{ collapse: true }` |
2351
+
2352
+ ## Z-Index
2353
+
2354
+ Controlling stack order.
2355
+
2356
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2357
+ | :--------------- | :-------------------------------- | :--------------------------- | :-------------------------------- | :---------------------------------------------------------- |
2358
+ | **Index** | `z-index: <number>` | `z-<number>` | `{ z: <number> }` | v4: fully dynamic, no static scale, accept any integer bare |
2359
+ | **Negative** | `z-index: -<number>` | `-z-<number>` | `{ z: -<number> }` | v4: fully dynamic, no static scale, accept any integer bare |
2360
+ | **Auto** | `z-index: auto` | `z-auto` | `{ z: 'auto' }` | |
2361
+ | **Arbitrary** | `z-index: calc(var(--index) + 1)` | `z-[calc(var(--index)_+_1)]` | `{ z: 'calc(var(--index) + 1)' }` | |
2362
+ | **CSS Variable** | `z-index: var(--my-z)` | `z-(--my-z)` | `{ z: '--my-z' }` | |
2363
+
2364
+
2365
+ # Misc Utilities
2366
+
2367
+ ## SVG
2368
+
2369
+ Utilities for controlling the appearance of SVG elements.
2370
+
2371
+ ### Fill
2372
+
2373
+ Utilities for controlling the fill color of SVG elements.
2374
+
2375
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2376
+ | :------------ | :-------------------- | :----------------- | :------------------------ | :--- |
2377
+ | **Color** | `fill: ...` | `fill-red-500` | `{ fill: 'red-500' }` | |
2378
+ | **None** | `fill: none;` | `fill-none` | `{ fill: 'none' }` | |
2379
+ | **Pick** | `fill: inherit;` | `fill-inherit` | `{ fill: 'inherit' }` | |
2380
+ | **Pick** | `fill: currentColor;` | `fill-current` | `{ fill: 'current' }` | |
2381
+ | **Pick** | `fill: transparent;` | `fill-transparent` | `{ fill: 'transparent' }` | |
2382
+ | **Arbitrary** | `fill: #50d71e` | `fill-[#50d71e]` | `{ fill: '#50d71e' }` | |
2383
+ | **Variable** | `fill: var(--c)` | `fill-(--c)` | `{ fill: '--c' }` | |
2384
+
2385
+ ### Stroke
2386
+
2387
+ Utilities for controlling the stroke color of SVG elements.
2388
+
2389
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2390
+ | :------------ | :---------------------- | :------------------- | :-------------------------- | :--- |
2391
+ | **Color** | `stroke: ...` | `stroke-red-500` | `{ stroke: 'red-500' }` | |
2392
+ | **None** | `stroke: none;` | `stroke-none` | `{ stroke: 'none' }` | |
2393
+ | **Pick** | `stroke: inherit;` | `stroke-inherit` | `{ stroke: 'inherit' }` | |
2394
+ | **Pick** | `stroke: currentColor;` | `stroke-current` | `{ stroke: 'current' }` | |
2395
+ | **Pick** | `stroke: transparent;` | `stroke-transparent` | `{ stroke: 'transparent' }` | |
2396
+ | **Arbitrary** | `stroke: #50d71e` | `stroke-[#50d71e]` | `{ stroke: '#50d71e' }` | |
2397
+ | **Variable** | `stroke: var(--c)` | `stroke-(--c)` | `{ stroke: '--c' }` | |
2398
+
2399
+ ### Stroke Width
2400
+
2401
+ Utilities for controlling the stroke width of SVG elements.
2402
+
2403
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2404
+ | :------------ | :----------------------- | :---------------- | :-------------------------- | :----------------------------------------------------------- |
2405
+ | **Scale** | `stroke-width: <number>` | `stroke-<number>` | `{ strokeWidth: <number> }` | v4: fully dynamic, no static scale, accept any integer bare. |
2406
+ | **Arbitrary** | `stroke-width: 0.5` | `stroke-[0.5]` | `{ strokeWidth: 0.5 }` | decimal |
2407
+ | **Arbitrary** | `stroke-width: 0.5rem` | `stroke-[0.5rem]` | `{ strokeWidth: '0.5rem' }` | CSS unit |
2408
+ | **Variable** | `stroke-width: var(--w)` | `stroke-(--w)` | `{ strokeWidth: '--w' }` | **Sugar**: Auto-detects `--`. |
2409
+
2410
+ ## Accessibility
2411
+
2412
+ Utilities for controlling accessibility-related properties.
2413
+
2414
+ ### Forced Color Adjust
2415
+
2416
+ Utilities for controlling whether browsers should automatically adjust element colors in high contrast modes.
2417
+
2418
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2419
+ | :------- | :--------------------------- | :------------------------- | :------------------------------ | :--- |
2420
+ | **Auto** | `forced-color-adjust: auto;` | `forced-color-adjust-auto` | `{ forcedColorAdjust: 'auto' }` | |
2421
+ | **None** | `forced-color-adjust: none;` | `forced-color-adjust-none` | `{ forcedColorAdjust: 'none' }` | |
2422
+
2423
+ ---
2424
+
2425
+ ## `css: {}` — Arbitrary CSS Escape Hatch
2426
+
2427
+ For CSS properties with no `sz` prop or Tailwind utility equivalent.
2428
+ Each key-value pair in the `css` object generates a Tailwind arbitrary-property class `[prop:value]`.
2429
+ Keys are camelCase CSS properties; the compiler converts them to kebab-case automatically.
2430
+ CSS custom properties (`--*`) are passed through unchanged.
2431
+
2432
+ **TypeScript:** `css?` is typed as `CSS.Properties & { [cssVar: \`--${string}\`]: string | number }` — full IDE autocomplete and typo protection.
2433
+
2434
+ | Concept | Example `sz` Prop | Output Class | Note |
2435
+ | :------------------ | :------------------------------------------------ | :------------------------------ | :----------------------------- |
2436
+ | **Regular prop** | `{ css: { writingMode: 'vertical-lr' } }` | `[writing-mode:vertical-lr]` | camelCase → kebab-case |
2437
+ | **Multi-word** | `{ css: { touchAction: 'none' } }` | `[touch-action:none]` | |
2438
+ | **CSS custom prop** | `{ css: { '--my-color': 'red' } }` | `[--my-color:red]` | `--*` passed through unchanged |
2439
+ | **Inside variant** | `{ hover: { css: { cursor: 'crosshair' } } }` | `hover:[cursor:crosshair]` | works in all variants |
2440
+ | **Responsive** | `{ md: { css: { writingMode: 'vertical-lr' } } }` | `md:[writing-mode:vertical-lr]` | |
2441
+ | **Numeric value** | `{ css: { zIndex: 10 } }` | `[z-index:10]` | numbers coerced to string |
2442
+
2443
+ ### Notes
2444
+
2445
+ - `css: {}` is intentional bypass — no sz-layer mapping applied. `{ css: { backgroundColor: 'red' } }` outputs `[background-color:red]`, not `bg-red`.
2446
+ - Spaces in values are normalised to underscores: `repeat(3, 1fr)` → `repeat(3,_1fr)`.
2447
+ - Works inside `dynamic()` at runtime — the same compiler logic handles the `css` key.
2448
+
2449
+
2450
+ # Sizing
2451
+
2452
+ Controlling the width and height of elements.
2453
+
2454
+ ## Width
2455
+
2456
+ Controlling the width.
2457
+
2458
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2459
+ | :----------------- | :--------------------------------------- | :---------------- | :------------------------ | :------------------------------------------------------------- |
2460
+ | **Spacing** | `width: calc(var(--spacing) * <number>)` | `w-<number>` | `{ w: <number> }` | v4: fully dynamic, accept any integer or 0.5-step decimal bare |
2461
+ | **Px** | `width: 1px` | `w-px` | `{ w: 'px' }` | |
2462
+ | **Fraction** | `width: calc(<int>/<int> * 100%)` | `w-<int>/<int>` | `{ w: '<int>/<int>' }` | v4: any integer/integer fraction works bare |
2463
+ | **Full** | `width: 100%` | `w-full` | `{ w: 'full' }` | |
2464
+ | **Screen** | `width: 100vw` | `w-screen` | `{ w: 'screen' }` | |
2465
+ | **Viewport (SVW)** | `width: 100svw` | `w-svw` | `{ w: 'svw' }` | |
2466
+ | **Viewport (LVW)** | `width: 100lvw` | `w-lvw` | `{ w: 'lvw' }` | |
2467
+ | **Viewport (DVW)** | `width: 100dvw` | `w-dvw` | `{ w: 'dvw' }` | |
2468
+ | **Min Content** | `width: min-content` | `w-min` | `{ w: 'min' }` | |
2469
+ | **Max Content** | `width: max-content` | `w-max` | `{ w: 'max' }` | |
2470
+ | **Fit Content** | `width: fit-content` | `w-fit` | `{ w: 'fit' }` | |
2471
+ | **Auto** | `width: auto` | `w-auto` | `{ w: 'auto' }` | |
2472
+ | **Arbitrary** | `width: 27px` | `w-[27px]` | `{ w: '27px' }` | |
2473
+ | **CSS Variable** | `width: var(--w)` | `w-(--w)` | `{ w: '--w' }` | **Sugar**: Auto-detects `--`. |
2474
+
2475
+ ## Min Width
2476
+
2477
+ Controlling the minimum width.
2478
+
2479
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2480
+ | :--------------- | :------------------------------------------- | :------------------ | :------------------------ | :------------------------------------------------------------- |
2481
+ | **Spacing** | `min-width: calc(var(--spacing) * <number>)` | `min-w-<number>` | `{ minW: <number> }` | v4: fully dynamic, accept any integer or 0.5-step decimal bare |
2482
+ | **Px** | `min-width: 1px` | `min-w-px` | `{ minW: 'px' }` | |
2483
+ | **Fraction** | `min-width: calc(<int>/<int> * 100%)` | `min-w-<int>/<int>` | `{ minW: '<int>/<int>' }` | v4: any integer/integer fraction works bare |
2484
+ | **Full** | `min-width: 100%` | `min-w-full` | `{ minW: 'full' }` | |
2485
+ | **Min Content** | `min-width: min-content` | `min-w-min` | `{ minW: 'min' }` | |
2486
+ | **Max Content** | `min-width: max-content` | `min-w-max` | `{ minW: 'max' }` | |
2487
+ | **Fit Content** | `min-width: fit-content` | `min-w-fit` | `{ minW: 'fit' }` | |
2488
+ | **Arbitrary** | `min-width: 3px` | `min-w-[3px]` | `{ minW: '3px' }` | |
2489
+ | **CSS Variable** | `min-width: var(--w)` | `min-w-(--w)` | `{ minW: '--w' }` | **Sugar**: Auto-detects `--`. |
2490
+
2491
+ ## Max Width
2492
+
2493
+ Controlling the maximum width.
2494
+
2495
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2496
+ | :--------------- | :------------------------------------------- | :------------------ | :------------------------ | :------------------------------------------------------------- |
2497
+ | **Spacing** | `max-width: calc(var(--spacing) * <number>)` | `max-w-<number>` | `{ maxW: <number> }` | v4: fully dynamic, accept any integer or 0.5-step decimal bare |
2498
+ | **Px** | `max-width: 1px` | `max-w-px` | `{ maxW: 'px' }` | |
2499
+ | **Fraction** | `max-width: calc(<int>/<int> * 100%)` | `max-w-<int>/<int>` | `{ maxW: '<int>/<int>' }` | v4: any integer/integer fraction works bare |
2500
+ | **Full** | `max-width: 100%` | `max-w-full` | `{ maxW: 'full' }` | |
2501
+ | **None** | `max-width: none` | `max-w-none` | `{ maxW: 'none' }` | |
2502
+ | **Prose** | `max-width: 65ch` | `max-w-prose` | `{ maxW: 'prose' }` | Requires `@tailwindcss/typography`. |
2503
+ | **Min Content** | `max-width: min-content` | `max-w-min` | `{ maxW: 'min' }` | |
2504
+ | **Max Content** | `max-width: max-content` | `max-w-max` | `{ maxW: 'max' }` | |
2505
+ | **Fit Content** | `max-width: fit-content` | `max-w-fit` | `{ maxW: 'fit' }` | |
2506
+ | **Arbitrary** | `max-width: 3px` | `max-w-[3px]` | `{ maxW: '3px' }` | |
2507
+ | **CSS Variable** | `max-width: var(--w)` | `max-w-(--w)` | `{ maxW: '--w' }` | **Sugar**: Auto-detects `--`. |
2508
+
2509
+ ### Breakpoints (xs-7xl)
2510
+
2511
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2512
+ | :------ | :----------------- | :---------------- | :------------------------ | :--- |
2513
+ | **XS** | `max-width: 20rem` | `max-w-xs` | `{ maxW: 'xs' }` | |
2514
+ | **SM** | `max-width: 24rem` | `max-w-sm` | `{ maxW: 'sm' }` | |
2515
+ | **MD** | `max-width: 28rem` | `max-w-md` | `{ maxW: 'md' }` | |
2516
+ | **LG** | `max-width: 32rem` | `max-w-lg` | `{ maxW: 'lg' }` | |
2517
+ | **XL** | `max-width: 36rem` | `max-w-xl` | `{ maxW: 'xl' }` | |
2518
+ | **2XL** | `max-width: 42rem` | `max-w-2xl` | `{ maxW: '2xl' }` | |
2519
+ | **3XL** | `max-width: 48rem` | `max-w-3xl` | `{ maxW: '3xl' }` | |
2520
+ | **4XL** | `max-width: 56rem` | `max-w-4xl` | `{ maxW: '4xl' }` | |
2521
+ | **5XL** | `max-width: 64rem` | `max-w-5xl` | `{ maxW: '5xl' }` | |
2522
+ | **6XL** | `max-width: 72rem` | `max-w-6xl` | `{ maxW: '6xl' }` | |
2523
+ | **7XL** | `max-width: 80rem` | `max-w-7xl` | `{ maxW: '7xl' }` | |
2524
+
2525
+ ### Screen Breakpoints
2526
+
2527
+ | Max Width Screen SM | `max-width: 640px` | `max-w-screen-sm` | `{ maxW: 'screen-sm' }` |
2528
+ | Max Width Screen MD | `max-width: 768px` | `max-w-screen-md` | `{ maxW: 'screen-md' }` |
2529
+ | Max Width Screen LG | `max-width: 1024px` | `max-w-screen-lg` | `{ maxW: 'screen-lg' }` |
2530
+ | Max Width Screen XL | `max-width: 1280px` | `max-w-screen-xl` | `{ maxW: 'screen-xl' }` |
2531
+ | Max Width Screen 2XL | `max-width: 1536px` | `max-w-screen-2xl` | `{ maxW: 'screen-2xl' }` |
2532
+
2533
+ ## Height
2534
+
2535
+ Controlling the height.
2536
+
2537
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2538
+ | :----------------- | :---------------------------------------- | :---------------- | :------------------------ | :------------------------------------------------------------- |
2539
+ | **Spacing** | `height: calc(var(--spacing) * <number>)` | `h-<number>` | `{ h: <number> }` | v4: fully dynamic, accept any integer or 0.5-step decimal bare |
2540
+ | **Px** | `height: 1px` | `h-px` | `{ h: 'px' }` | |
2541
+ | **Fraction** | `height: calc(<int>/<int> * 100%)` | `h-<int>/<int>` | `{ h: '<int>/<int>' }` | v4: any integer/integer fraction works bare |
2542
+ | **Full** | `height: 100%` | `h-full` | `{ h: 'full' }` | |
2543
+ | **Screen** | `height: 100vh` | `h-screen` | `{ h: 'screen' }` | |
2544
+ | **Viewport (SVH)** | `height: 100svh` | `h-svh` | `{ h: 'svh' }` | |
2545
+ | **Viewport (LVH)** | `height: 100lvh` | `h-lvh` | `{ h: 'lvh' }` | |
2546
+ | **Viewport (DVH)** | `height: 100dvh` | `h-dvh` | `{ h: 'dvh' }` | |
2547
+ | **Min Content** | `height: min-content` | `h-min` | `{ h: 'min' }` | |
2548
+ | **Max Content** | `height: max-content` | `h-max` | `{ h: 'max' }` | |
2549
+ | **Fit Content** | `height: fit-content` | `h-fit` | `{ h: 'fit' }` | |
2550
+ | **Auto** | `height: auto` | `h-auto` | `{ h: 'auto' }` | |
2551
+ | **Arbitrary** | `height: 3px` | `h-[3px]` | `{ h: '3px' }` | |
2552
+ | **CSS Variable** | `height: var(--h)` | `h-(--h)` | `{ h: '--h' }` | **Sugar**: Auto-detects `--`. |
2553
+
2554
+ ## Min Height
2555
+
2556
+ Controlling the minimum height.
2557
+
2558
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2559
+ | :----------------- | :-------------------------------------------- | :------------------ | :------------------------ | :------------------------------------------------------------- |
2560
+ | **Spacing** | `min-height: calc(var(--spacing) * <number>)` | `min-h-<number>` | `{ minH: <number> }` | v4: fully dynamic, accept any integer or 0.5-step decimal bare |
2561
+ | **Px** | `min-height: 1px` | `min-h-px` | `{ minH: 'px' }` | |
2562
+ | **Fraction** | `min-height: calc(<int>/<int> * 100%)` | `min-h-<int>/<int>` | `{ minH: '<int>/<int>' }` | v4: any integer/integer fraction works bare |
2563
+ | **Full** | `min-height: 100%` | `min-h-full` | `{ minH: 'full' }` | |
2564
+ | **Screen** | `min-height: 100vh` | `min-h-screen` | `{ minH: 'screen' }` | |
2565
+ | **Viewport (SVH)** | `min-height: 100svh` | `min-h-svh` | `{ minH: 'svh' }` | |
2566
+ | **Viewport (LVH)** | `min-height: 100lvh` | `min-h-lvh` | `{ minH: 'lvh' }` | |
2567
+ | **Viewport (DVH)** | `min-height: 100dvh` | `min-h-dvh` | `{ minH: 'dvh' }` | |
2568
+ | **Min Content** | `min-height: min-content` | `min-h-min` | `{ minH: 'min' }` | |
2569
+ | **Max Content** | `min-height: max-content` | `min-h-max` | `{ minH: 'max' }` | |
2570
+ | **Fit Content** | `min-height: fit-content` | `min-h-fit` | `{ minH: 'fit' }` | |
2571
+ | **Arbitrary** | `min-height: 3px` | `min-h-[3px]` | `{ minH: '3px' }` | |
2572
+ | **CSS Variable** | `min-height: var(--h)` | `min-h-(--h)` | `{ minH: '--h' }` | **Sugar**: Auto-detects `--`. |
2573
+
2574
+ ## Max Height
2575
+
2576
+ Controlling the maximum height.
2577
+
2578
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2579
+ | :----------------- | :-------------------------------------------- | :------------------ | :------------------------ | :------------------------------------------------------------- |
2580
+ | **Spacing** | `max-height: calc(var(--spacing) * <number>)` | `max-h-<number>` | `{ maxH: <number> }` | v4: fully dynamic, accept any integer or 0.5-step decimal bare |
2581
+ | **Px** | `max-height: 1px` | `max-h-px` | `{ maxH: 'px' }` | |
2582
+ | **Fraction** | `max-height: calc(<int>/<int> * 100%)` | `max-h-<int>/<int>` | `{ maxH: '<int>/<int>' }` | v4: any integer/integer fraction works bare |
2583
+ | **Full** | `max-height: 100%` | `max-h-full` | `{ maxH: 'full' }` | |
2584
+ | **Screen** | `max-height: 100vh` | `max-h-screen` | `{ maxH: 'screen' }` | |
2585
+ | **Viewport (SVH)** | `max-height: 100svh` | `max-h-svh` | `{ maxH: 'svh' }` | |
2586
+ | **Viewport (LVH)** | `max-height: 100lvh` | `max-h-lvh` | `{ maxH: 'lvh' }` | |
2587
+ | **Viewport (DVH)** | `max-height: 100dvh` | `max-h-dvh` | `{ maxH: 'dvh' }` | |
2588
+ | **Min Content** | `max-height: min-content` | `max-h-min` | `{ maxH: 'min' }` | |
2589
+ | **Max Content** | `max-height: max-content` | `max-h-max` | `{ maxH: 'max' }` | |
2590
+ | **Fit Content** | `max-height: fit-content` | `max-h-fit` | `{ maxH: 'fit' }` | |
2591
+ | **Arbitrary** | `max-height: 3px` | `max-h-[3px]` | `{ maxH: '3px' }` | |
2592
+ | **CSS Variable** | `max-height: var(--h)` | `max-h-(--h)` | `{ maxH: '--h' }` | **Sugar**: Auto-detects `--`. |
2593
+
2594
+ ## Size
2595
+
2596
+ Utilities for setting both the width and height of an element.
2597
+
2598
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2599
+ | :--------------- | :------------------------------------------------ | :----------------- | :------------------------ | :------------------------------------------------------------- |
2600
+ | **Spacing** | `width & height: calc(var(--spacing) * <number>)` | `size-<number>` | `{ size: <number> }` | v4: fully dynamic, accept any integer or 0.5-step decimal bare |
2601
+ | **Px** | `width & height: 1px` | `size-px` | `{ size: 'px' }` | |
2602
+ | **Fraction** | `width & height: calc(<int>/<int> * 100%)` | `size-<int>/<int>` | `{ size: '<int>/<int>' }` | v4: any integer/integer fraction works bare |
2603
+ | **Full** | `width: 100%; height: 100%` | `size-full` | `{ size: 'full' }` | |
2604
+ | **Min Content** | `width: min-content; height: min-content` | `size-min` | `{ size: 'min' }` | |
2605
+ | **Max Content** | `width: max-content; height: max-content` | `size-max` | `{ size: 'max' }` | |
2606
+ | **Fit Content** | `width: fit-content; height: fit-content` | `size-fit` | `{ size: 'fit' }` | |
2607
+ | **Arbitrary** | `width: 3px; height: 3px` | `size-[3px]` | `{ size: '3px' }` | |
2608
+ | **CSS Variable** | `width: var(--s); height: var(--s)` | `size-(--s)` | `{ size: '--s' }` | **Sugar**: Auto-detects `--`. |
2609
+
2610
+ ## Block Size (Logical Height)
2611
+
2612
+ Controlling block-size (logical equivalent of height). Added in Tailwind v4.2.
2613
+
2614
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2615
+ | :----------------- | :-------------------------------------------- | :------------------- | :--------------------------- | :---------------------------- |
2616
+ | **Spacing** | `block-size: calc(var(--spacing) * <number>)` | `block-<number>` | `{ blockSize: <number> }` | |
2617
+ | **Full** | `block-size: 100%` | `block-full` | `{ blockSize: 'full' }` | |
2618
+ | **Screen** | `block-size: 100vh` | `block-screen` | `{ blockSize: 'screen' }` | |
2619
+ | **Min Content** | `block-size: min-content` | `block-min` | `{ blockSize: 'min' }` | |
2620
+ | **Max Content** | `block-size: max-content` | `block-max` | `{ blockSize: 'max' }` | |
2621
+ | **Fit Content** | `block-size: fit-content` | `block-fit` | `{ blockSize: 'fit' }` | |
2622
+ | **Auto** | `block-size: auto` | `block-auto` | `{ blockSize: 'auto' }` | |
2623
+ | **Arbitrary** | `block-size: 27px` | `block-[27px]` | `{ blockSize: '27px' }` | |
2624
+ | **Min Block Size** | `min-block-size: calc(var(--spacing) * N)` | `min-block-<number>` | `{ minBlockSize: <number> }` | |
2625
+ | **Max Block Size** | `max-block-size: calc(var(--spacing) * N)` | `max-block-<number>` | `{ maxBlockSize: <number> }` | |
2626
+ | **CSS Variable** | `block-size: var(--bs)` | `block-(--bs)` | `{ blockSize: '--bs' }` | **Sugar**: Auto-detects `--`. |
2627
+
2628
+ ## Inline Size (Logical Width)
2629
+
2630
+ Controlling inline-size (logical equivalent of width). Added in Tailwind v4.2.
2631
+
2632
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2633
+ | :------------------ | :--------------------------------------------- | :-------------------- | :---------------------------- | :---------------------------- |
2634
+ | **Spacing** | `inline-size: calc(var(--spacing) * <number>)` | `inline-<number>` | `{ inlineSize: <number> }` | |
2635
+ | **Full** | `inline-size: 100%` | `inline-full` | `{ inlineSize: 'full' }` | |
2636
+ | **Min Content** | `inline-size: min-content` | `inline-min` | `{ inlineSize: 'min' }` | |
2637
+ | **Max Content** | `inline-size: max-content` | `inline-max` | `{ inlineSize: 'max' }` | |
2638
+ | **Fit Content** | `inline-size: fit-content` | `inline-fit` | `{ inlineSize: 'fit' }` | |
2639
+ | **Auto** | `inline-size: auto` | `inline-auto` | `{ inlineSize: 'auto' }` | |
2640
+ | **Arbitrary** | `inline-size: 27px` | `inline-[27px]` | `{ inlineSize: '27px' }` | |
2641
+ | **Min Inline Size** | `min-inline-size: calc(var(--spacing) * N)` | `min-inline-<number>` | `{ minInlineSize: <number> }` | |
2642
+ | **Max Inline Size** | `max-inline-size: calc(var(--spacing) * N)` | `max-inline-<number>` | `{ maxInlineSize: <number> }` | |
2643
+ | **CSS Variable** | `inline-size: var(--is)` | `inline-(--is)` | `{ inlineSize: '--is' }` | **Sugar**: Auto-detects `--`. |
2644
+
2645
+ ## Container
2646
+
2647
+ Component-like utility for fixing an element's width to the current breakpoint.
2648
+
2649
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2650
+ | :--------- | :---------------------------------------------- | :---------------- | :------------------------ | :------------------------------------------------------ |
2651
+ | **Enable** | `width: 100%; max-width: 100% (at breakpoints)` | `container` | `{ container: true }` | **Top-level prop**. Better DX than `maxW: 'container'`. |
2652
+
2653
+ ## Typography Plugin (Prose)
2654
+
2655
+ Handling `@tailwindcss/typography` classes.
2656
+
2657
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2658
+ | :--------------- | :-------------------------------- | :---------------- | :------------------------ | :-------------------------------------------------------------------- |
2659
+ | **Enable Prose** | `color: inherit; max-width: 65ch` | `prose` | `{ prose: true }` | **Standard mapping**. Output class regardless of plugin installation. |
2660
+ | **Size** | `font-size: 1.125rem` | `prose-lg` | `{ prose: 'lg' }` | |
2661
+ | **Invert** | `--tw-prose-body: (varies)` | `prose-invert` | `{ proseInvert: true }` | |
2662
+ | **Gray (Color)** | `--tw-prose-body: (varies)` | `prose-gray` | `{ prose: 'gray' }` | |
2663
+
2664
+
2665
+ # Spacing
2666
+
2667
+ Controlling padding, margin, and space between elements.
2668
+
2669
+ ## Padding
2670
+
2671
+ Controlling inner spacing.
2672
+
2673
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2674
+ | :------------------ | :------------------------------------------------------ | :---------------- | :------------------------ | :------------------------------------------------------------------------------- |
2675
+ | **Px** | `padding: 1px` | `p-px` | `{ p: 'px' }` | |
2676
+ | **All Sides** | `padding: calc(var(--spacing) * <number>)` | `p-<number>` | `{ p: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2677
+ | **X Axis** | `padding-inline: calc(var(--spacing) * <number>)` | `px-<number>` | `{ px: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2678
+ | **Y Axis** | `padding-block: calc(var(--spacing) * <number>)` | `py-<number>` | `{ py: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2679
+ | **Top** | `padding-top: calc(var(--spacing) * <number>)` | `pt-<number>` | `{ pt: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2680
+ | **Right** | `padding-right: calc(var(--spacing) * <number>)` | `pr-<number>` | `{ pr: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2681
+ | **Bottom** | `padding-bottom: calc(var(--spacing) * <number>)` | `pb-<number>` | `{ pb: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2682
+ | **Left** | `padding-left: calc(var(--spacing) * <number>)` | `pl-<number>` | `{ pl: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2683
+ | **Start (Logical)** | `padding-inline-start: calc(var(--spacing) * <number>)` | `ps-<number>` | `{ ps: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2684
+ | **End (Logical)** | `padding-inline-end: calc(var(--spacing) * <number>)` | `pe-<number>` | `{ pe: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2685
+ | **Block Start** | `padding-block-start: calc(var(--spacing) * <number>)` | `pbs-<number>` | `{ pbs: <number> }` | v4.2: logical block-direction. |
2686
+ | **Block End** | `padding-block-end: calc(var(--spacing) * <number>)` | `pbe-<number>` | `{ pbe: <number> }` | v4.2: logical block-direction. |
2687
+ | **Arbitrary** | `padding: 5px` | `p-[5px]` | `{ p: '5px' }` | |
2688
+ | **CSS Variable** | `padding: var(--p)` | `p-(--p)` | `{ p: '--p' }` | **Sugar**: Auto-detects `--`. |
2689
+
2690
+ ## Margin
2691
+
2692
+ Controlling outer spacing.
2693
+
2694
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2695
+ | :--------------------- | :----------------------------------------------------- | :---------------- | :------------------------ | :------------------------------------------------------------------------------- |
2696
+ | **Px** | `margin: 1px` | `m-px` | `{ m: 'px' }` | |
2697
+ | **Px Negative** | `margin: -1px` | `-m-px` | `{ m: '-px' }` | |
2698
+ | **All Sides** | `margin: calc(var(--spacing) * <number>)` | `m-<number>` | `{ m: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2699
+ | **All Sides Negative** | `margin: calc(var(--spacing) * -<number>)` | `-m-<number>` | `{ m: -<number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2700
+ | **X Axis** | `margin-inline: calc(var(--spacing) * <number>)` | `mx-<number>` | `{ mx: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2701
+ | **Y Axis** | `margin-block: calc(var(--spacing) * <number>)` | `my-<number>` | `{ my: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2702
+ | **Top** | `margin-top: calc(var(--spacing) * <number>)` | `mt-<number>` | `{ mt: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2703
+ | **Right** | `margin-right: calc(var(--spacing) * <number>)` | `mr-<number>` | `{ mr: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2704
+ | **Bottom** | `margin-bottom: calc(var(--spacing) * <number>)` | `mb-<number>` | `{ mb: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2705
+ | **Left** | `margin-left: calc(var(--spacing) * <number>)` | `ml-<number>` | `{ ml: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2706
+ | **Start (Logical)** | `margin-inline-start: calc(var(--spacing) * <number>)` | `ms-<number>` | `{ ms: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2707
+ | **End (Logical)** | `margin-inline-end: calc(var(--spacing) * <number>)` | `me-<number>` | `{ me: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2708
+ | **Block Start** | `margin-block-start: calc(var(--spacing) * <number>)` | `mbs-<number>` | `{ mbs: <number> }` | v4.2: logical block-direction. Supports negative. |
2709
+ | **Block End** | `margin-block-end: calc(var(--spacing) * <number>)` | `mbe-<number>` | `{ mbe: <number> }` | v4.2: logical block-direction. Supports negative. |
2710
+ | **Negative** | `margin-top: calc(var(--spacing) * -<number>)` | `-mt-<number>` | `{ mt: -<number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2711
+ | **Auto** | `margin: auto` | `m-auto` | `{ m: 'auto' }` | |
2712
+ | **Arbitrary** | `margin: 5px` | `m-[5px]` | `{ m: '5px' }` | |
2713
+ | **CSS Variable** | `margin: var(--m)` | `m-(--m)` | `{ m: '--m' }` | **Sugar**: Auto-detects `--`. |
2714
+
2715
+ ## Space Between
2716
+
2717
+ Controlling spacing between child elements (Legacy/Alternative to Gap).
2718
+
2719
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2720
+ | :--------------- | :------------------------ | :------------------ | :------------------------ | :------------------------------------------------------------------------------- |
2721
+ | **Space X** | (on children) | `space-x-<number>` | `{ spaceX: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2722
+ | **Space Y** | (on children) | `space-y-<number>` | `{ spaceY: <number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2723
+ | **Reverse X** | `--tw-space-x-reverse: 1` | `space-x-reverse` | `{ spaceXReverse: true }` | |
2724
+ | **Reverse Y** | `--tw-space-y-reverse: 1` | `space-y-reverse` | `{ spaceYReverse: true }` | |
2725
+ | **Negative** | (on children) | `-space-x-4` | `{ spaceX: -<number> }` | v4: fully dynamic, no static scale, accept any integer or 0.5-step decimal bare. |
2726
+ | **Px** | (on children) | `space-x-px` | `{ spaceX: 'px' }` | |
2727
+ | **Arbitrary** | (on children) | `space-x-[5px]` | `{ spaceX: '5px' }` | |
2728
+ | **CSS Variable** | (on children) | `space-x-(--space)` | `{ spaceX: '--space' }` | **Sugar**: Auto-detects `--`. |
2729
+
2730
+
2731
+ # Tables
2732
+
2733
+ Controlling the layout and style of tables.
2734
+
2735
+ ## Border Collapse
2736
+
2737
+ Utilities for controlling whether table borders should collapse or be separated.
2738
+
2739
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2740
+ | :----------- | :--------------------------- | :---------------- | :------------------------------- | :--- |
2741
+ | **Collapse** | `border-collapse: collapse;` | `border-collapse` | `{ borderCollapse: 'collapse' }` | |
2742
+ | **Separate** | `border-collapse: separate;` | `border-separate` | `{ borderCollapse: 'separate' }` | |
2743
+
2744
+ ## Border Spacing
2745
+
2746
+ Utilities for controlling the spacing between table borders.
2747
+
2748
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2749
+ | :----------------- | :------------------------------------------------- | :--------------------- | :------------------------- | :--- |
2750
+ | Border Spacing 0 | `border-spacing: 0px` | `border-spacing-0` | `{ borderSpacing: 0 }` | |
2751
+ | Border Spacing px | `border-spacing: 1px` | `border-spacing-px` | `{ borderSpacing: 'px' }` | |
2752
+ | Border Spacing 0.5 | `border-spacing: 0.125rem` | `border-spacing-0.5` | `{ borderSpacing: 0.5 }` | |
2753
+ | Border Spacing 1 | `border-spacing: 0.25rem` | `border-spacing-1` | `{ borderSpacing: 1 }` | |
2754
+ | Border Spacing 1.5 | `border-spacing: 0.375rem` | `border-spacing-1.5` | `{ borderSpacing: 1.5 }` | |
2755
+ | Border Spacing 2 | `border-spacing: 0.5rem` | `border-spacing-2` | `{ borderSpacing: 2 }` | |
2756
+ | Border Spacing 2.5 | `border-spacing: 0.625rem` | `border-spacing-2.5` | `{ borderSpacing: 2.5 }` | |
2757
+ | Border Spacing 3 | `border-spacing: 0.75rem` | `border-spacing-3` | `{ borderSpacing: 3 }` | |
2758
+ | Border Spacing 3.5 | `border-spacing: 0.875rem` | `border-spacing-3.5` | `{ borderSpacing: 3.5 }` | |
2759
+ | Border Spacing 4 | `border-spacing: 1rem` | `border-spacing-4` | `{ borderSpacing: 4 }` | |
2760
+ | Border Spacing 5 | `border-spacing: 1.25rem` | `border-spacing-5` | `{ borderSpacing: 5 }` | |
2761
+ | Border Spacing 6 | `border-spacing: 1.5rem` | `border-spacing-6` | `{ borderSpacing: 6 }` | |
2762
+ | Border Spacing 7 | `border-spacing: 1.75rem` | `border-spacing-7` | `{ borderSpacing: 7 }` | |
2763
+ | Border Spacing 8 | `border-spacing: 2rem` | `border-spacing-8` | `{ borderSpacing: 8 }` | |
2764
+ | Border Spacing 9 | `border-spacing: 2.25rem` | `border-spacing-9` | `{ borderSpacing: 9 }` | |
2765
+ | Border Spacing 10 | `border-spacing: 2.5rem` | `border-spacing-10` | `{ borderSpacing: 10 }` | |
2766
+ | Border Spacing 11 | `border-spacing: 2.75rem` | `border-spacing-11` | `{ borderSpacing: 11 }` | |
2767
+ | Border Spacing 12 | `border-spacing: 3rem` | `border-spacing-12` | `{ borderSpacing: 12 }` | |
2768
+ | Border Spacing 14 | `border-spacing: 3.5rem` | `border-spacing-14` | `{ borderSpacing: 14 }` | |
2769
+ | Border Spacing 16 | `border-spacing: 4rem` | `border-spacing-16` | `{ borderSpacing: 16 }` | |
2770
+ | Border Spacing 20 | `border-spacing: 5rem` | `border-spacing-20` | `{ borderSpacing: 20 }` | |
2771
+ | Border Spacing 24 | `border-spacing: 6rem` | `border-spacing-24` | `{ borderSpacing: 24 }` | |
2772
+ | Border Spacing 28 | `border-spacing: 7rem` | `border-spacing-28` | `{ borderSpacing: 28 }` | |
2773
+ | Border Spacing 32 | `border-spacing: 8rem` | `border-spacing-32` | `{ borderSpacing: 32 }` | |
2774
+ | Border Spacing 36 | `border-spacing: 9rem` | `border-spacing-36` | `{ borderSpacing: 36 }` | |
2775
+ | Border Spacing 40 | `border-spacing: 10rem` | `border-spacing-40` | `{ borderSpacing: 40 }` | |
2776
+ | Border Spacing 44 | `border-spacing: 11rem` | `border-spacing-44` | `{ borderSpacing: 44 }` | |
2777
+ | Border Spacing 48 | `border-spacing: 12rem` | `border-spacing-48` | `{ borderSpacing: 48 }` | |
2778
+ | Border Spacing 52 | `border-spacing: 13rem` | `border-spacing-52` | `{ borderSpacing: 52 }` | |
2779
+ | Border Spacing 56 | `border-spacing: 14rem` | `border-spacing-56` | `{ borderSpacing: 56 }` | |
2780
+ | Border Spacing 60 | `border-spacing: 15rem` | `border-spacing-60` | `{ borderSpacing: 60 }` | |
2781
+ | Border Spacing 64 | `border-spacing: 16rem` | `border-spacing-64` | `{ borderSpacing: 64 }` | |
2782
+ | Border Spacing 72 | `border-spacing: 18rem` | `border-spacing-72` | `{ borderSpacing: 72 }` | |
2783
+ | Border Spacing 80 | `border-spacing: 20rem` | `border-spacing-80` | `{ borderSpacing: 80 }` | |
2784
+ | Border Spacing 96 | `border-spacing: 24rem` | `border-spacing-96` | `{ borderSpacing: 96 }` | |
2785
+ | **X/Y Spacing** | `border-spacing-x: (etc); border-spacing-y: (etc)` | `border-spacing-x-4` | `{ borderSpacingX: 4 }` | |
2786
+ | **Arbitrary** | `border-spacing: 3px` | `border-spacing-[3px]` | `{ borderSpacing: '3px' }` | |
2787
+ | **Variable** | `border-spacing: var(--s)` | `border-spacing-(--s)` | `{ borderSpacing: '--s' }` | |
2788
+
2789
+ ## Table Layout
2790
+
2791
+ Utilities for controlling the table layout algorithm.
2792
+
2793
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2794
+ | :-------- | :--------------------- | :---------------- | :------------------------- | :--- |
2795
+ | **Auto** | `table-layout: auto;` | `table-auto` | `{ tableLayout: 'auto' }` | |
2796
+ | **Fixed** | `table-layout: fixed;` | `table-fixed` | `{ tableLayout: 'fixed' }` | |
2797
+
2798
+ ## Caption Side
2799
+
2800
+ Utilities for controlling the alignment of table captions.
2801
+
2802
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2803
+ | :--------- | :---------------------- | :---------------- | :------------------------ | :--- |
2804
+ | **Top** | `caption-side: top;` | `caption-top` | `{ caption: 'top' }` | |
2805
+ | **Bottom** | `caption-side: bottom;` | `caption-bottom` | `{ caption: 'bottom' }` | |
2806
+
2807
+
2808
+ ## Tooling
2809
+
2810
+ ### VS Code Extension (`@csszyx/vscode`)
2811
+
2812
+ IntelliSense, hover, and diagnostics for `sz` props. Supports JSX, TSX, JS, TS, HTML.
2813
+
2814
+ **Features:**
2815
+
2816
+ - Key + value completions inside `sz={{ ... }}` (variant-aware, depth 1 and 2)
2817
+ - Hover preview — shows generated Tailwind className + inline CSS variables via `transform()`
2818
+ - Diagnostics — unknown prop keys flagged as warnings; SUGGESTION_MAP hints (e.g. `padding` → `p`)
2819
+ - TextMate grammar injection — syntax highlighting for `sz` attribute
2820
+
2821
+ **Settings:**
2822
+
2823
+ - `csszyx.enableDiagnostics` (default: `true`) — toggle unknown-prop warnings
2824
+ - `csszyx.enableHover` (default: `true`) — toggle hover preview
2825
+
2826
+ **Build:** esbuild → `dist/extension.js` (85KB CJS, zero Babel, uses `@csszyx/compiler/browser`)
2827
+
2828
+ ### MCP Server (`@csszyx/mcp-server`)
2829
+
2830
+ Exposes CSSzyx to AI assistants via Model Context Protocol.
2831
+
2832
+ **Tools:** `sz_expand`, `sz_validate`, `sz_lookup`, `sz_migrate`
2833
+ **Resources:** `csszyx://docs/sz-props`, `csszyx://docs/variants`, `csszyx://llms-full`
2834
+ **Prompts:** `review-sz-usage`, `migrate-tailwind-component`
2835
+
2836
+ ```bash
2837
+ npm install -g @csszyx/mcp-server
2838
+ npx @csszyx/mcp-server # stdio transport (Claude Desktop / Cursor)
2839
+ ```
2840
+
2841
+
2842
+ # Transforms
2843
+
2844
+ Utilities for controlling element transformations.
2845
+
2846
+ ## Rotate
2847
+
2848
+ Utilities for rotating elements.
2849
+
2850
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2851
+ | :------------- | :----------------- | :------------------------------------------- | :------------------------ | :------------ |
2852
+ | Rotate 0 | `rotate: 0deg` | `rotate-0` | `{ rotate: 0 }` | |
2853
+ | Rotate 1 | `rotate: 1deg` | `rotate-1` | `{ rotate: 1 }` | |
2854
+ | Rotate 2 | `rotate: 2deg` | `rotate-2` | `{ rotate: 2 }` | |
2855
+ | Rotate 3 | `rotate: 3deg` | `rotate-3` | `{ rotate: 3 }` | |
2856
+ | Rotate 6 | `rotate: 6deg` | `rotate-6` | `{ rotate: 6 }` | |
2857
+ | Rotate 12 | `rotate: 12deg` | `rotate-12` | `{ rotate: 12 }` | |
2858
+ | Rotate 45 | `rotate: 45deg` | `rotate-45` | `{ rotate: 45 }` | |
2859
+ | Rotate 90 | `rotate: 90deg` | `rotate-90` | `{ rotate: 90 }` | |
2860
+ | Rotate 180 | `rotate: 180deg` | `rotate-180` | `{ rotate: 180 }` | |
2861
+ | **Neg Angle** | `rotate: -45deg` | `-rotate-45` | `{ rotate: -45 }` | |
2862
+ | **X/Y/Z Axis** | `rotate: x 45deg` | `rotate-x-45`, `rotate-y-90`, `rotate-z-180` | `{ rotateX: 45 }`(etc) | 3D rotations. |
2863
+ | **Arbitrary** | `rotate: 1.2rad` | `rotate-[1.2rad]` | `{ rotate: '1.2rad' }` | |
2864
+ | **Variable** | `rotate: var(--r)` | `rotate-(--r)` | `{ rotate: '--r' }` | |
2865
+
2866
+ ## Scale
2867
+
2868
+ Utilities for scaling elements.
2869
+
2870
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2871
+ | :------------ | :---------------- | :---------------- | :------------------------ | :--- |
2872
+ | Scale 0 | `scale: 0` | `scale-0` | `{ scale: 0 }` | |
2873
+ | Scale 50 | `scale: 0.5` | `scale-50` | `{ scale: 50 }` | |
2874
+ | Scale 75 | `scale: 0.75` | `scale-75` | `{ scale: 75 }` | |
2875
+ | Scale 90 | `scale: 0.9` | `scale-90` | `{ scale: 90 }` | |
2876
+ | Scale 95 | `scale: 0.95` | `scale-95` | `{ scale: 95 }` | |
2877
+ | Scale 100 | `scale: 1` | `scale-100` | `{ scale: 100 }` | |
2878
+ | Scale 105 | `scale: 1.05` | `scale-105` | `{ scale: 105 }` | |
2879
+ | Scale 110 | `scale: 1.1` | `scale-110` | `{ scale: 110 }` | |
2880
+ | Scale 125 | `scale: 1.25` | `scale-125` | `{ scale: 125 }` | |
2881
+ | Scale 150 | `scale: 1.5` | `scale-150` | `{ scale: 150 }` | |
2882
+ | Scale 200 | `scale: 2` | `scale-200` | `{ scale: 200 }` | |
2883
+ | **X Axis** | `scale-x: 0.5` | `scale-x-50` | `{ scaleX: 50 }` | |
2884
+ | **Y Axis** | `scale-y: 0.5` | `scale-y-50` | `{ scaleY: 50 }` | |
2885
+ | **Z Axis** | `scale-z: 0.5` | `scale-z-50` | `{ scaleZ: 50 }` | |
2886
+ | **3D** | `scale: 0.5` | `scale-3d` | `{ scale: '3d' }` | |
2887
+ | **Arbitrary** | `scale: 1.5` | `scale-[1.5]` | `{ scale: '1.5' }` | |
2888
+ | **Variable** | `scale: var(--s)` | `scale-(--s)` | `{ scale: '--s' }` | |
2889
+
2890
+ ## Skew
2891
+
2892
+ Utilities for skewing elements.
2893
+
2894
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2895
+ | :------------ | :------------------------ | :---------------- | :------------------------ | :--- |
2896
+ | Skew X 0 | `transform: skewX(0deg)` | `skew-x-0` | `{ skewX: 0 }` | |
2897
+ | Skew X 1 | `transform: skewX(1deg)` | `skew-x-1` | `{ skewX: 1 }` | |
2898
+ | Skew X 2 | `transform: skewX(2deg)` | `skew-x-2` | `{ skewX: 2 }` | |
2899
+ | Skew X 3 | `transform: skewX(3deg)` | `skew-x-3` | `{ skewX: 3 }` | |
2900
+ | Skew X 6 | `transform: skewX(6deg)` | `skew-x-6` | `{ skewX: 6 }` | |
2901
+ | Skew X 12 | `transform: skewX(12deg)` | `skew-x-12` | `{ skewX: 12 }` | |
2902
+ | Skew Y 0 | `transform: skewY(0deg)` | `skew-y-0` | `{ skewY: 0 }` | |
2903
+ | Skew Y 1 | `transform: skewY(1deg)` | `skew-y-1` | `{ skewY: 1 }` | |
2904
+ | Skew Y 2 | `transform: skewY(2deg)` | `skew-y-2` | `{ skewY: 2 }` | |
2905
+ | Skew Y 3 | `transform: skewY(3deg)` | `skew-y-3` | `{ skewY: 3 }` | |
2906
+ | Skew Y 6 | `transform: skewY(6deg)` | `skew-y-6` | `{ skewY: 6 }` | |
2907
+ | Skew Y 12 | `transform: skewY(12deg)` | `skew-y-12` | `{ skewY: 12 }` | |
2908
+ | **Arbitrary** | `skew-x: 5deg` | `skew-x-[5deg]` | `{ skewX: '5deg' }` | |
2909
+
2910
+ ## Translate
2911
+
2912
+ Utilities for translating elements.
2913
+
2914
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2915
+ | :----------------------- | :--------------------------------------------- | :------------------------- | :------------------------------- | :------------------------------------------------------------- |
2916
+ | **Shorthand Spacing** | `translate: calc(var(--spacing) * <n>)` | `translate-<number>` | `{ translate: <number> }` | CSS `translate` property — sets both axes |
2917
+ | **Shorthand Fraction** | `translate: calc(<int>/<int> * 100%)` | `translate-<int>/<int>` | `{ translate: '<int>/<int>' }` | v4: bare fraction, both axes |
2918
+ | **Shorthand Negative** | `translate: calc(-<int>/<int> * 100%)` | `-translate-<int>/<int>` | `{ translate: '-<int>/<int>' }` | |
2919
+ | **Translate X Spacing** | `translate-x: calc(var(--spacing) * <number>)` | `translate-x-<number>` | `{ translateX: <number> }` | v4: fully dynamic, accept any integer or 0.5-step decimal bare |
2920
+ | **Translate X Px** | `translate-x: 1px` | `translate-x-px` | `{ translateX: 'px' }` | |
2921
+ | **Translate X Fraction** | `translate-x: calc(<int>/<int> * 100%)` | `translate-x-<int>/<int>` | `{ translateX: '<int>/<int>' }` | v4: any integer/integer fraction works bare |
2922
+ | **Translate X Neg Frac** | `translate-x: calc(-<int>/<int> * 100%)` | `-translate-x-<int>/<int>` | `{ translateX: '-<int>/<int>' }` | |
2923
+ | **Translate Y Spacing** | `translate-y: calc(var(--spacing) * <number>)` | `translate-y-<number>` | `{ translateY: <number> }` | v4: fully dynamic, accept any integer or 0.5-step decimal bare |
2924
+ | **Translate Y Fraction** | `translate-y: calc(<int>/<int> * 100%)` | `translate-y-<int>/<int>` | `{ translateY: '<int>/<int>' }` | v4: any integer/integer fraction works bare |
2925
+ | **Translate Y Neg Frac** | `translate-y: calc(-<int>/<int> * 100%)` | `-translate-y-<int>/<int>` | `{ translateY: '-<int>/<int>' }` | |
2926
+ | **Z Axis** | `translate-z: 4px` | `translate-z-4` | `{ translateZ: 4 }` | |
2927
+ | **Full** | `translate-x: 100%` | `translate-x-full` | `{ translateX: 'full' }` | |
2928
+ | **3D** | `translate: (value)` | `translate-3d` | `{ translate: '3d' }` | |
2929
+ | **Arbitrary** | `translate-x: 5px` | `translate-x-[5px]` | `{ translateX: '5px' }` | |
2930
+ | **Variable** | `translate-x: var(--t)` | `translate-x-(--t)` | `{ translateX: '--t' }` | |
2931
+
2932
+ ## Transform Origin
2933
+
2934
+ Utilities for controlling the origin of transformations.
2935
+
2936
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2937
+ | :------------ | :--------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------ | :------------------------------- |
2938
+ | **Keywords** | `transform-origin: center` | `origin-center`, `origin-top`, `origin-top-right`, `origin-right`, `origin-bottom-right`, `origin-bottom`, `origin-bottom-left`, `origin-left`, `origin-top-left` | `{ origin: 'top' }` | Shorthand for `transformOrigin`. |
2939
+ | **Arbitrary** | `transform-origin: (etc)` | `origin-[33%_75%]` | `{ origin: '33%_75%' }` | |
2940
+ | **Variable** | `transform-origin: var(--o)` | `origin-(--o)` | `{ origin: '--o' }` | |
2941
+
2942
+ ## Transform Style
2943
+
2944
+ Utilities for controlling how children of a 3D element are rendered.
2945
+
2946
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2947
+ | :------- | :------------------------------ | :---------------- | :--------------------------- | :--- |
2948
+ | **Flat** | `transform-style: flat;` | `transform-flat` | `{ transformStyle: 'flat' }` | |
2949
+ | **3D** | `transform-style: preserve-3d;` | `transform-3d` | `{ transformStyle: '3d' }` | |
2950
+
2951
+ ## Backface Visibility
2952
+
2953
+ Utilities for controlling whether the back face of an element is visible when turned towards the user.
2954
+
2955
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2956
+ | :---------- | :------------------------------ | :----------------- | :------------------------ | :---------------------------------- |
2957
+ | **Visible** | `backface-visibility: visible;` | `backface-visible` | `{ backface: 'visible' }` | Shorthand for `backfaceVisibility`. |
2958
+ | **Hidden** | `backface-visibility: hidden;` | `backface-hidden` | `{ backface: 'hidden' }` | |
2959
+
2960
+ ## Perspective
2961
+
2962
+ Utilities for controlling the 3D perspective of an element.
2963
+
2964
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2965
+ | :------------ | :---------------------- | :--------------------------------------------------------- | :------------------------- | :--- |
2966
+ | **Scale** | `perspective: 250px` | `perspective-none`, `perspective-xs`(etc)`perspective-2xl` | `{ perspective: 'xs' }` | |
2967
+ | **Arbitrary** | `perspective: 500px` | `perspective-[500px]` | `{ perspective: '500px' }` | |
2968
+ | **Variable** | `perspective: var(--p)` | `perspective-(--p)` | `{ perspective: '--p' }` | |
2969
+
2970
+ ## Perspective Origin
2971
+
2972
+ Utilities for controlling the origin of the perspective.
2973
+
2974
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2975
+ | :------------ | :--------------------------- | :--------------------------------------------------------- | :--------------------------------- | :--- |
2976
+ | **Keywords** | `perspective-origin: center` | `perspective-origin-center`, `perspective-origin-top`(etc) | `{ perspectiveOrigin: 'top' }` | |
2977
+ | **Arbitrary** | `perspective-origin: (etc)` | `perspective-origin-[25%_25%]` | `{ perspectiveOrigin: '25%_25%' }` | |
2978
+
2979
+ ## Transform
2980
+
2981
+ Utilities for controlling the transform property itself.
2982
+
2983
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2984
+ | :------- | :------------------------------------------- | :---------------- | :------------------------ | :--- |
2985
+ | **None** | `transform: none;` | `transform-none` | `{ transform: 'none' }` | |
2986
+ | **GPU** | `transform: translateZ(0)` (GPU compositing) | `transform-gpu` | `{ transform: 'gpu' }` | |
2987
+ | **CPU** | `transform: none` (disable GPU compositing) | `transform-cpu` | `{ transform: 'cpu' }` | |
2988
+
2989
+
2990
+ # Transitions & Animation
2991
+
2992
+ Controlling transition and animation properties.
2993
+
2994
+ ## Transition Property
2995
+
2996
+ Utilities for controlling which CSS properties transition.
2997
+
2998
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
2999
+ | :------------ | :------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------- | :-------------------------- | :------------------ |
3000
+ | **None** | `transition-property: none;` | `transition-none` | `{ transition: 'none' }` | |
3001
+ | **Common** | `transition-property: color, background-color, border-color, (etc)` | `transition` | `{ transition: true }` | Default properties. |
3002
+ | **Scale** | `transition-property: color, background-color, border-color, (etc)` | `transition-all`, `transition-colors`, `transition-opacity`, `transition-shadow`, `transition-transform` | `{ transition: 'colors' }` | |
3003
+ | **Arbitrary** | `transition-property: opacity` | `transition-opacity` | `{ transition: 'opacity' }` | |
3004
+
3005
+ ## Transition Behavior
3006
+
3007
+ Utilities for controlling the transition behavior.
3008
+
3009
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3010
+ | :----------- | :------------------------------------- | :-------------------- | :----------------------------------- | :--- |
3011
+ | **Discrete** | `transition-behavior: allow-discrete;` | `transition-discrete` | `{ transitionBehavior: 'discrete' }` | |
3012
+ | **Normal** | `transition-behavior: normal;` | `transition-normal` | `{ transitionBehavior: 'normal' }` | |
3013
+
3014
+ ## Transition Duration
3015
+
3016
+ Utilities for controlling the duration of CSS transitions.
3017
+
3018
+ | Concept | CSS Rule | Tailwind v4 Class | sz Prop |
3019
+ | :------------ | :---------------------------- | :---------------- | :------------------- |
3020
+ | Duration 0 | `transition-duration: 0ms` | `duration-0` | `{ duration: 0 }` |
3021
+ | Duration 75 | `transition-duration: 75ms` | `duration-75` | `{ duration: 75 }` |
3022
+ | Duration 100 | `transition-duration: 100ms` | `duration-100` | `{ duration: 100 }` |
3023
+ | Duration 150 | `transition-duration: 150ms` | `duration-150` | `{ duration: 150 }` |
3024
+ | Duration 200 | `transition-duration: 200ms` | `duration-200` | `{ duration: 200 }` |
3025
+ | Duration 300 | `transition-duration: 300ms` | `duration-300` | `{ duration: 300 }` |
3026
+ | Duration 500 | `transition-duration: 500ms` | `duration-500` | `{ duration: 500 }` |
3027
+ | Duration 700 | `transition-duration: 700ms` | `duration-700` | `{ duration: 700 }` |
3028
+ | Duration 1000 | `transition-duration: 1000ms` | `duration-1000` | `{ duration: 1000 }` |
3029
+
3030
+ ## Transition Timing Function
3031
+
3032
+ Utilities for controlling the easing of CSS transitions.
3033
+
3034
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3035
+ | :------------ | :------------------------------------------------------ | :-------------------------------------------------- | :-------------------------------------- | :--- |
3036
+ | **Keywords** | `transition-timing-function: linear` | `ease-linear`, `ease-in`, `ease-out`, `ease-in-out` | `{ ease: 'in' }` | |
3037
+ | **Arbitrary** | `transition-timing-function: cubic-bezier(0.4,0,0.2,1)` | `ease-[cubic-bezier(0.4,0,0.2,1)]` | `{ ease: 'cubic-bezier(0.4,0,0.2,1)' }` | |
3038
+ | **Variable** | `transition-timing-function: var(--e)` | `ease-(--e)` | `{ ease: '--e' }` | |
3039
+
3040
+ ## Transition Delay
3041
+
3042
+ Utilities for controlling the delay of CSS transitions.
3043
+
3044
+ | Concept | CSS Rule | Tailwind v4 Class | sz Prop |
3045
+ | :--------- | :------------------------- | :---------------- | :---------------- |
3046
+ | Delay 0 | `transition-delay: 0ms` | `delay-0` | `{ delay: 0 }` |
3047
+ | Delay 75 | `transition-delay: 75ms` | `delay-75` | `{ delay: 75 }` |
3048
+ | Delay 100 | `transition-delay: 100ms` | `delay-100` | `{ delay: 100 }` |
3049
+ | Delay 150 | `transition-delay: 150ms` | `delay-150` | `{ delay: 150 }` |
3050
+ | Delay 200 | `transition-delay: 200ms` | `delay-200` | `{ delay: 200 }` |
3051
+ | Delay 300 | `transition-delay: 300ms` | `delay-300` | `{ delay: 300 }` |
3052
+ | Delay 500 | `transition-delay: 500ms` | `delay-500` | `{ delay: 500 }` |
3053
+ | Delay 700 | `transition-delay: 700ms` | `delay-700` | `{ delay: 700 }` |
3054
+ | Delay 1000 | `transition-delay: 1000ms` | `delay-1000` | `{ delay: 1000 }` |
3055
+
3056
+ ## Animation
3057
+
3058
+ Utilities for animating elements with CSS animations.
3059
+
3060
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3061
+ | :------------ | :----------------------------------- | :---------------------------------------------------------------- | :--------------------------------------- | :--- |
3062
+ | **None** | `animation: none;` | `animate-none` | `{ animate: 'none' }` | |
3063
+ | **Keywords** | `animation: spin 1s linear infinite` | `animate-spin`, `animate-ping`, `animate-pulse`, `animate-bounce` | `{ animate: 'spin' }` | |
3064
+ | **Arbitrary** | `animation: spin_1s_linear_infinite` | `animate-[spin_1s_linear_infinite]` | `{ animate: 'spin_1s_linear_infinite' }` | |
3065
+
3066
+ ## Animation Delay
3067
+
3068
+ Tailwind v4 has no `animation-delay-*` utility. CSSzyx emits an arbitrary CSS property.
3069
+ `delay` is **transition-delay** — do not confuse with `animationDelay`.
3070
+
3071
+ | Concept | CSS Rule | Output Class | `sz` Prop (Object Syntax) | Note |
3072
+ | :---------------- | :------------------------------ | :-------------------------------------- | :------------------------------------------ | :----------------------------------------------- |
3073
+ | **Number (ms)** | `animation-delay: 150ms` | `[animation-delay:150ms]` | `{ animationDelay: 150 }` | Number → appended `ms` |
3074
+ | **Number zero** | `animation-delay: 0ms` | `[animation-delay:0ms]` | `{ animationDelay: 0 }` | |
3075
+ | **String** | `animation-delay: 0.5s` | `[animation-delay:0.5s]` | `{ animationDelay: '0.5s' }` | String passed through as-is |
3076
+ | **Stagger combo** | `animation: pulse; delay 150ms` | `animate-pulse [animation-delay:150ms]` | `{ animate: 'pulse', animationDelay: 150 }` | `delay` is transition-delay, not animation-delay |
3077
+
3078
+
3079
+ # Typography
3080
+
3081
+ Controlling the style, size, and layout of text.
3082
+
3083
+ ## Font Family
3084
+
3085
+ Controlling the font family.
3086
+
3087
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3088
+ | :--------------- | :------------------------------------------------------------------------------ | :----------------------- | :---------------------------- | :----------------------------------------------------------------- |
3089
+ | **Sans** | `font-family: ui-sans-serif, system-ui, sans-serif` | `font-sans` | `{ fontFamily: 'sans' }` | **Preferred key**. |
3090
+ | **Serif** | `font-family: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif` | `font-serif` | `{ fontFamily: 'serif' }` | |
3091
+ | **Mono** | `font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace` | `font-mono` | `{ fontFamily: 'mono' }` | |
3092
+ | **Arbitrary** | `font-family: "My Font"` | `font-['My_Font']` | `{ fontFamily: "'My Font'" }` | |
3093
+ | **CSS Variable** | `font-family: var(--f)` | `font-(family-name:--f)` | `{ fontFamily: '--f' }` | **Sugar**: Auto-detects `--`. Type hint disambiguates from weight. |
3094
+
3095
+ ## Font Size
3096
+
3097
+ Controlling the font size.
3098
+
3099
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3100
+ | :--------------- | :------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------ | :-------------------------------------- | :---------------------------------------------------------------- |
3101
+ | **Scale** | `font-size: (size); line-height: (leading)` | `text-xs`, `text-sm`, `text-base`, `text-lg`, `text-xl`, `text-2xl`, `text-3xl`, `text-4xl`, `text-5xl`, `text-6xl`, `text-7xl`, `text-8xl`, `text-9xl` | `{ text: 'xs' }`, `{ text: 'sm' }` etc. | Sets size & leading. |
3102
+ | **Number** | `font-size: 16px` | `text-[16px]` | `{ text: '16px' }` | CamelCase `fontSize` also valid. |
3103
+ | **Arbitrary** | `font-size: 1.5rem` | `text-[1.5rem]` | `{ text: '1.5rem' }` | |
3104
+ | **CSS Variable** | `font-size: var(--size)` | `text-(length:--size)` | `{ text: '--size' }` | **Sugar**: Auto-detects `--`. Type hint disambiguates from color. |
3105
+
3106
+ ## Font Weight
3107
+
3108
+ Controlling the font weight.
3109
+
3110
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3111
+ | :--------------- | :---------------------- | :--------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------ | :----------------------------------------------------------------- |
3112
+ | **Keywords** | `font-weight: 100-900` | `font-thin`, `font-extralight`, `font-light`, `font-normal`, `font-medium`, `font-semibold`, `font-bold`, `font-extrabold`, `font-black` | `{ fontWeight: 'thin' }`, `{ fontWeight: 'extralight' }` etc. | |
3113
+ | **Number** | `font-weight: 100-900` | `font-100`, `font-200`, `font-300`, `font-400`, `font-500`, `font-600`, `font-700`, `font-800`, `font-900` | `{ fontWeight: 100 }`, `{ fontWeight: 200 }` etc. | v4 shorthand. |
3114
+ | **Alias** | (Sugar) | `font-bold` | `{ weight: 'bold' }` | Sugar for `fontWeight`. |
3115
+ | **Arbitrary** | `font-weight: 550` | `font-[550]` | `{ fontWeight: 550 }` | |
3116
+ | **CSS Variable** | `font-weight: var(--w)` | `font-(weight:--w)` | `{ fontWeight: '--w' }` | **Sugar**: Auto-detects `--`. Type hint disambiguates from family. |
3117
+
3118
+ ## Font Stretch
3119
+
3120
+ Controlling the font width.
3121
+
3122
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3123
+ | :--------------------- | :----------------------- | :-------------------- | :------------------------ | :--- |
3124
+ | Font Stretch 50% | `font-stretch: 50%` | `font-stretch-50%` | `{ fontStretch: '50%' }` | |
3125
+ | Font Stretch 75% | `font-stretch: 75%` | `font-stretch-75%` | `{ fontStretch: '75%' }` | |
3126
+ | Font Stretch 100% | `font-stretch: 100%` | `font-stretch-100%` | `{ fontStretch: '100%' }` | |
3127
+ | Font Stretch 125% | `font-stretch: 125%` | `font-stretch-125%` | `{ fontStretch: '125%' }` | |
3128
+ | Font Stretch 150% | `font-stretch: 150%` | `font-stretch-150%` | `{ fontStretch: '150%' }` | |
3129
+ | Font Stretch Arbitrary | `font-stretch: 110%` | `font-stretch-[110%]` | `{ fontStretch: '110%' }` | |
3130
+ | CSS Variable | `font-stretch: var(--s)` | `font-stretch-(--s)` | `{ fontStretch: '--s' }` | |
3131
+
3132
+ ## Font Variant Numeric
3133
+
3134
+ Controlling numeric glyphs.
3135
+
3136
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3137
+ | :---------- | :-------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------ | :---------------------------- |
3138
+ | **Variant** | `font-variant-numeric: ordinal, slashed-zero` | `normal-nums`, `ordinal`, `slashed-zero`, `lining-nums`, `oldstyle-nums`, `proportional-nums`, `tabular-nums`, `diagonal-fractions`, `stacked-fractions` | `{ fontVariant: 'normal-nums' }` etc. | |
3139
+ | **Boolean** | `font-variant-numeric: slashed-zero` | `slashed-zero` | `{ slashedZero: true }` | **Overwrites** `fontVariant`. |
3140
+ | **Boolean** | `font-variant-numeric: ordinal` | `ordinal` | `{ ordinal: true }` | **Overwrites** `fontVariant`. |
3141
+
3142
+ ## Font Features
3143
+
3144
+ Controlling font-feature-settings. Added in Tailwind v4.2.
3145
+
3146
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3147
+ | :------------ | :-------------------------------- | :------------------------- | :----------------------------- | :--- |
3148
+ | **Normal** | `font-feature-settings: normal` | `font-features-normal` | `{ fontFeatures: 'normal' }` | |
3149
+ | **Arbitrary** | `font-feature-settings: "liga" 1` | `font-features-["liga"_1]` | `{ fontFeatures: '"liga" 1' }` | |
3150
+
3151
+ ## Font Style & Smoothing
3152
+
3153
+ Controlling the font style and smoothing.
3154
+
3155
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3156
+ | :-------------- | :------------------------------------ | :--------------------- | :------------------------------ | :----------------------------------------------------- |
3157
+ | **Italic** | `font-style: italic` | `italic` | `{ italic: true }` | |
3158
+ | **Not Italic** | `font-style: normal` | `not-italic` | `{ notItalic: true }` | `false` = NOOP; use `notItalic: true` to reset. |
3159
+ | **Antialiased** | `-webkit-font-smoothing: antialiased` | `antialiased` | `{ antialiased: true }` | |
3160
+ | **Subpixel** | `-webkit-font-smoothing: auto` | `subpixel-antialiased` | `{ subpixelAntialiased: true }` | `false` = NOOP; use `subpixelAntialiased` to override. |
3161
+
3162
+ ## Letter Spacing (Tracking)
3163
+
3164
+ Controlling the tracking (letter spacing).
3165
+
3166
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3167
+ | :--------------- | :------------------------- | :----------------- | :------------------------ | :--- |
3168
+ | Tracking Tighter | `-0.05em` | `tracking-tighter` | `{ tracking: 'tighter' }` | |
3169
+ | Tracking Tight | `-0.025em` | `tracking-tight` | `{ tracking: 'tight' }` | |
3170
+ | Tracking Normal | `0em` | `tracking-normal` | `{ tracking: 'normal' }` | |
3171
+ | Tracking Wide | `0.025em` | `tracking-wide` | `{ tracking: 'wide' }` | |
3172
+ | Tracking Wider | `0.05em` | `tracking-wider` | `{ tracking: 'wider' }` | |
3173
+ | Tracking Widest | `0.1em` | `tracking-widest` | `{ tracking: 'widest' }` | |
3174
+ | Arbitrary | `letter-spacing: .25em` | `tracking-[.25em]` | `{ tracking: '.25em' }` | |
3175
+ | CSS Variable | `letter-spacing: var(--t)` | `tracking-(--t)` | `{ tracking: '--t' }` | |
3176
+
3177
+ ## Line Height (Leading)
3178
+
3179
+ Controlling the leading (line height).
3180
+
3181
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3182
+ | :--------------- | :------------------------- | :------------------------------------------------------------------------------------------------------ | :------------------------- | :---------------------------- |
3183
+ | **Keywords** | `line-height: 1.5` | `leading-none`, `leading-tight`, `leading-snug`, `leading-normal`, `leading-relaxed`, `leading-loose` | `{ leading: 'none' }` etc. | |
3184
+ | **Fixed** | `line-height: .75rem`(etc) | `leading-3`, `leading-4`, `leading-5`, `leading-6`, `leading-7`, `leading-8`, `leading-9`, `leading-10` | `{ leading: 3 }` etc. | Maps to spacing scale. |
3185
+ | **Arbitrary** | `line-height: 3rem` | `leading-[3rem]` | `{ leading: '3rem' }` | |
3186
+ | **CSS Variable** | `line-height: var(--l)` | `leading-(--l)` | `{ leading: '--l' }` | **Sugar**: Auto-detects `--`. |
3187
+
3188
+ ### Text/Leading Shorthand
3189
+
3190
+ When both `text` (font-size) and `leading` (line-height) are specified together, they are automatically merged into a single Tailwind class using the `/` shorthand syntax.
3191
+
3192
+ | Input | Output | Note |
3193
+ | :---------------------------------- | :----------------- | :--------------------------------------- |
3194
+ | `{ text: 'lg', leading: 7 }` | `text-lg/7` | Numeric leading merged with text size. |
3195
+ | `{ text: 'sm', leading: 'tight' }` | `text-sm/tight` | Keyword leading merged with text size. |
3196
+ | `{ text: 'xl', leading: '1.5rem' }` | `text-xl/[1.5rem]` | Arbitrary leading merged with text size. |
3197
+ | `{ text: 'lg' }` | `text-lg` | No merge — `leading` not present. |
3198
+ | `{ leading: 7 }` | `leading-7` | No merge — `text` not present. |
3199
+
3200
+ ## Text Align
3201
+
3202
+ Controlling the alignment of text.
3203
+
3204
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3205
+ | :-------- | :-------------------------------- | :--------------------------------------------------------------------------------- | :--------------------------- | :--- |
3206
+ | **Align** | `text-align: left, center, right` | `text-left`, `text-center`, `text-right`, `text-justify`, `text-start`, `text-end` | `{ textAlign: 'left' }` etc. | |
3207
+
3208
+ ## Text Color
3209
+
3210
+ Controlling the text color.
3211
+
3212
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3213
+ | :-------------------- | :---------------- | :----------------------------------------------------------------------------- | :----------------------------------------- | :----------------------------------------- |
3214
+ | **Keywords** | `color: inherit` | `text-inherit`, `text-current`, `text-transparent`, `text-black`, `text-white` | `{ color: 'inherit' }` etc. | |
3215
+ | **Color** | `color: (value)` | `text-slate-50`(etc)`text-slate-950` (and full palette) | `{ color: 'slate-50' }` etc. | Full color palette. |
3216
+ | **Opacity** | `color: (value)` | `text-blue-500/50` | `{ color: { color: 'blue-500', op: 50 } }` | |
3217
+ | **CSS Var + Opacity** | `color: var(--c)` | `text-(--c)/50` | `{ color: { color: '--c', op: 50 } }` | CSS variables are auto-wrapped in `(...)`. |
3218
+ | **Arbitrary** | `color: (value)` | `text-[#50d71e]` | `{ color: '#50d71e' }` | |
3219
+ | **CSS Variable** | `color: var(--c)` | `text-(--c)` | `{ color: '--c' }` | **Sugar**: Auto-detects `--`. |
3220
+
3221
+ ## Text Decoration
3222
+
3223
+ Controlling the decoration of text.
3224
+
3225
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3226
+ | :----------------- | :------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------ | :---------------------------------- | :------------------------------------------------------------ |
3227
+ | **Line (string)** | `text-decoration-line: underline` | `underline`, `overline`, `line-through`, `no-underline` | `{ decoration: 'underline' }` etc. | String key. `'none'` → `no-underline` (resets ALL decoration) |
3228
+ | **Style** | `text-decoration-style: solid` | `decoration-solid`, `decoration-dashed`, `decoration-dotted`, `decoration-double`, `decoration-wavy` | `{ decorationStyle: 'solid' }` etc. | |
3229
+ | **Thickness** | `text-decoration-thickness: auto` | `decoration-0`, `decoration-1`, `decoration-2`, `decoration-4`, `decoration-8`, `decoration-auto`, `decoration-from-font` | `{ decorationThickness: 1 }` etc. | |
3230
+ | **Offset** | `text-underline-offset: auto` | `underline-offset-0`, `underline-offset-1`, `underline-offset-2`, `underline-offset-4`, `underline-offset-8`, `underline-offset-auto` | `{ underlineOffset: 1 }` etc. | |
3231
+ | **Color** | `text-decoration-color: currentColor` | `decoration-blue-500` | `{ decorationColor: 'blue-500' }` | |
3232
+ | **Arbitrary** | `text-decoration: (value)` | `decoration-[3px]` | `{ decorationThickness: '3px' }` | |
3233
+ | **Var** | `text-decoration: (value)` | `decoration-(--v)` | `{ decorationThickness: '--v' }` | **Sugar**: Auto-detects `--`. |
3234
+ | **Bool underline** | `text-decoration-line: underline` | `underline` | `{ underline: true }` | **Sugar**. `false` = NOOP. |
3235
+ | **Bool overline** | `text-decoration-line: overline` | `overline` | `{ overline: true }` | **Sugar**. `false` = NOOP. |
3236
+ | **Bool through** | `text-decoration-line: line-through` | `line-through` | `{ lineThrough: true }` | **Sugar**. `false` = NOOP. |
3237
+ | **Bool reset** | `text-decoration-line: none` | `no-underline` | `{ noUnderline: true }` | **Sugar**. Resets ALL decoration. Use for responsive reset. |
3238
+
3239
+ ## Text Transform
3240
+
3241
+ Controlling the capitalization of text.
3242
+
3243
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3244
+ | :------------------ | :-------------------------- | :---------------------------------------------------- | :------------------------------------ | :------------------------------------- |
3245
+ | **Transform** | `text-transform: uppercase` | `uppercase`, `lowercase`, `capitalize`, `normal-case` | `{ textTransform: 'uppercase' }` etc. | |
3246
+ | **Boolean (Sugar)** | `text-transform: uppercase` | `uppercase` | `{ uppercase: true }` | **Sugar**. Overwrites `textTransform`. |
3247
+
3248
+ ## Text Overflow & Whitespace
3249
+
3250
+ Controlling text wrapping and overflow.
3251
+
3252
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3253
+ | :---------------------- | :--------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------- |
3254
+ | **Overflow** | `text-overflow: ellipsis` | `truncate`, `text-ellipsis`, `text-clip` | `{ textOverflow: 'ellipsis' }`(etc) | |
3255
+ | **Wrap** | `text-wrap: wrap` | `text-wrap`, `text-nowrap`, `text-balance`, `text-pretty` | `{ textWrap: 'wrap' }`(etc) | |
3256
+ | **Indent Spacing** | `text-indent: calc(var(--spacing) * <number>)` | `indent-<number>` | `{ indent: <number> }` | v4: fully dynamic, accept any integer or 0.5-step decimal bare |
3257
+ | **Indent Px** | `text-indent: 1px` | `indent-px` | `{ indent: 'px' }` | |
3258
+ | **Indent Arbitrary** | `text-indent: 50%` | `indent-[50%]` | `{ indent: '50%' }` | |
3259
+ | **Indent CSS Variable** | `text-indent: var(--i)` | `indent-(--i)` | `{ indent: '--i' }` | **Sugar**: Auto-detects `--`. |
3260
+ | **Vertical** | `vertical-align: baseline` | `align-baseline`, `align-top`, `align-middle`, `align-bottom`, `align-text-top`, `align-text-bottom`, `align-sub`, `align-super` | `{ align: 'middle' }`(etc) | |
3261
+ | **Arbitrary Vertical** | `vertical-align: (value)` | `align-[4px]` | `{ align: '4px' }` | |
3262
+ | **Var Vertical** | `vertical-align: (value)` | `align-(--v)` | `{ align: '--v' }` | |
3263
+ | **Whitespace** | `white-space: normal` | `whitespace-normal`, `whitespace-nowrap`, `whitespace-pre`, `whitespace-pre-line`, `whitespace-pre-wrap`, `whitespace-break-spaces` | `{ whitespace: 'normal' }`(etc) | |
3264
+ | **Word Break** | `word-break: break-all` | `break-normal`, `break-all`, `break-keep` | `{ break: 'all' }` | v4.1: `break-words` moved to `wrap` |
3265
+ | **Overflow Wrap** | `overflow-wrap: anywhere` | `wrap-normal`, `wrap-break-word`, `wrap-anywhere` | `{ wrap: 'anywhere' }` | v4.1: new `wrap-*` prefix (was `break-*`) |
3266
+ | **Hyphens** | `hyphens: manual` | `hyphens-none`, `hyphens-manual`, `hyphens-auto` | `{ hyphens: 'auto' }` | |
3267
+ | **Content** | `content: none` | `content-none` | `{ content: 'none' }` | |
3268
+ | **Content Empty** | `content: ""` | `content-['']` | `{ content: '""' }` or `{ content: "''" }` | Compiler normalizes double-quote form `'""'` to single-quote output `content-['']`. Both JS forms produce identical class. |
3269
+ | **Arbitrary Content** | `content: (value)` | `content-['hello']` | `{ content: "'hello'" }` or `{ content: '"hello"' }` | Double-quote-wrapped values are normalized to single-quote brackets at compile time. |
3270
+ | **Var Content** | `content: (value)` | `content-(--c)` | `{ content: '--c' }` | |
3271
+ | **Line Clamp** | `line-clamp` | `line-clamp-1`, `line-clamp-2`, `line-clamp-3`, `line-clamp-4`, `line-clamp-5`, `line-clamp-6`, `line-clamp-none` | `{ lineClamp: 1 }`(etc) | |
3272
+ | **Arbitrary Clamp** | `line-clamp` | `line-clamp-[7]` | `{ lineClamp: 7 }` | |
3273
+ | **Var Clamp** | `line-clamp` | `line-clamp-(--c)` | `{ lineClamp: '--c' }` | |
3274
+
3275
+ ## List Style
3276
+
3277
+ Controlling list styles.
3278
+
3279
+ | Concept | CSS Rule | Tailwind v4 Class | `sz` Prop (Object Syntax) | Note |
3280
+ | :----------------- | :---------------------------------- | :--------------------------------------- | :------------------------------------------------------------ | :---------------------------- |
3281
+ | **Type** | `list-style-type: disc` | `list-none`, `list-disc`, `list-decimal` | `{ list: 'none' }`, `{ list: 'disc' }`, `{ list: 'decimal' }` | |
3282
+ | **Arbitrary Type** | `list-style-type: (value)` | `list-[upper-roman]` | `{ list: 'upper-roman' }` | |
3283
+ | **Var Type** | `list-style-type: var(--t)` | `list-(--t)` | `{ list: '--t' }` | **Sugar**: Auto-detects `--`. |
3284
+ | **Position** | `list-style-position: inside` | `list-inside`, `list-outside` | `{ listPos: 'inside' }`, `{ listPos: 'outside' }` | |
3285
+ | **Image** | `list-style-image: none` | `list-image-none` | `{ listImg: 'none' }` | |
3286
+ | **Arbitrary Img** | `list-style-image: url('/img.png')` | `list-image-[url('/img.png')]` | `{ listImg: "url('/img.png')" }` | |
3287
+ | **Var Image** | `list-style-image: var(--i)` | `list-image-(--i)` | `{ listImg: '--i' }` | **Sugar**: Auto-detects `--`. |
3288
+
3289
+ ## css: {} — Arbitrary CSS Escape Hatch
3290
+
3291
+ For CSS properties with no sz prop or Tailwind equivalent. Keys are camelCase; the compiler
3292
+ converts to kebab-case. CSS custom properties (`--*`) are passed through unchanged.
3293
+
3294
+ ```tsx
3295
+ <div sz={{ p: 4, css: { writingMode: 'vertical-lr', touchAction: 'none' } }} />
3296
+ // → p-4 [writing-mode:vertical-lr] [touch-action:none]
3297
+
3298
+ <div sz={{ hover: { css: { cursor: 'crosshair' } } }} />
3299
+ // → hover:[cursor:crosshair]
3300
+
3301
+ <div sz={{ css: { '--my-color': 'red' } }} />
3302
+ // → [--my-color:red]
3303
+ ```
3304
+
3305
+ TypeScript: `css?` is typed as `CSS.Properties` — full IDE autocomplete, typo protection.
3306
+ Works inside `dynamic()` at runtime.
3307
+
3308
+ ## sz Array Syntax
3309
+
3310
+ Pass an array to the `sz` prop to compose multiple sz objects with conditional items.
3311
+ Static items are pre-computed at build time; conditional items use `_szMerge` at runtime:
3312
+
3313
+ ```tsx
3314
+ <div
3315
+ sz={[
3316
+ { flex: true, items: "center", p: 4 }, // always — extracted at build time
3317
+ isActive && { bg: "blue-500" }, // runtime conditional
3318
+ isDisabled && { opacity: 50, cursor: "not-allowed" },
3319
+ ]}
3320
+ />
3321
+ ```
3322
+
3323
+ ## Reusing Styles
3324
+
3325
+ CSSzyx resolves style variables at build time — same output as inline objects, zero runtime.
3326
+
3327
+ ```tsx
3328
+ const card = { p: 6, rounded: 'xl', shadow: 'md' } as const;
3329
+
3330
+ sz={card} // direct — no override needed
3331
+ sz={{ ...card, p: 4 }} // spread — override p, keep rest
3332
+ sz={[card, isActive && { bg: 'blue-50' }]} // array — conditional composition
3333
+ sz={on ? activeStyle : inactiveStyle} // ternary — both branches resolved
3334
+ sz={{ scale: shrunk ? 75 : 100 }} // inline prop ternary — both literal values compiled at build time
3335
+ ```
3336
+
3337
+ **Rules:**
3338
+
3339
+ - Use `sz={var}` when no override needed (simpler)
3340
+ - Use `sz={{ ...var, key: val }}` only when overriding/adding
3341
+ - Variables in array elements, ternary branches, and chained initializers all resolve at build time
3342
+ - `sz={{ key: cond ? a : b }}` — both literal branches compiled to static Tailwind classes; CSS variable fallback only when a branch is a runtime expression
3343
+ - `sz={{ ...(cond ? a : b), static: val }}` — conditional spread hoist: compiler resolves both branches at build time
3344
+ - Imported variables / function call results fall back to `_sz()` runtime — dev mode emits a build-time compiler warning explaining the fallback reason and suggesting `szv()` or `dynamic()`
3345
+
3346
+ Full guide: `/docs/reusing-styles`
3347
+
3348
+ ## szv() — Variant Authoring
3349
+
3350
+ CVA-equivalent that returns sz objects. TypeScript infers valid keys/values from config — no
3351
+ manual type annotations needed. Numeric variant keys are supported.
3352
+
3353
+ ```tsx
3354
+ import { szv } from "csszyx";
3355
+
3356
+ const buttonSz = szv({
3357
+ base: {
3358
+ inlineFlex: true,
3359
+ items: "center",
3360
+ rounded: "md",
3361
+ fontWeight: "medium",
3362
+ },
3363
+ variants: {
3364
+ variant: {
3365
+ default: { bg: "primary", text: "primary-foreground" },
3366
+ outline: { border: true, borderColor: "blue-500", bg: "transparent" },
3367
+ ghost: { hover: { bg: "accent" } },
3368
+ },
3369
+ size: {
3370
+ sm: { h: 9, px: 3, text: "sm" },
3371
+ md: { h: 10, px: 4 },
3372
+ lg: { h: 11, px: 8 },
3373
+ },
3374
+ },
3375
+ defaultVariants: { variant: "default", size: "md" },
3376
+ });
3377
+
3378
+ <button sz={buttonSz({ variant: "outline", size: "sm" })} />;
3379
+
3380
+ // Numeric keys — e.g. index-based opacity variants
3381
+ const itemSz = szv({
3382
+ base: { rounded: "sm", shrink: 0 },
3383
+ variants: {
3384
+ idx: { 0: { opacity: 50 }, 1: { opacity: 70 }, 2: { opacity: 90 } },
3385
+ },
3386
+ defaultVariants: { idx: 0 },
3387
+ });
3388
+ <div sz={itemSz({ idx: 1 })} />; // → "rounded-sm shrink-0 opacity-70"
3389
+
3390
+ // TypeScript catches invalid values:
3391
+ buttonSz({ variant: "invalid" }); // ❌ TS error: '"invalid"' not assignable
3392
+ ```
3393
+
3394
+ All variant class combinations are catalogued at build time (compiler prescan) — Tailwind
3395
+ generates CSS for every combination, no runtime injection needed.
3396
+
3397
+ ## @csszyx/dynamic — Runtime CSS Injection
3398
+
3399
+ For styles from JSON / API / CMS / form renderer schemas:
3400
+
3401
+ ```tsx
3402
+ import { dynamic, preloadManifest } from "@csszyx/dynamic";
3403
+ // or: import { dynamic } from 'csszyx/dynamic';
3404
+
3405
+ // Optional: preload at app startup for zero-latency first inject
3406
+ await preloadManifest("/csszyx-manifest.json");
3407
+
3408
+ // Apply runtime sz object — CSS injected only for missing classes
3409
+ const cls = dynamic({
3410
+ p: 4,
3411
+ bg: "white",
3412
+ hover: { bg: "gray-50" },
3413
+ dark: { bg: "gray-900" },
3414
+ });
3415
+ ```
3416
+
3417
+ **Build-time extraction (Layer-1 prescan):** When `dynamic()` receives a static literal or
3418
+ module-level const, the compiler extracts classes at build time → Tailwind generates CSS
3419
+ ahead of time → no runtime injection needed. Works in Astro SSR without `client:*`.
3420
+
3421
+ ```tsx
3422
+ const boxStyles = { w: 7, h: 8, rounded: "sm" } as const;
3423
+ <div className={dynamic(boxStyles)} />; // CSS pre-generated, zero runtime inject
3424
+ ```
3425
+
3426
+ ### React hook
3427
+
3428
+ ```tsx
3429
+ import { useSz } from "@csszyx/dynamic/react";
3430
+ // or: import { useSz } from 'csszyx/dynamic/react';
3431
+
3432
+ function DynamicCard({ style }) {
3433
+ const { sz } = useSz();
3434
+ return <div className={sz(style)} />;
3435
+ }
3436
+ ```
3437
+
3438
+ Delta injection: CSS is injected only for classes not already in the pre-built stylesheet.
3439
+ SSR-safe: on the server, returns class names without CSSOM access.
3440
+
3441
+ ## Runtime Helpers
3442
+
3443
+ For dynamic classes at runtime (the only runtime overhead):
3444
+
3445
+ ```tsx
3446
+ import { _sz, _szIf, _szSwitch, _szMerge } from '@csszyx/runtime';
3447
+
3448
+ // Concatenate class strings
3449
+ <div className={_sz('base-class', conditionalClass)} />
3450
+
3451
+ // Conditional class
3452
+ <div className={_szIf(isActive, 'active-class', 'inactive-class')} />
3453
+
3454
+ // Switch/enum
3455
+ <div className={_szSwitch(status, {
3456
+ loading: 'opacity-50',
3457
+ error: 'border-red-500',
3458
+ success: 'border-green-500',
3459
+ })} />
3460
+
3461
+ // Merge (last wins for conflicts)
3462
+ <div className={_szMerge(baseClasses, overrideClasses)} />
3463
+ ```
3464
+
3465
+ For color CSS variables:
3466
+
3467
+ ```tsx
3468
+ import { __szColorVar } from "csszyx/lite";
3469
+ // Usage: __szColorVar('--ds-primary') → 'var(--ds-primary)'
3470
+ // __szColorVar('blue-500') → 'var(--color-blue-500)'
3471
+ // __szColorVar('#ff0000') → '#ff0000'
3472
+ ```
3473
+
3474
+ ## SSR Hydration
3475
+
3476
+ CSSzyx validates that server and client use the same mangle map:
3477
+
3478
+ ```tsx
3479
+ // Server (Next.js app/layout.tsx)
3480
+ import { initRuntime } from "@csszyx/runtime";
3481
+ import { headers } from "next/headers";
3482
+
3483
+ const hdrs = await headers();
3484
+ initRuntime({ checksum: hdrs.get("x-csszyx-checksum") ?? "" });
3485
+ ```
3486
+
3487
+ If the checksum mismatches, the runtime aborts hydration to prevent CSS corruption.
3488
+
3489
+ ### szRecover — per-element recovery opt-in
3490
+
3491
+ By default a hydration mismatch aborts the entire page. For specific
3492
+ subtrees where re-rendering on the client is cheaper than aborting,
3493
+ opt in per-element with the `szRecover` JSX attribute:
3494
+
3495
+ ```tsx
3496
+ <section szRecover="csr">
3497
+ {/* mismatch in this subtree triggers a client re-render instead of abort */}
3498
+ <UserGeneratedContent />
3499
+ </section>
3500
+
3501
+ <aside szRecover="dev-only">
3502
+ {/* same, but only in development; stripped from prod manifest */}
3503
+ <DebugPanel />
3504
+ </aside>
3505
+ ```
3506
+
3507
+ The build emits a `data-sz-recovery-token` attribute on each element
3508
+ plus a `<script id="__SZ_RECOVERY_MANIFEST__">` JSON tag in `<head>`.
3509
+ The runtime's `verifyRecoveryToken` matches the two at hydration time.
3510
+ The manifest stores both `checksum` (recovery token-set checksum) and
3511
+ `mangleChecksum` (the value checked against the page `data-sz-checksum`).
3512
+
3513
+ `szRecover` is typed on `React.HTMLAttributes` via `@csszyx/types/jsx` —
3514
+ no tsconfig change needed.
3515
+
3516
+ ## Production Build (Mangling)
3517
+
3518
+ In production, class names are mangled for maximum compression:
3519
+
3520
+ ```js
3521
+ // vite.config.ts (production)
3522
+ ...csszyx({ production: { mangle: true } })
3523
+ ```
3524
+
3525
+ Output: `<div class="z y x" />` — the CSS `.z { padding: 1rem }` etc. is injected automatically.
3526
+
3527
+ ### AST budget guard
3528
+
3529
+ Files larger than 50 000 AST nodes throw `ASTBudgetExceededError` at
3530
+ build time — pathologically large generated files (json-as-ts fixtures,
3531
+ GraphQL schemas) would otherwise hang the build. Raise the cap when you
3532
+ need:
3533
+
3534
+ ```js
3535
+ ...csszyx({ build: { astBudgetLimit: 100_000 } })
3536
+ ```
3537
+
3538
+ Or exclude the file from csszyx processing entirely before parsing:
3539
+
3540
+ ```js
3541
+ ...csszyx({ exclude: ['src/generated/**', /icon-dump\.tsx$/] })
3542
+ ```
3543
+
3544
+ ## Theme Auto-Scan (Custom Tokens → TypeScript Types)
3545
+
3546
+ When using Tailwind v4 `@theme` blocks for custom design tokens, enable `build.scanCss`
3547
+ to generate `.csszyx/theme.d.ts` — surfaces custom tokens in `sz` prop IntelliSense.
3548
+ Literal paths and simple globs are supported:
3549
+
3550
+ ```ts
3551
+ // vite.config.ts
3552
+ ...csszyx({ build: { scanCss: 'src/index.css' } })
3553
+ ```
3554
+
3555
+ ```css
3556
+ /* src/index.css */
3557
+ @theme {
3558
+ --color-brand-500: #6d28d9;
3559
+ --spacing-prose: 65ch;
3560
+ }
3561
+ ```
3562
+
3563
+ After the build, add `.csszyx/theme.d.ts` to your `tsconfig.json` `"include"` array.
3564
+ Result: `{ bg: 'brand-500' }` gets autocomplete and type-checking.
3565
+
3566
+ ## Tailwind v4 Compatibility
3567
+
3568
+ - Requires `@tailwindcss/vite` or `@tailwindcss/postcss` v4.x
3569
+ - `csszyx` Vite plugin MUST come before `tailwindcss` in plugins array
3570
+ - All spacing values are dynamic (any integer, 0.5-step decimals work bare)
3571
+ - Arbitrary values: `{ p: '5px' }` → `p-[5px]` (auto-wrapped)
3572
+ - CSS variables: `{ p: '--my-var' }` → `p-(--my-var)` (auto-wrapped)
3573
+
3574
+ ## Migrate CLI
3575
+
3576
+ Convert `className=` (JSX/TSX) or `class=` (HTML) to `sz=` props:
3577
+
3578
+ ### Basic usage
3579
+
3580
+ ```bash
3581
+ npx @csszyx/cli migrate src/ # migrate all JSX/TSX/HTML under src/
3582
+ npx @csszyx/cli migrate --dry-run # preview changes without writing files
3583
+ npx @csszyx/cli migrate --ignore "**/*.test.tsx,**/fixtures/**"
3584
+ npx @csszyx/cli migrate --pattern "src/components/**/*.tsx"
3585
+ ```
3586
+
3587
+ Migration logs are written to `.csszyx/logs/`. Add `.csszyx/` to `.gitignore`.
3588
+
3589
+ ### Audit — discover unrecognized classes
3590
+
3591
+ ```bash
3592
+ npx @csszyx/cli migrate --audit # scan + write .csszyx-todo.json (no file edits)
3593
+ ```
3594
+
3595
+ `.csszyx-todo.json` is a snapshot map of every class csszyx couldn't recognize.
3596
+ Each entry starts as `"sz:todo"` (not yet decided):
3597
+
3598
+ ```json
3599
+ {
3600
+ "btn": "sz:todo",
3601
+ "custom-card": "sz:todo"
3602
+ }
3603
+ ```
3604
+
3605
+ ### `.csszyx-todo.json` resolution routes
3606
+
3607
+ Edit the file to tell csszyx what to do with each class:
3608
+
3609
+ | Value | Meaning |
3610
+ | -------------------------- | ------------------------------------------------ |
3611
+ | `"sz:todo"` | Not yet decided — skip, surface in reports |
3612
+ | `"sz:keep"` | Keep in `className`, acknowledged as intentional |
3613
+ | `"sz:remove"` | Drop from output entirely |
3614
+ | `{ p: 4, bg: 'blue-500' }` | Direct sz object — merge into sz prop |
3615
+ | `"p-4 bg-blue-500"` | Tailwind string — auto-converted to sz |
3616
+ | `null` / `false` | Same as `"sz:todo"` (backwards compat) |
3617
+
3618
+ `sz:todo` entries always skip conversion — they are never silently parsed, even if
3619
+ the class happens to be a valid Tailwind class. This prevents accidental conversion
3620
+ of classes the developer has explicitly flagged as "not yet decided."
3621
+
3622
+ ### Display utilities
3623
+
3624
+ `csszyx migrate` emits canonical display props, not boolean sugar:
3625
+
3626
+ | Tailwind | Migrated sz |
3627
+ | ------------- | ---------------------------- |
3628
+ | `block` | `{ display: 'block' }` |
3629
+ | `inline` | `{ display: 'inline' }` |
3630
+ | `flex` | `{ display: 'flex' }` |
3631
+ | `inline-flex` | `{ display: 'inline-flex' }` |
3632
+ | `hidden` | `{ display: 'none' }` |
3633
+
3634
+ Manual authoring can still use `{ flex: true }`, `{ inlineFlex: true }`, etc.
3635
+ The migrate command uses `display` so duplicate display utilities are visible as
3636
+ one semantic CSS property. Conflicting display utilities in the same variant
3637
+ scope, such as `block flex` or `md:block md:flex`, are left unresolved instead
3638
+ of guessed. `flex flex-1` is safe and migrates to
3639
+ `{ display: 'flex', flex: '1' }`.
3640
+
3641
+ ### `--resolve-todos` — apply the resolution map
3642
+
3643
+ ```bash
3644
+ npx @csszyx/cli migrate --resolve-todos .csszyx-todo.json
3645
+ ```
3646
+
3647
+ Reads `.csszyx-todo.json` and applies it during migration.
3648
+ `--resolve-todos` is **read-only**: it never writes to the todo file.
3649
+ Still-unresolved classes appear in the console and log only.
3650
+ Re-run `--audit` to get a fresh snapshot when ready.
3651
+
3652
+ ### `--inject-todos` — mark unrecognized classes in code
3653
+
3654
+ ```bash
3655
+ npx @csszyx/cli migrate --inject-todos
3656
+ ```
3657
+
3658
+ Inserts `{/* @sz-todo: classname1, classname2 */}` above elements with unrecognized
3659
+ classes — a visual marker so you can grep or skim the diff to find what still needs
3660
+ attention. When `--resolve-todos` is active, `--inject-todos` is automatically enabled
3661
+ for still-unresolved classes.
3662
+
3663
+ ### Full workflow
3664
+
3665
+ ```bash
3666
+ # 1. Dry run to preview
3667
+ npx @csszyx/cli migrate --dry-run
3668
+
3669
+ # 2. Audit to find unknowns
3670
+ npx @csszyx/cli migrate --audit
3671
+ # → writes .csszyx-todo.json
3672
+
3673
+ # 3. Edit .csszyx-todo.json
3674
+ # → set "sz:keep", "sz:remove", or direct sz objects for each entry
3675
+
3676
+ # 4. Apply with resolution map
3677
+ npx @csszyx/cli migrate --resolve-todos .csszyx-todo.json
3678
+
3679
+ # 5. Re-audit if anything remains unresolved
3680
+ npx @csszyx/cli migrate --audit
3681
+ ```
3682
+
3683
+ ### HTML files
3684
+
3685
+ Converts `class="..."` → `sz="..."`. FOUC prevention CSS is injected into
3686
+ `<head>` by default. Runtime script injection is **opt-in** — without it,
3687
+ `[sz]` elements stay hidden (FOUC CSS hides them until the runtime sets
3688
+ `body.sz-ready`).
3689
+
3690
+ ```bash
3691
+ # CDN runtime (default URL: https://cdn.csszyx.com/runtime.js)
3692
+ npx @csszyx/cli migrate public/ --inject-runtime cdn
3693
+ # Local runtime (default path: csszyx-runtime.js)
3694
+ npx @csszyx/cli migrate public/ --inject-runtime local
3695
+ # Custom URLs
3696
+ npx @csszyx/cli migrate public/ --inject-runtime cdn --cdn-url https://my-cdn.com/csszyx.js
3697
+ npx @csszyx/cli migrate public/ --inject-runtime local --local-path ./vendor/csszyx-runtime.js
3698
+ # Format and FOUC options
3699
+ npx @csszyx/cli migrate public/ --braces # sz="{ p: 4 }" instead of sz="p: 4"
3700
+ npx @csszyx/cli migrate public/ --no-fouc # skip FOUC prevention CSS injection
3701
+ ```