Skip to main content

State styling

Tosui's Box component supports state props for styling hover, focus, active, and disabled states.

State props​

Box accepts four state props that override base styles:

PropTriggered By
_hoverMouse hover
_focusElement focus
_activeActive state
_disabledDisabled state
import { Box } from "@tosui/react";

<Box
bg="surface"
p={4}
cursor="pointer"
_hover={{ bg: "primary-subtle" }}
>
Hover to highlight
</Box>

Combining states​

Apply multiple state styles to a single element:

<Box
bg="surface"
p={4}
cursor="pointer"
_hover={{ bg: "primary-subtle" }}
_active={{ bg: "primary-default" }}
>
Click me
</Box>

When multiple states apply at the same time, later states take precedence for conflicting properties.

Supported properties by state​

Most style properties support all four states. Grid properties currently support _hover only.

Category_hover_focus_active_disabled
Colors (color, bg, borderColor)YesYesYesYes
Spacing (p, m, etc.)YesYesYesYes
Sizing (w, h, etc.)YesYesYesYes
Layout (display, position, etc.)YesYesYesYes
Typography (fontSize, fontWeight, etc.)YesYesYesYes
OpacityYesYesYesYes
ShadowYesYesYesYes
Interactions (cursor, pointerEvents, userSelect)YesYesYesYes
Borders (border, borderX, borderY, etc.)YesYesYesYes
Roundness (rounded, roundedTop, etc.)YesYesYesYes
FlexboxYesYesYesYes
GridYesNoNoNo
Text (textAlign, whiteSpace)YesYesYesYes

Disabled state​

Use _disabled to style elements when disabled:

<Box
as="button"
p={4}
bg="primary-default"
color="foreground-inverted"
cursor="pointer"
disabled
_hover={{ bg: "primary-emphasis" }}
_disabled={{
opacity: "faint",
cursor: "not-allowed",
bg: "surface"
}}
>
Submit
</Box>

The _disabled styles apply when the element has the disabled attribute or aria-disabled="true".

Responsive state styling​

State props support responsive values:

<Box
bg="surface"
p={4}
_hover={{
bg: { base: "primary-subtle", md: "primary-default" },
p: { base: 4, md: 6 }
}}
>
Different hover effect by screen size
</Box>

See the Responsive guide for more on breakpoints.

Built-in component states​

Interactive components such as Button and Input include state styles:

// Button handles hover, active, focus, and disabled automatically
<Button>Click me</Button>
<Button disabled>Can't click</Button>

// Input handles focus and disabled automatically
<Input placeholder="Type here" />
<Input disabled placeholder="Disabled" />

Button states​

Button applies these states automatically based on variant and colorScheme:

  • Hover: Slightly darker/lighter background
  • Active: Further emphasis
  • Focus: Focus ring for accessibility
  • Disabled: Reduced opacity, not-allowed cursor

Input states​

Input applies these states automatically:

  • Focus: Border color change, focus ring
  • Disabled: Reduced opacity, different background

When to use state props​

Use state props for:

  • Custom interactive elements built with Box
  • Hover effects on cards or list items
  • Custom buttons not using the Button component

Do not use state props for:

  • Standard Button, Input, Link (already styled)
  • Non-interactive content
  • Complex hover effects (use CSS modules instead)

Examples​

Hoverable card​

<Box
as="article"
p={6}
bg="surface"
rounded="md"
shadow="sm"
cursor="pointer"
_hover={{ shadow: "md", bg: "primary-subtle" }}
>
<Heading size="lg">Card Title</Heading>
<Text color="foreground-muted">Card description</Text>
</Box>

Interactive list item​

<Box
p={3}
cursor="pointer"
_hover={{ bg: "surface" }}
_active={{ bg: "primary-subtle" }}
>
List item content
</Box>

Custom button​

<Box
as="button"
px={4}
py={2}
bg="primary-default"
color="foreground-inverted"
rounded="md"
cursor="pointer"
_hover={{ bg: "primary-emphasis" }}
_active={{ bg: "primary-emphasis", opacity: "semi" }}
_disabled={{ opacity: "faint", cursor: "not-allowed" }}
>
Custom Button
</Box>

Focus ring​

<Box
as="button"
p={4}
bg="surface"
rounded="md"
cursor="pointer"
_focus={{ shadow: "md", borderColor: "primary" }}
border="thin"
borderColor="border"
>
Focusable element
</Box>

CSS pseudo-classes​

For more complex state styling, use CSS modules with standard pseudo-classes:

/* custom.module.css */
.customButton {
transition: all 0.15s ease;
}

.customButton:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.customButton:active {
transform: translateY(0);
}

.customButton:focus-visible {
outline: 2px solid var(--t-color-primary-default);
outline-offset: 2px;
}
import styles from "./custom.module.css";

<Box className={styles.customButton} p={4} bg="surface" rounded="md">
Fancy button
</Box>

Use CSS modules for:

  • Transitions and animations
  • Transform effects
  • Focus rings with outline
  • Complex multi-property changes