Selector
The attributes defined in Pseudo-Class correspond to those defined in Selector, allowing them to be used directly as component props.
| Selector | Pseudo-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
hoverorfocusVisible, is that pseudo-class of the element; a name that selects nothing, such asdiv, 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.
| Selector | Media Query |
|---|---|
_print | print |
_screen | screen |
_all | all |
_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.