Scopes are an incredible useful feature of Assembler CSS that allow you to set properties
to a child element or to a pseudo-element. Using a scope is done by prefixing the property
name with the !
symbol and the scope’s name.
For example, scopes allow you set a property to the first letter in a text.
<div x-style="color:royalblue; first-letter!color:tomato; ...">
First letter scope
</div>
Another useful thing you could do is combine a scope with a state to obtain the desired effect.
<input x-style="placeholder!color:slateblue; placeholder!color.focus:coral; ..."
placeholder="Email address">
Creating scopes
The best thing about scopes is that you can create your own! So, for example, if a certain pseudo-element selector is not supported by default, you don’t have to wait until we implement it.
Writing your own scope is simply a matter of defining a custom CSS variable suffixed with --scope
.
The content of the CSS variable must be a selector that targets either a child element or a pseudo-element.
In order for you to be able to build a custom selector, Assembler CSS provides you with a series of placeholders.
$var
- The name of the variable holding the value set to the property$property
- The name of the targeted CSS property$value
- The value of the property in the formvar(--asm-var)
$variants
- A collection of alternative, cross-browser, CSS property-value pairs, or an empty string$body
- A combination between$property
,$value
, and$variants
placeholders, representing the body of the current CSS rule.$class
- The CSS selector class that identifies the current scope$state
- The CSS scope associated with the property, or an empty string$selector
- A combination between$class
and$state
placeholders, representing the current CSS selection rule
Let’s exemplify how one can create a custom scope by building a scope named bullet
that targets the ::marker
pseudo-element.
The only thing we need to do is to define the scope itself.
:root {
--bullet--scope: "$selector::marker { $body }";
}
Now we can start using our newly created scope.
- JavaScript
- HTML
- CSS
<ul>
<li x-style="bullet!color:red">JavaScript</li>
<li x-style="bullet!color:green">HTML</li>
<li x-style="bullet!color:blue">CSS</li>
</ul>
The above scope works great when setting individual values,
but what if we want to set the property for all ::marker
pseudo-elements under ul
?
We can simply define a new scope bullet-l1
that will do exactly that.
:root {
--bullet-l1--scope: "$selector > *::marker { $body }";
--bullet--scope: "$selector::marker { $body }";
}
The order in which you declare scopes matters when multiple scopes targets the same pseudo-element or element,
so we must make sure we declare bullet
after bullet-l1
.
This way we can use bullet
to overwrite values for individual elements.
- CSS
- HTML
- JavaScript
<ul x-style="bullet-l1!color:green; bullet-l1!content:'✓'; ...">
<li>CSS</li>
<li>HTML</li>
<li x-style="bullet!color:red; bullet!content:'✗'">JavaScript</li>
</ul>
Built-in scopes
Below is the full list of scopes that Assembler CSS is providing, together with their definitions.
Scope | Definition |
---|---|
before |
$selector::before { $body }
|
after |
$selector::after { $body }
|
selection |
$selector::selection { $body }
|
placeholder |
$selector::placeholder { $body }
|
first-letter |
$selector::first-letter { $body }
|
first-line |
$selector::first-line { $body }
|
marker |
$selector::marker { $body }
|
marker-l1 |
$selector > *::marker {$body}
|
even |
$selector:nth-child(even) {$body}
|
odd |
$selector:nth-child(odd) {$body}
|
first |
selector:first-child {$body}
|
last |
selector:last-child {$body}
|
l1 |
$selector > * {$body}
|
l2 |
$selector > * > * {$body}
|
sibling |
$selector > * + * {$body}
|
child |
$selector > $class {$body}
|
dark |
@media(prefers-color-scheme: dark) {$selector {$body}}
|
light |
@media(prefers-color-scheme: light) {$selector {$body}}
|
landscape |
@media(orientation: landscape) {$selector {$body}}
|
portrait |
@media(orientation: portrait) {$selector {$body}}
|
motion-reduce |
@media(prefers-reduced-motion: reduce) {$selector {$body}}
|
motion-safe |
@media(prefers-reduced-motion: no-preference) {$selector {$body}}
|
text-clip |
$selector {-webkit-background-clip: text !important;
-moz-background-clip:text !important;
background-clip:text !important;}
|
Text clip
The text-clip
scope is used only to overcome a bug in Chromium-based browsers when using
a CSS variable, having the value text
, for the background-clip
property.
<div x-style="text-clip!bg-clip:text; color:transparent; gradient:red, blue; ...">
Text clip
</div>