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$variantsplaceholders, 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$classand$stateplaceholders, 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>