Selector

The attributes defined in Pseudo-Class correspond to those defined in Selector, allowing them to be used directly as component props.


SelectorPseudo-Class
_active:active
_checked:checked
_default:default
_disabled:disabled
_empty:empty
_enabled:enabled
_first:first
_firstChild:first-child
_firstOfType:first-of-type
_focus:focus
_focusVisible:focus-visible
_focusWithin:focus-within
_hover:hover
_invalid:invalid
_lastChild:last-child
_lastOfType:last-of-type
_link:link
_onlyChild:only-child
_optional:optional
_readOnly:read-only

Any other pseudo-class or pseudo-element works the same way, as _nthChild for :nth-child or _placeholder for ::placeholder. A name that selects nothing, such as _notASelector, is a build error rather than CSS that matches nothing.

Pseudo-classes that take arguments get them from params, also in their group form:

1const example = (
2  <Box
3    _groupNthChild={{ params: ['odd'], color: 'red' }}
4    _nthChild={{ params: ['2n'], bg: 'gray' }}
5  />
6)
7// :is([role=group],[data-group]):nth-child(odd) .a{color:red}
8// .b:nth-child(2n){background:gray}
1const example = (
2  <Box
3    _groupNthChild={{ params: ['odd'], color: 'red' }}
4    _nthChild={{ params: ['2n'], bg: 'gray' }}
5  />
6)
7// :is([role=group],[data-group]):nth-child(odd) .a{color:red}
8// .b:nth-child(2n){background:gray}

A selector takes styles: an object, or CSS text such as _hover="color: red". Any other string, such as a class name, is a build error.

selectors

selectors takes any selector. A key with & says where the element goes; a key without & is relative to the element:

  • a pseudo-class name, as hover or focusVisible, is that pseudo-class of the element; a name that selects nothing, such as div, is a build error
  • a key starting with :, :: or [ applies to the element itself, as ':hover' or '[aria-busy]'
  • any other selector selects descendants, as '.child', '> p' or 'div p'
1const example = (
2  <Box
3    selectors={{
4      '&:hover, .parent &': { color: 'red' },
5      '[aria-busy]': { opacity: 0.5 },
6      '> p': { m: 0 },
7    }}
8  />
9)
10// .a:hover{color:red}
11// .parent .b{color:red}
12// .c[aria-busy]{opacity:.5}
13// .d > p{margin:0}
1const example = (
2  <Box
3    selectors={{
4      '&:hover, .parent &': { color: 'red' },
5      '[aria-busy]': { opacity: 0.5 },
6      '> p': { m: 0 },
7    }}
8  />
9)
10// .a:hover{color:red}
11// .parent .b{color:red}
12// .c[aria-busy]{opacity:.5}
13// .d > p{margin:0}

Nested rules in styled and css templates follow styled-components and Emotion: .child { } and > p { } select descendants, :hover { } and ::before { } apply to the component, and a rule nested in a selector list applies under each of its selectors.

Media Shorthands

These props wrap their styles in a fixed media query. They accept responsive arrays and nest in either direction with selectors and other at-rules.


SelectorMedia Query
_printprint
_screenscreen
_allall
_portrait(orientation:portrait)
_landscape(orientation:landscape)
_motionReduce(prefers-reduced-motion:reduce)
_motionSafe(prefers-reduced-motion:no-preference)
_contrastMore(prefers-contrast:more)
_contrastLess(prefers-contrast:less)
_forcedColors(forced-colors:active)
1const example = (
2  <Box
3    _motionReduce={{ transition: 'none' }}
4    _motionSafe={{ _hover: { transform: 'scale(1.05)' } }}
5    transition={['opacity .2s', null, 'all .3s']}
6  />
7)
1const example = (
2  <Box
3    _motionReduce={{ transition: 'none' }}
4    _motionSafe={{ _hover: { transform: 'scale(1.05)' } }}
5    transition={['opacity .2s', null, 'all .3s']}
6  />
7)

At-Rules

_media, _supports and _container take a record of queries to styles. A query can also sit in the key itself, as in Emotion, and globalCss accepts at-rules around whole selector maps.

1const example = (
2  <Box
3    _media={{ '(min-width: 500px)': { p: 2 } }}
4    selectors={{ '@media print': { display: 'none' } }}
5  />
6)
7
8globalCss({
9  _motionReduce: { '*, *::before, *::after': { transition: 'none' } },
10})
1const example = (
2  <Box
3    _media={{ '(min-width: 500px)': { p: 2 } }}
4    selectors={{ '@media print': { display: 'none' } }}
5  />
6)
7
8globalCss({
9  _motionReduce: { '*, *::before, *::after': { transition: 'none' } },
10})

Conditions always win over breakpoint values: at-rule styles come after every responsive rule. Among themselves they are ordered by condition, with width queries mobile-first (min-width ascending, then max-width descending), then media types, other features, and user preferences such as prefers-* last.