Appearance
CSS at-rules β
In vanilla CSS, it's not possible to write at-rules in an element's attributes. Bring in some additional tooling βfor example Tailwind CSS, Windi CSS, or in this case UnoCSSβ and you can.
TIP
As always with unocss-preset-css
, the ruleset can have more than one rule (docs: CSS rulesets > Multiple CSS declarations) and/or block at-rules (docs: CSS block at-rules) and/or customized selectors. For the sake of legibility, the examples on this page use single-rule rulesets with no custom selectors.
π You can experiment with all of these examples in this UnoCSS Play.
Layers β
To put CSS rules in a layer block at-rule, write your CSS ruleset in the class attribute prefixed with the @layer_<layer name>
.
class="@layer_<layer name>{<property>:<value>}"
TIP
Unlike everywhere else with unocss-preset-css
, underscores in <layer name>
are not replaced with spaces.
WARNING
You have to tell UnoCSS to use CSS layers, by adding outputToCssLayers: true
to your uno.config.(j|t)s
configuration.
Input
html
<div class="@layer_stuff{color:red}">
This is red
</div>
ts
// β¦
export default defineConfig({
outputToCssLayers: true,
// β¦
})
Output
Front end
This is redCSS
css@layer stuff { .\@layer_stuff\{color\:red\} { color: red; } }
You can use multiple layers, and control their order in the cascade.
β οΈ unocss-preset-css
does not support statement at-rules. Notably this means you can't write a class name to generate @layer stuff, other;
. Instead, use UnoCSS's layer
config field (docs).
Input
html
<div class="@layer_other{color:red} @layer_stuff{color:blue}">
This is red
</div>
ts
// β¦
export default defineConfig({
layers: {
other: 2,
stuff: 1,
},
outputToCssLayers: true,
// β¦
})
Output
Front end
This is redCSS
TIP
Notice that UnoCSS does not generate a
@layer
statement at-rule. Instead, it puts each layers' styles in a single@layer
block at-rule, and orders those blocks according to thelayers
config.If you have additional CSS not generated by UnoCSS (for example CSS in a separate stylesheet), make sure it comes after the UnoCSS-generated CSS to guarantee the UnoCSS-configured layer order is respected.
Alternatively, add an
@layer
statement at-rule before the UnoCSS-generated styles.css@layer stuff { .\@layer_stuff\{color\:blue\} { color:blue; } } @layer other { .\@layer_other\{color\:red\}{ color:red; } }
Everything else β
To put CSS rules in another block at-rule, write your CSS ruleset in the class attribute prefixed with the at-rule.
class="<at-rule>{<property>:<value>}"
TIP
Like everywhere else with unocss-preset-css
except for layer block at-rules, underscores in <at-rule>
are replaced with spaces. To use a literal underscore, escape it with a backslash (\
). Like everywhere else with unocss-preset-css
except for layer block at-rules, underscores in <at-rule>
are replaced with spaces. To use a literal underscore, escape it with a backslash (\
).
Input
html
<div class="@media(width<768px){color:red}">
Red on windows narrower than 768px.
</div>
<div class="@media(width>=768px){color:red}">
Red on windows 768px wide or wider.
</div>
Output
Front end
Red on windows narrower than 768px.Red on windows 768px wide or wider.CSS
css@media (width < 768px) { .\@media\(width\<768px\)\{color\:red\} { color: red; } } @media (width >= 768px) { .\@media\(width\>\=768px\)\{color\:red\} { color: red; } }
Multiple at-rules β
Layer + arbitrary β
To combine a layer block at-rule and an arbitrary block at-rule, string the class name prefixes together:
@layer_<layer name><at-rule>{<property>:<value>}
or <at-rule>@layer_<layer name>{<property>:<value>}
.
Here's an example of supporting aspect-ratio in Safari 13 and 14 (read Adding Safari 14 Support To Tailwind's Aspect Ratio for more info) with inline class
CSS.
Input
html
<div
class="
{aspect-ratio:1_/_1}
{border:1px_solid_red}
{width:4rem}
@layer_safari-14@supports_not_(aspect-ratio:1_/_1)[&::before]{content:.,float:left.,padding-top:calc(100%)}
@layer_safari-14@supports_not_(aspect-ratio:1_/_1)[&::after]{clear:left.,content.,display:block}
"></div>
Output
Front end
CSS
css@media (width < 768px) { .\@media\(width\<768px\)\{color\:red\} { color: red; } } @media (width >= 768px) { .\@media\(width\>\=768px\)\{color\:red\} { color: red; } }
Arbitrary + arbitrary β
DANGER
unocss-preset-css
does not support combining multiple arbitrary at-rule blocks in a single class.
You might be able to use a wrapping element.
Input
html
<div class="{display:none} @supports(-webkit-hyphens:none){display:block}">
<div class="@media(width<768px){color:red}">
Red on windows narrower than 768px. Safari.
</div>
<div class="@media(width>=768px){color:red}">
Red on windows 768px wide or wider. Safari.
</div>
</div>
<div class="{display:none} @supports_not_(-webkit-hyphens:none){display:block}">
<div class="@media(width<768px){color:red}">
Red on windows narrower than 768px. Not Safari.
</div>
<div class="@media(width>=768px){color:red}">
Red on windows 768px wide or wider. Not Safari.
</div>
</div>
Output
Front end
Red on windows narrower than 768px. Safari.Red on windows 768px wide or wider. Safari.Red on windows narrower than 768px. Not Safari.Red on windows 768px wide or wider. Not Safari.CSS
css.\{display\:none\} { display: none; } @media (width < 768px) { .\@media\(width\<768px\)\{color\:red\}{ color: red; } } @media (width >= 768px) { .\@media\(width\>\=768px\)\{color\:red\}{ color: red; } } @supports not (-webkit-hyphens:none) { .\@supports_not_\(-webkit-hyphens\:none\)\{display\:block\}{ display: block; } } @supports(-webkit-hyphens:none) { .\@supports\(-webkit-hyphens\:none\)\{display\:block\}{ display: block; } }
Layer + layer β
DANGER
unocss-preset-css
does not support combining multiple layer at-rule blocks in a single class.
You might be able to use a wrapper element. I'm not sure what it would mean, but maybe there's some interesting use case.
Input
html
<details id="doubled-layers">
<summary>Toggle me</summary>
</details>
<div class="{display:none} [body:has(#doubled-layers[open])_&]{display:block}">
<div class="@layer_stuff{color:red}">
Toggle is open
</div>
</div>
<div class="{display:none} [body:has(#doubled-layers:not([open]))_&]{display:block}">
<div class="@layer_stuff{color:red}">
Toggle is closed
</div>
</div>
ts
// β¦
export default defineConfig({
layers: {
other: 2,
stuff: 1,
},
outputToCssLayers: true,
// β¦
})
Output
Front end
Toggle me
Toggle is openToggle is closedCSS
css@layer default { .\{display\:none\} { display: none; } } @layer stuff { .\@layer_stuff\{color\:red\} { color: red; } } @layer other{ .\@layer_other\[body\:has\(\#doubled-layers\:not\(\[open\]\)\)_\&\]\{display\:block\} { body:has(#doubled-layers:not([open])) & { display: block; } } .\@layer_other\[body\:has\(\#doubled-layers\[open\]\)_\&\]\{display\:block\} { body:has(#doubled-layers[open]) & { display: block; } } }