Navigation

Syntax

Declarations and values

Accepted class forms, native value parsing, units, importance and fixed utilities.

On this page

A class starts with a registered utility or a native declaration, followed by optional selectors, conditions and importance. This page defines those declaration forms, value parsing and rejection rules. For a worked introduction, use the Syntax tutorial; for native property meanings, use the CSS reference.

The named forms below assume the default preset is loaded through @import '@master/css'. Project definitions can add or replace utilities. Native declarations do not require a registered utility.

Accepted forms

FormExampleMeaning
Static utilityflexA registered name; here, display: flex
Token utilityp-mdA registered prefix and token key; here, padding: var(--spacing-md)
Functional utilityp(12)A registered function with arguments; here, padding: calc(12 * 1px)
Native declaration(padding:1rem)One full CSS property and value

These are syntax shapes, not interchangeable spellings. Static, token and functional utilities can each contain several declarations: truncate, text-sm and grid-cols(2) are recipes. A native head contains exactly one declaration, which may use a CSS shorthand.

Generated CSS
@layer theme {  :root,  :host {    --spacing-md: 1rem  }}@layer utilities {  .flex {    display: flex  }  .p-md {    padding: var(--spacing-md)  }  .p\(12\) {    padding: calc(12 * 1px)  }  .\(padding\:1rem\) {    padding: 1rem  }}

Every form accepts suffixes. In p(12):hover@sm!, the head is p(12), :hover is the selector, @sm is the condition and ! marks importance. A suffix affects its own class only. Selectors and Conditions own their complete contracts.

Native declarations

Write (property:value) using the full property name. Master CSS reads the balanced head before parsing suffixes. A colon after a bare name starts a selector: flex:hover selects the registered flex utility; display:block is not an alternative to (display:block).

The closing boundary

Strings, comments, escapes, nested parentheses and brackets, and unquoted url() tokens follow CSS component-value boundaries. A ) inside a quoted string does not close the head:

<span class="(content:')')::before"></span>

A quoted parenthesis stays inside the value

The first closing parenthesis is quoted value text. The next one closes the declaration; ::before begins outside it.

Text description
  1. In (content:')')::before, content is the property and ')' is its quoted value.
  2. The ) inside the string is preserved. The next ) closes the native declaration head.
  3. The ::before suffix targets the pseudo-element. Its generated declaration is content: ')';.

Other CSS constructs keep their own boundaries inside the head:

