Syntax Tutorial

State Selectors

Learn how to append selectors for hover, focus, attributes, descendants, pseudo-elements, and custom states.

Overview

<div class="fg:blue-60:hover"></div><input class="border:red:invalid" /><details class="bg:white[open]" open></details>

State selectors let one declaration apply only when a selector matches. Append the selector after the declaration value:

property:value<selector>

Common examples include interaction states such as :hover, validation states such as :invalid, and attributes such as [disabled] or [open].

<h2 class="font:lg font:2xl:hover font:3xl:active">

Selectors can be stacked when the CSS selector itself needs more detail.

<div class="bg:blue-20:hover:not(.active)">

If you also need a breakpoint, mode, or other condition, put the conditional query after the selector.

<button class="bg:blue-60:hover@md">Save</button>

For readability, Master CSS can use selector variants to name selectors that appear often.

<div class="mt:sm:first"><div class="mt:sm:first-child"><div class="mt:sm:odd"><div class="mt:sm:nth-child(2n)"><div class="mt:sm:rtl"><div class="mt:sm:dir(rtl)">

You can also create project-specific selector variants for longer selectors.

<div class="font:semibold_:headings"><div class="font:semibold_:is(h1,h2,h3,h4,h5,h6)">

Basic selectors

Master CSS accepts native selector syntax. The selector is relative to the element that owns the class unless a combinator points to another element.

SelectorDescriptionPreview CSS
*Universal selector* { margin: 0; }
elementType selectorp { color: red; }
.classClass selector.box { padding: 1rem; }
#idID selector#header { background: blue; }
[attribute]Attribute selector[disabled] { opacity: 0.5; }
:pseudo-classPseudo-class selectora:hover { color: blue; }
::pseudo-elementPseudo-element selectorp::first-letter { font-size: 2em; }

* — Universal

Use * as a wildcard. In >*, every direct child matches.

<div class="bg:blue-60>*">    <div>hit</div>    <div>hit</div>    ...</div>

element

Use a type selector to target elements by tag name.

<div class="bg:blue-60>span">    <span>hit</span></div>

If a raw type selector is hard to read or conflicts with nearby syntax, wrap it with :is() or :where().

<span class="bg:blue-60:is(span)"></span>

.class

Use a class selector for custom application state, such as .active, .selected, or .expanded.

<div class="bg:blue-60.active active">...</div>

#id

Use an ID selector when the state is tied to a unique element.

<nav id="nav" class="bg:blue-60#nav">...</nav>

[attribute]

Use attribute selectors for DOM state that already lives in markup, such as [disabled], [open], aria-*, and data-*.

<button class="bg:blue-60[disabled]" disabled>Submit</button>

:pseudo-class

Use pseudo-classes for browser-managed states.

<button class="bg:blue-60:hover">Submit</button>

::pseudo-element

Use pseudo-elements such as ::before and ::after when the style should target generated content.

<div class="content:''::before">quotes</div>

Combinators

Combinators target elements by their relationship to the element that owns the class. Use them when the declaration should style a child, sibling, or descendant instead of the element itself.

SelectorDescriptionPreview CSS
A BDescendant selector (_)nav a { color: white; }
A > BChild selectorul > li { list-style: none; }
A + BAdjacent sibling selectorh1 + p { margin-top: 0; }
A ~ BGeneral sibling selectorh1 ~ p { color: gray; }

_ — Descendant

Use _ as the descendant combinator. It stands in for the CSS space, because spaces split class names in HTML.

<div class="bg:blue-60_div">    <div>hit</div>    <div>hit        <div>hit            <div>hit</div>        </div>    </div></div>

> — Child

Use > when only direct children should match.

<div class="bg:blue-60>div">    <div>hit</div></div>

+ — Adjacent sibling

Use + to style the next sibling when it appears immediately after the current element.

<div class="bg:blue-60+div"></div><div>hit</div>

~ — General sibling

Use ~ to style later siblings that share the same parent.

<div class="bg:blue-60~div"></div><div>hit</div><div>hit</div><div>hit</div>

Selector groups

Use , when the same declaration should apply to several selectors.

