Change styles when element states change.
In Sfumato, you can make any utility class conditional by prefixing it with a variant that specifies the state you want to target.
For example, to set the background color to sky-500 when an element is hovered, use the class hover:bg-sky-500
:
Try interacting with the anchor button above to see hover, focus, and active states.
Sfumato offers a wide range of variants to cover nearly any scenario, including:
You can even combine multiple variants to target highly specific situations—for instance, changing the background color on hover, but only when it is also not focused:
You can target elements when they are the first-child or last-child using the first and last variants, as well as children whose position in the markup is an odd or even number.
You can also target children by specific position using nth-* and nth-last-* variants:
When you need to style an element based on the state of some ancestor (e.g. parent) element, identify the ancestor with the group
class, and use group-*
variants like group-hover
to style the target element:
When groups are nested, you can style descendants based on the state of a specific ancestor group by giving that ancestor a unique group name using a group/{name}
class, and including that name in variants using classes like group-hover/{name}
:
When you need to style an element based on the state of a previous sibling element, identify the sibling with the peer
class, and use peer-*
variants like peer-hover
to style the target element. Type some text into the field below to see this in action:
Note: CSS only allows this to work when evaluating the previous sibling
When using more than one peer, you can style an element based on the state of a specific peer by giving that peer a unique name using a peer/{name}
class, and including that name in variants using classes like peer-checked/{name}
:
Style the button within file inputs using the file
variant:
Style the bullets and counters in lists using the marker
variant on the parent list block, or individual list items:
You can style text selections using the selection
variant.
In a tranquil temple, a student asked the master for answers. The master poured tea into the cup until it overflowed. “Sometimes,” the master smiled, “the cup must be emptied to be filled anew.” But now the space is yours to fill with new questions and curiosities.
Try selecting text in the paragraph above to see this in action.
You can style the first letter or first line in a block of content using the first-letter
and first-line
variants, respectively:
Many have said... In a tranquil temple, a student asked the master for answers. The master poured tea into the cup until it overflowed. “Sometimes,” the master smiled, “the cup must be emptied to be filled anew.” But now the space is yours to fill with new questions and curiosities.
The pointer
media query is used to target elements when the user has a primary pointing device, like a mouse, and the accuracy of that pointing device.
Use the pointer-fine
to target an accurate pointing device, like a mouse or trackpad, or pointer-coarse
to target a less accurate pointing device, like a finger, which can be useful for providing larger click targets on touch devices:
Try emulating a touch device in the browser developer tools to see pointer-based changes
The pointer
variants only target the primary pointing device, while the any-pointer
variants are used to target any pointing devices that might be available. Use the any-pointer-fine
and any-pointer-coarse
variants as you would their equivalent pointer variants.
You can also use pointer-none
and any-pointer-none
to target the absence of a pointing device.
Though it's usually better to style child elements themselves, you can use the *
variant in cases where you need to style children. This is especially useful when you don’t have control over them (like in third party injected code).
Likewise, the **
variant can be used to style all descendants of an element.
Similar to arbitrary values, arbitrary variants let you create custom selector variants.
Arbitrary variants are simply formatted strings that represent the selector, wrapped in square brackets. For example, the arbitrary variant below changes the cursor to a disallowed pointer when the element is being dragged:
You can also use at-rules like @media or @supports in arbitrary variants:
For times when you're using the same arbitrary variant more than once, you should consider creating a custom variant using the @custom-variant
directive:
Following are state pseudo-class variants:
Use the not-{pseudo-class} variant to set styles when a state is not true, like "not hover".