ClassValue boundary
(width:calc(1px+(2px*3)))Nested parentheses belong to the calculation
(grid-template-columns:[start]|1fr|[end])Brackets enclose grid line names
(background-image:url(/a{b.svg))The brace belongs to the unquoted URL token
Generated CSS
@layer utilities {  .\(background-image\:url\(\/a\{b\.svg\)\) {    background-image:url(/a{b.svg)  }  .\(grid-template-columns\:\[start\]\|1fr\|\[end\]\) {    grid-template-columns: [start] 1fr [end]  }  .\(width\:calc\(1px\+\(2px\*3\)\)\) {    width: calc(1px + (2px * 3))  }  .\(content\:\'\)\'\)\:\:before::before {    content: ')'  }}

CSS escaping still applies inside a value. For an unquoted URL containing parentheses, use a quoted URL or CSS escapes so the token remains valid.

Invalid heads

A malformed head generates no rule; it is not retried as a utility or a different class form.

Rejected classReason
(display:blockMissing closing parenthesis
(color:red)(display:block)Two heads in one class
(color:red;display:block)More than one declaration
(display:block;)A top-level semicolon, even at the end
(width:calc(1px])Mismatched delimiters
(width:)Empty value for an ordinary property
(color:{red})A brace block as an ordinary property value
(width:calc(((…1px…)))) nested 65 levelsBrackets nested more than 64 levels deep

A custom property may have an empty value or a balanced brace block: (--slot:) and (--state:{open}) are accepted. (--slot:!important) is an empty important custom property, while (width:!important) is invalid.

Emission and browser validity

A syntactically valid property name can emit a declaration even when tooling does not list it. Native values are not limited to the preset, but they must still be valid for the property in the target browser. For example, (font-size:48) emits font-size: 48; it does not acquire px, and that nonzero unitless length is invalid CSS. Use (font-size:48px) for that length. A native property such as (field-sizing:content) needs no utility registration.

Generated CSS
@layer utilities {  .\(field-sizing\:content\) {    field-sizing: content  }  .\(font-size\:48px\) {    font-size: 48px  }}

Master CSS emits selected compatibility declarations, such as -webkit-backdrop-filter beside backdrop-filter. It does not add vendor-specific selectors or polyfill browser features. Inspect the generated CSS and use Compatibility for browser requirements and fallback design.

Generated CSS
@layer utilities {  .\(backdrop-filter\:blur\(16px\)\) {    -webkit-backdrop-filter: blur(16px);    backdrop-filter: blur(16px)  }  .\(background-color\:\#000\)\:\:-webkit-scrollbar::-webkit-scrollbar {    background-color: #000  }}

Value encoding

Spaces, strings and underscores

HTML whitespace separates classes, even when the value contains CSS quotes. Within a class value, an unquoted | encodes a space. Inside a quoted string, the pipe remains literal. Keep CSS punctuation such as commas and slashes in place.

<div class="(color:rgb(30|60|90/80%)) (content:'a|b')::before"></div>
Generated CSS
@layer utilities {  .\(animation-name\:slide_in\) {    animation-name: slide_in  }  .\(color\:rgb\(30\|60\|90\/80\%\)\) {    color: rgb(30 60 90/80%)  }  .\(color\:red\)_a a {    color: red  }  .\(content\:\'a\|b\'\)\:\:before::before {    content: 'a|b'  }}

The color value becomes rgb(30 60 90 / 80%); the content string stays 'a|b'. For an actual space in a CSS string, use a CSS escape such as \000020: (content:'New\000020collection')::before produces “New collection”. The six-digit escape avoids a terminating space in the HTML class.

An underscore inside the native head is literal, as in slide_in. After the head closes, _ starts a descendant selector: (color:red)_a targets descendant links. Registered utility names cannot contain _; a token key containing it can still be referenced through var(--name).

Functions and explicit variables

CSS functions remain values of the native property. Master CSS normalizes arithmetic spacing in calc(100%-2rem), through at most 64 levels of nested parentheses and chained subtractions such as 1px-2px-3px, and leaves anything deeper as written; the browser evaluates the calculation. It does not infer a token from a bare word or evaluate a CSS function as a utility call.

Generated CSS
@layer theme {  :root,  :host {    --color-red-60: oklch(60.94% .2501 29.2)  }  :root,  :host {    --color-red: var(--color-red-60)  }}@layer utilities {  .\(color\:var\(--color-red\)\) {    color: var(--color-red)  }  .\(width\:calc\(100\%-2rem\)\) {    width: calc(100% - 2rem)  }  .\(width\:calc\(100\%-var\(--spacing-md\)\)\) {    width: calc(100%-var(--spacing-md))  }}

Native color values retain their meaning: (color:red), (color:#175fe9) and (color:rgb(23,95,233)) all supply CSS values. fg-red instead selects a theme token. A var() reference is explicit; (font-family:mono) names the CSS family mono, not --font-mono. See Variables and modes for token resolution, modes and derived values.

Numbers and units

Native declarations preserve units. They do not convert rem to pixels or infer a unit from the property. Leading zeros on decimals are optional: (opacity:.5) and (opacity:0.5) supply the same numeric value.

Native valueInterpretation
(margin:1rem)Length relative to the root font size
(width:50%)Percentage resolved in the property's context
(rotate:30deg)Explicit angle
(animation-duration:200ms)Explicit time; .2s expresses the same duration
(opacity:.5)Unitless number
(background-image:image-set(url(a.png)|1x,url(b.png)|2x))Native image resolution in dots per CSS pixel

Whether a property accepts a number, length, percentage or other type is a CSS values and units rule. p(12) is different: the preset function explicitly multiplies its argument by 1px.

Negative values

Native negatives stay inside the value: (margin-top:-2rem). Direct numeric arguments use mt(-8). Negative token classes put - before the complete class: -mt-sm. The negative-token form requires a numeric token and a supporting utility; -p-sm is rejected because padding does not support it.

Generated CSS
@layer theme {  :root,  :host {    --spacing-sm: .75rem  }}@layer utilities {  .-mt-sm {    margin-top: calc(var(--spacing-sm) * -1)  }  .mt\(-8\) {    margin-top: calc(-8 * 1px)  }  .\(margin-top\:-2rem\) {    margin-top: -2rem  }}

Argument validation does not redefine the CSS property’s value constraints.

Registered utilities

Token names

Token prefixes are registered by utility definitions, not inferred from property abbreviations. p-md reads --spacing-md; fg-red and bg-red both read --color-red but set different properties. There is no automatic full-property equivalent such as padding-md, and no implicit numeric scale such as p-4: that key must exist in the selected namespace.

A static name wins over a same-spelled token class. For example, w-full remains width: 100% even if the project defines --container-full; pill remains a fully rounded radius even if --radius-pill exists. A static utility and a function with the same name register independently.

Use the token family index for complete prefix-to-namespace mappings, and utility definitions for registration and replacement rules. Theme tokens owns the workflow for defining and scoping project values.

A fixed spelling keeps its own definition

Both parents are 240px wide. The custom --container-full is 12rem (192px at a 16px root); w-full remains the fixed 100% utility.

Text description
  1. The configuration defines @theme { --container-full: 12rem; }. The preset already registers the complete fixed name w-full with width: 100%.
  2. w-full therefore fills the 240px parent. The explicit (width:var(--container-full)) class reads --container-full and gives the second block a 192px width.
  3. The token remains available through an explicit var() reference; defining it does not replace the fixed w-full registration.

Direct numeric values

Preset functions such as m(4), b(1) and grow(1) take one static number. Length functions emit a multiplication by 1px; grow(), shrink() and order() pass the number through, with order() requiring an integer. Zero, decimals and negative arguments follow each parameter's declared type.

Units and dynamic expressions are not numeric arguments: m(1px) and b(var(--x)) generate no rule. Use (margin:1rem) or (border-width:var(--x)) for those values. Direct values owns the complete function list, parameter types and generated declarations.

Recipes can coordinate properties or companions: text-sm includes size, line height and tracking, while animate-fade supplies an animation shorthand. Their lookup and override rules belong to text tokens and motion tokens.

Custom properties

A (--name:value) head declares a CSS custom property on the matched element. It can carry the same selectors and conditions as any other declaration. It does not register a utility or a theme token.

<div class="(--progress:40%) (--progress:60%):hover (width:var(--progress))">Progress</div>
Generated CSS
@layer utilities {  .\(--progress\:40\%\) {    --progress: 40%  }  .\(width\:var\(--progress\)\) {    width: var(--progress)  }  .\(--progress\:60\%\)\:hover:hover {    --progress: 60%  }}

var(--progress) uses normal CSS resolution and inheritance. An unresolved variable or an incompatible substituted value can make the consuming declaration invalid; use a CSS variable fallback where appropriate. The Syntax tutorial covers keeping a fixed class while supplying a dynamic value.

Composition and importance

Separate classes express independent decisions, such as b(1) b-solid b-line-control. Native shorthands remain supported: this authoring preference does not change CSS grammar. Repeat selectors and conditions on each class that needs them.

<ul class="block>li:hover@md (font-size:14px)>li:hover@md text-center>li:hover@md">…</ul>

Within the same layer, conditions and selector, recipes sort before single-declaration utilities, then native declarations. Single-declaration utilities sort by property family and coverage before value source; a token precedes a fixed or direct value for the same property. HTML class order does not determine the result:

Generated CSS
@layer theme {  :root,  :host {    --spacing-md: 1rem  }}@layer utilities {  .m-md {    margin: var(--spacing-md)  }  .mx-auto {    margin-inline: auto  }  .mt\(0\) {    margin-top: calc(0 * 1px)  }  .p-md {    padding: var(--spacing-md)  }  .p\(12\) {    padding: calc(12 * 1px)  }  .\(padding\:1rem\) {    padding: 1rem  }}

Here the native padding follows both utilities, while mt(0) and mx-auto override the relevant parts of m-md. Cascade layers owns the complete ordering contract. Use Reusing styles to choose a component class, @utility recipe or CSS mixin.

Importance

A final ! marks the class's declarations important. A trailing native !important inside a parenthesized value has the same effect; writing both emits it once. The text '!important' inside a string remains content.

Generated CSS
@layer utilities {  .text-center\! {    text-align: center !important  }  .\(color\:red\!important\) {    color: red !important  }  .\(color\:red\!important\)\! {    color: red !important  }  .\(content\:\'\!important\'\)\:\:before::before {    content: '!important'  }}

Importance covers every declaration in the recipe

One final ! marks all three declarations; ellipses omit their token references. It does not mark nearby HTML classes or the theme token definitions important.

Text description
  1. text-sm writes font-size, line-height and letter-spacing using its primary token and companion references.
  2. text-sm! marks all three generated declarations !important. The dependency declarations remain ordinary theme tokens.

Fixed utility lookup

The preset provides 292 fixed, single-declaration utilities. Each sets only its listed property: flex-col does not enable flex layout, b-none does not reset border width, and pill does not set a size. The multi-declaration truncate recipe is listed separately in Truncation.

Class, DeclarationsCSS
blockdisplay: block
inlinedisplay: inline
inline-blockdisplay: inline-block
flow-rootdisplay: flow-root
flexdisplay: flex
inline-flexdisplay: inline-flex
griddisplay: grid
inline-griddisplay: inline-grid
contentsdisplay: contents
list-itemdisplay: list-item
tabledisplay: table
inline-tabledisplay: inline-table
table-captiondisplay: table-caption
table-celldisplay: table-cell
table-columndisplay: table-column
table-column-groupdisplay: table-column-group
table-header-groupdisplay: table-header-group
table-footer-groupdisplay: table-footer-group
table-rowdisplay: table-row
table-row-groupdisplay: table-row-group
hiddendisplay: none
staticposition: static
relativeposition: relative
absoluteposition: absolute
fixedposition: fixed
stickyposition: sticky
visiblevisibility: visible
invisiblevisibility: hidden
isolateisolation: isolate
box-borderbox-sizing: border-box
box-contentbox-sizing: content-box
italicfont-style: italic
obliquefont-style: oblique
uppercasetext-transform: uppercase
lowercasetext-transform: lowercase
capitalizetext-transform: capitalize
underlinetext-decoration-line: underline
overlinetext-decoration-line: overline
line-throughtext-decoration-line: line-through
flex-rowflex-direction: row
flex-row-reverseflex-direction: row-reverse
flex-colflex-direction: column
flex-col-reverseflex-direction: column-reverse
flex-wrapflex-wrap: wrap
flex-nowrapflex-wrap: nowrap
flex-wrap-reverseflex-wrap: wrap-reverse
items-normalalign-items: normal
items-startalign-items: start
items-endalign-items: end
items-flex-startalign-items: flex-start
items-flex-endalign-items: flex-end
items-centeralign-items: center
items-baselinealign-items: baseline
items-stretchalign-items: stretch
content-normalalign-content: normal
content-startalign-content: start
content-endalign-content: end
content-flex-startalign-content: flex-start
content-flex-endalign-content: flex-end
content-centeralign-content: center
content-baselinealign-content: baseline
content-stretchalign-content: stretch
content-betweenalign-content: space-between
content-aroundalign-content: space-around
content-evenlyalign-content: space-evenly
self-autoalign-self: auto
self-normalalign-self: normal
self-startalign-self: start
self-endalign-self: end
self-flex-startalign-self: flex-start
self-flex-endalign-self: flex-end
self-centeralign-self: center
self-baselinealign-self: baseline
self-stretchalign-self: stretch
justify-normaljustify-content: normal
justify-startjustify-content: start
justify-endjustify-content: end
justify-flex-startjustify-content: flex-start
justify-flex-endjustify-content: flex-end
justify-centerjustify-content: center
justify-betweenjustify-content: space-between
justify-aroundjustify-content: space-around
justify-evenlyjustify-content: space-evenly
justify-stretchjustify-content: stretch
object-coverobject-fit: cover
object-containobject-fit: contain
object-fillobject-fit: fill
object-noneobject-fit: none
object-scale-downobject-fit: scale-down
object-centerobject-position: center
object-topobject-position: top
object-bottomobject-position: bottom
object-leftobject-position: left
object-rightobject-position: right
m-automargin: auto
mt-automargin-top: auto
mr-automargin-right: auto
mb-automargin-bottom: auto
ml-automargin-left: auto
mx-automargin-inline: auto
mxs-automargin-inline-start: auto
mxe-automargin-inline-end: auto
my-automargin-block: auto
mys-automargin-block-start: auto
mye-automargin-block-end: auto
top-autotop: auto
right-autoright: auto
bottom-autobottom: auto
left-autoleft: auto
inset-autoinset: auto
ix-autoinset-inline: auto
ixs-autoinset-inline-start: auto
ixe-autoinset-inline-end: auto
iy-autoinset-block: auto
iys-autoinset-block-start: auto
iye-autoinset-block-end: auto
w-autowidth: auto
h-autoheight: auto
size-x-autoinline-size: auto
size-y-autoblock-size: auto
min-w-automin-width: auto
min-h-automin-height: auto
min-size-x-automin-inline-size: auto
min-size-y-automin-block-size: auto
basis-autoflex-basis: auto
max-w-nonemax-width: none
max-h-nonemax-height: none
max-size-x-nonemax-inline-size: none
max-size-y-nonemax-block-size: none
w-fullwidth: 100%
w-fitwidth: fit-content
w-maxwidth: max-content
w-minwidth: min-content
h-fullheight: 100%
h-fitheight: fit-content
h-maxheight: max-content
h-minheight: min-content
size-x-fullinline-size: 100%
size-x-fitinline-size: fit-content
size-x-maxinline-size: max-content
size-x-mininline-size: min-content
size-y-fullblock-size: 100%
size-y-fitblock-size: fit-content
size-y-maxblock-size: max-content
size-y-minblock-size: min-content
min-w-fullmin-width: 100%
min-w-fitmin-width: fit-content
min-w-maxmin-width: max-content
min-w-minmin-width: min-content
min-h-fullmin-height: 100%
min-h-fitmin-height: fit-content
min-h-maxmin-height: max-content
min-h-minmin-height: min-content
min-size-x-fullmin-inline-size: 100%
min-size-x-fitmin-inline-size: fit-content
min-size-x-maxmin-inline-size: max-content
min-size-x-minmin-inline-size: min-content
min-size-y-fullmin-block-size: 100%
min-size-y-fitmin-block-size: fit-content
min-size-y-maxmin-block-size: max-content
min-size-y-minmin-block-size: min-content
max-w-fullmax-width: 100%
max-w-fitmax-width: fit-content
max-w-maxmax-width: max-content
max-w-minmax-width: min-content
max-h-fullmax-height: 100%
max-h-fitmax-height: fit-content
max-h-maxmax-height: max-content
max-h-minmax-height: min-content
max-size-x-fullmax-inline-size: 100%
max-size-x-fitmax-inline-size: fit-content
max-size-x-maxmax-inline-size: max-content
max-size-x-minmax-inline-size: min-content
max-size-y-fullmax-block-size: 100%
max-size-y-fitmax-block-size: fit-content
max-size-y-maxmax-block-size: max-content
max-size-y-minmax-block-size: min-content
basis-fullflex-basis: 100%
basis-fitflex-basis: fit-content
basis-maxflex-basis: max-content
basis-minflex-basis: min-content
order-firstorder: -999999
order-lastorder: 999999
pillborder-radius: calc(infinity*1px)
b-solidborder-style: solid
b-dashedborder-style: dashed
b-dottedborder-style: dotted
b-doubleborder-style: double
b-noneborder-style: none
bt-solidborder-top-style: solid
bt-dashedborder-top-style: dashed
bt-dottedborder-top-style: dotted
bt-doubleborder-top-style: double
bt-noneborder-top-style: none
br-solidborder-right-style: solid
br-dashedborder-right-style: dashed
br-dottedborder-right-style: dotted
br-doubleborder-right-style: double
br-noneborder-right-style: none
bb-solidborder-bottom-style: solid
bb-dashedborder-bottom-style: dashed
bb-dottedborder-bottom-style: dotted
bb-doubleborder-bottom-style: double
bb-noneborder-bottom-style: none
bl-solidborder-left-style: solid
bl-dashedborder-left-style: dashed
bl-dottedborder-left-style: dotted
bl-doubleborder-left-style: double
bl-noneborder-left-style: none
bx-solidborder-inline-style: solid
bx-dashedborder-inline-style: dashed
bx-dottedborder-inline-style: dotted
bx-doubleborder-inline-style: double
bx-noneborder-inline-style: none
bxs-solidborder-inline-start-style: solid
bxs-dashedborder-inline-start-style: dashed
bxs-dottedborder-inline-start-style: dotted
bxs-doubleborder-inline-start-style: double
bxs-noneborder-inline-start-style: none
bxe-solidborder-inline-end-style: solid
bxe-dashedborder-inline-end-style: dashed
bxe-dottedborder-inline-end-style: dotted
bxe-doubleborder-inline-end-style: double
bxe-noneborder-inline-end-style: none
by-solidborder-block-style: solid
by-dashedborder-block-style: dashed
by-dottedborder-block-style: dotted
by-doubleborder-block-style: double
by-noneborder-block-style: none
bys-solidborder-block-start-style: solid
bys-dashedborder-block-start-style: dashed
bys-dottedborder-block-start-style: dotted
bys-doubleborder-block-start-style: double
bys-noneborder-block-start-style: none
bye-solidborder-block-end-style: solid
bye-dashedborder-block-end-style: dashed
bye-dottedborder-block-end-style: dotted
bye-doubleborder-block-end-style: double
bye-noneborder-block-end-style: none
outline-solidoutline-style: solid
outline-dashedoutline-style: dashed
outline-dottedoutline-style: dotted
outline-doubleoutline-style: double
outline-noneoutline-style: none
text-lefttext-align: left
text-centertext-align: center
text-righttext-align: right
text-starttext-align: start
text-endtext-align: end
text-justifytext-align: justify
overflow-autooverflow: auto
overflow-hiddenoverflow: hidden
overflow-clipoverflow: clip
overflow-visibleoverflow: visible
overflow-scrolloverflow: scroll
overflow-x-autooverflow-x: auto
overflow-x-hiddenoverflow-x: hidden
overflow-x-clipoverflow-x: clip
overflow-x-visibleoverflow-x: visible
overflow-x-scrolloverflow-x: scroll
overflow-y-autooverflow-y: auto
overflow-y-hiddenoverflow-y: hidden
overflow-y-clipoverflow-y: clip
overflow-y-visibleoverflow-y: visible
overflow-y-scrolloverflow-y: scroll
whitespace-normalwhite-space: normal
whitespace-nowrapwhite-space: nowrap
whitespace-prewhite-space: pre
whitespace-pre-wrapwhite-space: pre-wrap
whitespace-pre-linewhite-space: pre-line
whitespace-break-spaceswhite-space: break-spaces
select-noneuser-select: none
select-textuser-select: text
select-alluser-select: all
select-autouser-select: auto
pointer-nonepointer-events: none
pointer-autopointer-events: auto
vertical-baselinevertical-align: baseline
vertical-topvertical-align: top
vertical-middlevertical-align: middle
vertical-bottomvertical-align: bottom
vertical-text-topvertical-align: text-top
vertical-text-bottomvertical-align: text-bottom
vertical-subvertical-align: sub
vertical-supervertical-align: super
container-inlinecontainer-type: inline-size
container-sizecontainer-type: size
container-normalcontainer-type: normal
wrap-anywhereoverflow-wrap: anywhere
wrap-break-wordoverflow-wrap: break-word
wrap-normaloverflow-wrap: normal
ellipsistext-overflow: ellipsis

start and end retain their native meaning, distinct from flex-start and flex-end. For logical axes, x means inline and y means block; t, r, b and l are physical sides. Fixed utilities accept selectors, conditions and !, and emit CSS when used.