Skip to Content
DocumentationCSS State & Element Selector

CSS Selectors

AliasCSS lets you target states, pseudo-elements, and nested elements directly from class names. The goal is simple: keep styling close to the markup while still using a strict, predictable selector grammar.

This page covers the three selector patterns you will use most:

  • Pseudo selectors such as :hover, :focus, and ::before
  • Element selectors such as descendant, child, and sibling targeting
  • Functional selectors such as :is(), :has(), :where(), and :not()
💡

Think of AliasCSS selectors as prefixes that modify where a utility is applied.


Quick start

If you only remember three patterns, remember these:

<div class="--hover-bgc-yellow">...</div> <div class="_h3-c-white">...</div> <div class="--is(_h3,_p)-c-black/8">...</div>

They mean:

  • --hover-bgc-yellow → apply background-color: yellow on :hover
  • _h3-c-white → target descendant h3 elements
  • --is(_h3,_p)-c-black/8 → target multiple selectors using :is()

Pseudo selectors

Use pseudo selector flags when a utility should only apply in a specific state or pseudo-element.

Basic syntax

--state-utility

Examples:

  • --hover-bgc-yellow
  • --focus-c-blue
  • --before-content-Hello
  • --placeholder-c-gray

Example

<div class="bgc-cccccc --hover-bgc-yellow"> Hover me </div> <div class="bgc-cccccc --h-bgc-yellow"> Hover me too </div>

Both classes target the same state:

:hover { background-color: yellow; }
ℹ️

--hover and --h are equivalent. Use full flags for readability, and shorthand flags when the markup gets utility-heavy.

Common pseudo selector examples

AliasCSS classMeaning
--hover-display-flexApply display: flex on hover
--focus-list-style-noneApply list-style: none on focus
--placeholder-c-grayStyle placeholder text color
--before-content-HelloAdd content: "Hello" to ::before
--selection-bgc-yellowStyle text selection background

Pseudo selector reference

Common

FlagShort flagCSS selector
--hover--h, --ho:hover
--focus--f, --fo:focus
--focus-within--fw:focus-within
--focus-visible--fv:focus-visible
--active--a, --ac:active
--visited--vi, --v:visited
--link--ln, --l:link
--disabled--di:disabled
--enabled--en:enabled
--checked--ch:checked
--invalid--inv:invalid
--valid--va:valid
--required--rq:required
--optional--op:optional
--placeholder--ph::placeholder
--before--bf::before
--after--af::after
--selection--s::selection
--target--tg:target
--root--rt:root

Full Reference

FlagShort flagCSS selector
--active--a, --ac:active
--after--af::after
--after-hover--afh::after:hover
--autofill--atf:-webkit-autofill
--anylink--al:-webkit-anylink
--backdrop--bd::backdrop
--before--bf::before
--before-hover--bfh::before:hover
--blank--bl:blank
--checked--ch:checked
--cue--cu::cue
--current--cur:current
--default--de:default
--disabled--di:disabled
--empty--em:empty
--enabled--en:enabled
--first-child--fc:first-child
--first-letter--fl::first-letter
--first-line--fln::first-line
--first-of-type--fot:first-of-type
--focus--f, --fo:focus
--focus-within--fw:focus-within
--focus-visible--fv:focus-visible
--file-selector-button--fsb::file-selector-button
--fullscreen--fs:fullscreen
--hover--h, --ho:hover
--hover-after--haf:hover::after
--hover-before--hbf:hover::before
--hover-target--htg:hover:target
--in-range--ir:in-range
--indeterminate--ind:indeterminate
--invalid--inv:invalid
--lang--lan:lang()
--last-child--lc:last-child
--last-of-type--lot:last-of-type
--link--ln, --l:link
--marker--m::marker
--only-child--oc:only-child
--only-of-type--oot:only-of-type
--optional--op:optional
--out-of-range--oor:out-of-range
--placeholder--ph::placeholder
--placeholder-shadow--phs::placeholder-shadow
--popover-open--po:popover-open
--read-only--ro:read-only
--read-write--rw:read-write
--required--rq:required
--root--rt:root
--selection--s::selection
--scrollbar--sb::-webkit-scrollbar
--scrollbar-track--st::-webkit-scrollbar-track
--scrollbar-thumb--stm::-webkit-scrollbar-thumb
--spelling-error--se::spelling-error
--target--tg:target
--user-invalid--ui:user-invalid
--valid--va:valid
--visited--vi, --v:visited
--where--w:where()

