Conditions
Combine states, breakpoints, modes and conditional CSS.
Composition
<div class="fg-red:hover@sm">Hover at sm and above</div>With the current preset, fg-red uses --color-red, :hover selects the hovered element, and @sm applies (width>=52.125rem). The color token changes with the active mode; the breakpoint determines when the rule applies. The final result also depends on the CSS cascade.
Load the base stylesheet (normally through @import '@master/css') to establish @layer theme, base, defaults, components, utilities;. The generated rules below include theme dependencies; they do not add the base layer statement. Custom project settings can change tokens, conditions and modes.
Complete generated CSS
@layer theme { :root, :host { --color-red: var(--color-red-60); --color-red-60: oklch(60.94% .2501 29.2); --color-red-50: oklch(62.82% .25 28.6) } @media (prefers-color-scheme:light) { :root { --color-red: var(--color-red-60) } } @media (prefers-color-scheme:light) { :host { --color-red: var(--color-red-60) } } @media (prefers-color-scheme:dark) { :root { --color-red: var(--color-red-50) } } @media (prefers-color-scheme:dark) { :host { --color-red: var(--color-red-50) } }}@layer utilities { @media (width>=52.125rem) { .fg-red\:hover\@sm:hover { color: var(--color-red) } }}Overview
Append a named condition or a simple native query to a class. The outer parentheses delimit the Master CSS suffix; parentheses inside it belong to CSS.
<div class="hidden@sm">Hidden at the named breakpoint</div><div class="hidden@media((width>=800px))">Hidden from 800px</div><div class="grid@supports((display:grid))">Grid when supported</div>@layer utilities { @supports (display:grid) { .grid\@supports\(\(display\:grid\)\) { display: grid } } @media (width>=800px) { .hidden\@media\(\(width\>\=800px\)\) { display: none } } @media (width>=52.125rem) { .hidden\@sm { display: none } }}Native media queries, supports conditions and container queries decide whether the browser applies the rule. Master CSS preserves the query rather than testing the current browser during compilation.
Named conditions
@sm resolves a breakpoint token. Modes such as @dark resolve an explicit @mode definition. Custom variants resolve @custom-variant definitions. These names share one namespace: a collision is an error, and an unknown name never becomes a container query.
The preset provides these named variants:
| Name | Meaning |
|---|---|
@print, @screen, @all, @speech | Native media types |
@landscape, @portrait | Viewport orientation |
@motion, @reduce-motion | Reduced-motion preference |
@base, @default, @component, @utility | The corresponding existing CSS layer |
@starting-style | Native starting styles |
These names come from preset definitions. A project can define its own descriptive entry:
@custom-variant motion-safe { @media (prefers-reduced-motion: no-preference) { @slot; }}Breakpoints
A breakpoint token means “at or above this viewport width.” The original unit is preserved: a token defined as 800px generates a query using 800px, not 50rem.
<h2 class="font-lg font-2xl@sm font-3xl@md">Responsive heading</h2>Selectors work with every condition:
<button class="bg-blue-60:hover@sm">Save</button>See breakpoints and responsive design.
Modes
@light and @dark use the preset's explicit system-preference definitions. A project's @mode can replace either definition with manual activation or combined system and manual branches. @theme supplies the token values; it does not choose how a mode activates.
See modes and activation.
Layers
The preset's layer variants keep the stable order theme, base, defaults, components, utilities. Use @custom-variant with an explicit @layer wrapper for a named sublayer. See cascade layers.
Starting styles
Use the preset's @starting-style variant to define a transition's initial value.
<div popover class="opacity:0@starting-style transition:opacity|250ms@motion">Details</div>@layer utilities { @media (prefers-reduced-motion:no-preference) { .transition\:opacity\|250ms\@motion { transition: opacity 250ms } } @starting-style { .opacity\:0\@starting-style { opacity: 0 } }}Simple native queries
| Purpose | Suffix |
|---|---|
| Viewport width | @media((width>=800px)) |
| Aspect ratio | @media((aspect-ratio>=1.5)) |
| Resolution | @media((resolution>=2x)) |
| Supports declaration | @supports((display:grid)) |
| Nearest size container | @container((width>=40rem)) |
| Named container | @container(card|(width>=40rem)) |
| Style container | @container(style(--density:compact)) |
| encodes whitespace in query syntax. Quoted strings and escaped characters retain their literal content. CSS's resolution unit x stays native; Master CSS has no length multiplier unit.
Media
<div class="hidden@media((pointer:coarse))">Fine-pointer controls</div><div class="grid-cols:2@media((width>=50rem))">Responsive content</div>@layer utilities { @media (pointer:coarse) { .hidden\@media\(\(pointer\:coarse\)\) { display: none } } @media (width>=50rem) { .grid-cols\:2\@media\(\(width\>\=50rem\)\) { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)) } }}Supports
<div class="grid@supports((display:grid))">Content</div>@layer utilities { @supports (display:grid) { .grid\@supports\(\(display\:grid\)\) { display: grid } }}Containers
Choose a query container using ordinary CSS. The suffix contains the complete query, including a container name when needed.
<aside class="container:card/inline-size"> <div class="grid-cols:2@container(card|(width>=40rem))">Card content</div></aside>@layer utilities { .container\:card\/inline-size { container: card/inline-size } @container card (width>=40rem) { .grid-cols\:2\@container\(card\|\(width\>\=40rem\)\) { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)) } }}Style queries use their native form:
<div style="--density:compact"> <div class="p:8px@container(style(--density:compact))">Compact content</div></div>Ranges
Use native CSS comparisons, including chained ranges. Put and, or and not in a CSS custom variant. Do not abbreviate feature names or omit units.
<div class="hidden@media((width<40rem))">Hidden below 40rem</div><div class="grid-cols:2@media((40rem<=width<64rem))">Two columns within a range</div>@layer utilities { @media (width<40rem) { .hidden\@media\(\(width\<40rem\)\) { display: none } } @media (40rem<=width<64rem) { .grid-cols\:2\@media\(\(40rem\<\=width\<64rem\)\) { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)) } }}Combining wrappers
Multiple suffixes preserve their nesting and source order, including repeated wrappers of the same kind:
<div class="grid@media((width>=40rem))@media((hover:hover))@supports((display:grid))">Content</div>@layer utilities { @media (width>=40rem) { @media (hover:hover) { @supports (display:grid) { .grid\@media\(\(width\>\=40rem\)\)\@media\(\(hover\:hover\)\)\@supports\(\(display\:grid\)\) { display: grid } } } }}Comparable ranges in the same unit retain range priority. Incomparable units and expressions use a stable syntax-based order; Master CSS does not assume a browser root font size. A named condition and its equivalent native query share sorting data. Autofix cannot reorder wrappers merely because their current declarations happen to match.
Upgrading RC conditions
The old numeric and feature shorthand forms are historical syntax. Use the v2 RC migration guide to preserve the old generated result, including a project's former root-size assumption. The ordinary compiler never interprets those forms.
Simple queries in classes
Classes accept one media type, one parenthesized media feature or range, one supports declaration, or one container size or custom-property style query. Feature names are not restricted to a browser support database. Balanced functions inside a single value are preserved.
<div class="hidden@media(print) p-md@media((40rem<=width<64rem))"></div><div class="grid@supports((display:grid)) p-md@container(card|(width>=40rem))"></div><div class="p-md@container(style(--density:compact))"></div>Define compound queries, query lists, negation, selector() and literal pipes in CSS. These class forms report MASTER_QUERY_REQUIRES_CSS and generate no rule. Quoting a query does not enable additional syntax.
@custom-variant wide-screen { @media screen and (width >=50rem) { @slot; }}@custom-variant language-selector { @supports selector([lang|=en]) { @slot; }}<div class="p-md@wide-screen display:block@language-selector"></div>The class encoding replaces | with a space only outside strings, comments and CSS escapes. Native CSS, custom variants and mode definitions do not use that encoding. Repeated simple suffixes preserve their wrapper order. Equivalent media ranges share ordering evidence, while container query domains remain distinct. Different units are never converted for sorting. Within equivalent conditions and the same property scope, direct values follow named tokens.