apps/www/content/docs/styling/conditional-styles.mdx
Chakra allows you to write styles for pseudo states, media queries, and custom data attributes with the conditional style props.
:::note
See the list of built-in conditions below.
:::
For example, here's how to change the background color of a button when it's hovered:
<Box bg="red.500" _hover={{ bg: "red.700" }}>
Hover me
</Box>
Conditional values can be nested to create complex selector rules.
Here's how to change the background color of an element when in focus on hover:
<Box bg={{ base: "red.500", _hover: { _focus: "red.700" } }}>
Hover & Focus me
</Box>
This also works with the supported at-rules (@media, @layer, @container,
@supports, and @page):
<Box
css={{
"@container (min-width: 10px)": {
color: "green.300",
},
}}
>
Hello
</Box>
Here's an example of how to style the hover, active, focus, and disabled states of an element
<chakra.button
_hover={{ bg: "red.700" }}
_active={{ bg: "red.900" }}
_focus={{ bg: "red.800" }}
_disabled={{ opacity: "0.5" }}
>
Hover me > Hover me
</chakra.button>
Here's an example of how to style the first, last, odd, and even elements in a list
<Box as="ul">
{items.map((item) => (
<Box
as="li"
key={item}
_first={{ color: "red.500" }}
_last={{ color: "red.800" }}
>
{item}
</Box>
))}
</Box>
You can also style even and odd elements using the _even and _odd modifier
<table>
<tbody>
{items.map((item) => (
<chakra.tr key={item} _even={{ bg: "gray.100" }} _odd={{ bg: "white" }}>
<td>{item}</td>
</chakra.tr>
))}
</tbody>
</table>
To style the ::before and ::after pseudo elements of an element, use the
_before and _after modifiers
<Box _before={{ content: '"👋"' }} _after={{ content: '"🥂"' }}>
Hello
</Box>
To style the placeholder text of any input or textarea, use the _placeholder
modifier:
<chakra.input
placeholder="Enter your name"
_placeholder={{ color: "gray.500" }}
/>
To style the file input button, use the _file modifier:
<chakra.input
type="file"
_file={{ bg: "gray.500", px: "4", py: "2", marginEnd: "3" }}
/>
Use the _motionReduce and _motionSafe modifiers to style an element based on
the user's motion preference:
<Box _motionSafe={{ transition: "all 0.3s" }}>Hello</Box>
The prefers-color-scheme media feature is used to detect if the user has
requested the system to use a light or dark color theme.
Use the _osLight and _osDark modifiers to style an element based on the
user's color scheme preference:
<chakra.div bg={{ base: "white", _osDark: "black" }}>Hello</chakra.div>
The prefers-contrast media feature is used to detect if the user has requested
the system use a high or low contrast theme.
Use the _highContrast and _lessContrast modifiers to style an element based
on the user's color contrast preference:
<Box bg={{ base: "white", _highContrast: "black" }}>Hello</Box>
The orientation media feature is used to detect if the user has a device in
portrait or landscape mode.
Use the _portrait and _landscape modifiers to style an element based on the
user's device orientation:
<Box pb="4" _portrait={{ pb: "8" }}>
Hello
</Box>
For arbitrary, use the css prop to write styles for one-off selectors:
<Box css={{ "&[data-state=closed]": { color: "red.300" } }} />
Here's another example that targets the child elements of a parent element:
<Box
css={{
"& > *": { margin: "2" },
}}
/>
To style an element based on its parent element's state or attribute, add the
group class to the parent element, and use any of the _group* modifiers on
the child element.
<div className="group">
<Text _groupHover={{ bg: "red.500" }}>Hover me</Text>
</div>
This modifier works for every pseudo class modifiers like _groupHover,
_groupActive, _groupFocus, and _groupDisabled, etc.
To style an element based on its sibling element's state or attribute, add the
peer class to the sibling element, and use any of the _peer* modifiers on
the target element.
<div>
<p className="peer">Hover me</p>
<Box _peerHover={{ bg: "red.500" }}>I'll change by bg</Box>
</div>
Note: This only works for when the element marked with
peeris a previous siblings, that is, it comes before the element you want to start.
To style an element based on the direction of the text, use the _ltr and
_rtl modifiers
<div dir="ltr">
<Box _ltr={{ ml: "3" }} _rtl={{ mr: "3" }}>
Hello
</Box>
</div>
To style an element based on its data-{state} attribute, use the corresponding
_{state} modifier
<Box data-loading _loading={{ bg: "gray.500" }}>
Hello
</Box>
This works for common states like data-active, data-disabled, data-focus,
data-hover, data-invalid, data-required, and data-valid.
<Box data-active _active={{ bg: "gray.500" }}>
Hello
</Box>
To style an element based on its data-orientation attribute, use the
_horizontal and _vertical modifiers
<Box
data-orientation="horizontal"
_horizontal={{ bg: "red.500" }}
_vertical={{ bg: "blue.500" }}
>
Hello
</Box>
To style an element based on its aria-{state}=true attribute, use the
corresponding _{state} prop
<Box aria-expanded="true" _expanded={{ bg: "gray.500" }}>
Hello
</Box>
Here's a list of all the condition props you can use in Chakra:
<ConditionalStylesReferenceDoc />Chakra lets you create your own conditions, so you're not limited to the ones in the default preset. Learn more about customizing conditions here.