Element selectors

Use _-based selectors when you want a utility to target elements relative to the current element.

Basic syntax

_selector-utility

Examples:

  • _h3-c-white
  • _p-fs-14px
  • _button-bgc-blue

Example

<div class="_h3-c-white _p-fs-14px"> <h3>Hello World</h3> <p>Welcome to AliasCSS</p> </div>

Compiled CSS:

._h3-c-white h3 { color: white; } ._p-fs-14px p { font-size: 14px; }

Selector combinators

AliasCSS classCompiled selector
_div-df._div-df div { ... }
__div-df.__div-df > div { ... }
___div-df.___div-df + div { ... }
____div-df.____div-df ~ div { ... }
_all-c-red._all-c-red * { ... }
_child_div-df._child_div-df > div { ... }
_next_div-df._next_div-df + div { ... }
_siblings_div-df._siblings_div-df ~ div { ... }

Mental model

  • _element → descendant selector
  • __element → direct child selector
  • ___element → adjacent sibling selector
  • ____element → general sibling selector
💡

Use _ selectors for local component styling. They are powerful, but they stay easiest to maintain when scoped to a clear parent element.


Functional selectors

AliasCSS supports selector functions like :is(), :has(), :where(), and :not().

Unlike plain CSS, these functions accept AliasCSS-style selectors, not raw CSS selectors. That keeps the grammar consistent across the framework.

Prefix reference

PrefixCSS outputBehavior
--hs() or --has():has()Uses AliasCSS selector input
--n() or --not():not()Uses AliasCSS selector input
--is():is()Adds a space before the selector by default
--Is():is()Removes the space before the selector
--Has():has()Adds a space before the selector
--w() or --where():where()Adds a space before the selector by default
--W() or --Where():where()Removes the space before the selector

Example

<div class="--is(_h3,_p)-c-black/8 --Is(--hover)-bgc-black/2"> <h3>Hello World</h3> <p>Welcome to AliasCSS</p> </div>

Compiled CSS:

.--is\(_h3\,_p\)-c-black\/8 :is(h3, p) { color: oklch(from black l c h / 0.8); } .--Is\(--hover\)-bgc-black\/2:is(:hover) { background-color: oklch(from black l c h / 0.2); }

--is() vs --Is()

This difference is important:

  • --is(...) inserts a space before :is(...)
  • --Is(...) attaches :is(...) directly to the current selector

That means the two forms do not target the same thing.

⚠️

Use --Is(...) only when you intentionally want the selector function attached directly to the current class. In most cases, --is(...) is easier to reason about.


Structural selectors

Some selectors need arguments, such as :nth-child() or :not().

Examples

AliasCSS classMeaning
--nth-child-2n-ml-20pxApply margin-left to every even matching child
--nth-last-child-2-c-redApply color to the second child from the end
--n(_button)-d-noneApply display: none when the selector does not match _button
ℹ️

For argument-based selectors, always follow AliasCSS syntax exactly. Do not mix plain CSS selector syntax into the class name.


Best practices

  • Use full selector flags when readability matters more than brevity.
  • Use shorthand flags when working in utility-dense markup.
  • Prefer _element selectors for component-local styling instead of broad global targeting.
  • Keep selector-heavy classes readable. If one class starts doing too much, split the logic across multiple classes.
  • Document casing-sensitive forms such as --is() and --Is() clearly for your team.

Cheat sheet

--hover-bgc-yellow -> apply utility on :hover --focus-c-blue -> apply utility on :focus --before-content-Hello -> apply utility on ::before --placeholder-c-gray -> apply utility on ::placeholder _h3-c-white -> target descendant h3 __div-d-flex -> target direct child div ___div-mt-20px -> target adjacent sibling div ____div-bgc-gray -> target general sibling div --is(_h3,_p)-c-black/8 -> target multiple selectors with :is() --Is(--hover)-bgc-black/2 -> attach :is(:hover) directly --nth-child-2n-ml-20px -> target every 2n child
Last updated on