<div class="content:''::before,::after">quotes</div>
Generated CSS
@layer utilities {    .content\:\'\'\:\:before\,\:\:after::before,    .content\:\'\'\:\:before\,\:\:after::after {        content: ''    }}

Selector groups also work with combinators. In this example, the declaration applies to direct div and span children.

<div class="block>div,>span">hit</div>
Generated CSS
@layer utilities {    .block\>div\,\>span>div,    .block\>div\,\>span>span {        display: block    }}

Pseudo-classes

:hover, :active, :focus

Use interaction pseudo-classes to give controls feedback as people hover, press, focus, or navigate with a keyboard.

Try clicking the button to see states change

<button class="bg:blue-60 fg:white bg:blue-70:hover bg:blue-80:active">Submit</button>

Use :focus-visible for keyboard focus rings when you want to avoid showing the focus style after every pointer click.

<button class="outline:2px|solid|blue:focus-visible">Submit</button>

:first, :last, :odd, :even

Use structural shorthands such as :first, :last, :odd, :even, and :nth(N) to style list items by position.

  • avatar
    Dressing Table
    A dress-up space.
  • avatar
    Double Bed
    A sweet moment for everyone.
  • avatar
    Sofa
    A place to be lazy all day.
  • avatar
    Cabinet
    Secrets are hidden here.
  • avatar
    Desk
    A good partner in the office.
<ul class="">    <li class="bg:slate-5:even@light bg:gray-90:even@dark">…</li></ul>

:valid, :invalid, :required

Use form validation pseudo-classes to reflect native validity without writing JavaScript state.

Try typing co as a valid email address

<input class="b:red:invalid b:green:valid b:1px|solid" type="email" />

:disabled

Use :disabled for controls that cannot be interacted with.

<button class="opacity:.5:disabled" disabled>Submit</button>

:checked, :indeterminate

Use :checked and :indeterminate for checkboxes, radio buttons, switches, and custom controls backed by native inputs.

<input class="bg:blue-60:checked" type="checkbox" checked />

:rtl, :ltr

Use :rtl and :ltr to react to text direction. They map to :dir(rtl) and :dir(ltr).

<div class="mr:xs:rtl">...</div>

:has()

Use :has() when the current element should change because it contains a matching child or descendant.

<div class="bg:blue-60:has(.active)">    <div>Item 1</div>    <div class="active">Item 2</div>    <div>Item 3</div></div>

:not()

Use :not() to exclude a selector from the match.

<div class="fg:green-60:not(.active) active">...</div>

:of()

:of() is the only proprietary selector introduced by Master CSS. It lets the current element respond to a parent, ancestor, or previous sibling. Use native selectors first when they can express the relationship; use :of() when you need to style the current element from outside-in context.

Style the element when an ancestor matches.

<div class="active">    <div>        <div class="hidden:of(.active)">hidden</div>    </div></div>

Style the element when its parent matches.

<div class="active">    <div class="hidden:of(.active>)">hidden</div></div>

Style the element when its previous adjacent sibling matches.

<div class="active"></div><div class="hidden:of(.active+)">hidden</div>

Style the element when one of its preceding siblings matches.

<div class="active"></div><div></div><div class="hidden:of(.active~)">hidden</div>

Do not put combinators or pseudo-elements before :of().

<div class="hidden_div::before:of(.active)">hidden</div>

Pseudo-elements

::before, ::after

Use ::before and ::after to style generated content attached to the element.

Be the change you wish to see in the world.
<div class="content:open-quote::before content:close-quote::after">    Be the change you wish to see in the world.</div>

::scrollbar

Style scrollbars with ::scrollbar, ::scrollbar-thumb, ::scrollbar-track, ::scrollbar-button, ::scrollbar-corner, and ::scrollbar-track-piece shorthands.

Try scrolling horizontally and interact with the scroll bar

Cat
Bear
Fox
Dog
Bunny
Camel
Bird
Chicken
Crocodile
Elephant
Frog
<div class="size:0.375rem::scrollbar bg:neutral-50/.2::scrollbar-thumb overflow-x:auto">

Attribute selectors

[open]

Use [open] to style a <details> element while it is expanded.

<details class="bg:white[open]" open>    <summary>Details</summary>    <p>Details content goes here.</p></details>

[aria-<key>=<value>]

Use ARIA attributes when accessible state is already present in the DOM.

<div class="bg:blue-60[aria-checked=true]" aria-checked="true">...</div>

[data-<key>=<value>]

Use data-* attributes for component state that is not covered by native attributes or ARIA.

<div class="bg:blue-60[data-active]" data-active>...</div>

[<attr>=<value>]

Match an exact attribute value.

<input class="b:blue[type=checkbox]" type="checkbox" />

[<attr>^=<value>]

Match values that start with a specific string.

Links that start with http.

<a class="content:''[href^=http]::after" href="https://…">External</a>

[<attr>$=<value>]

Match values that end with a specific string.

<a class="content:''[href$='.pdf']::after" href="https://….pdf">PDF</a>

[<attr>*=<value>]

Match values that contain a specific string.

<div class="bg:blue-60[title*=master]" title="mastercss">...</div>

[<attr>|=<value>]

Match a value exactly or followed by a hyphen, which is common for language codes.

<div class="bg:blue-60[lang|=en]" lang="en-US">...</div>

[<attr>~=<value>]

Match one word inside a whitespace-separated attribute value.

<div class="bg:blue-60[title~=css]" title="master css">...</div>

  • Master UI


© 2026 Aoyue Design LLC.MIT License
Trademark Policy