Modifiers

ARIA State

Create ARIA state modifiers for styling elements based on their ARIA attribute values with full type safety.

Overview

ARIA state modifiers let you apply utility styles conditionally based on ARIA attribute values. They wrap utility declarations in attribute selectors like [aria-expanded="true"], generating variant utility classes that respond to accessibility state changes.

Why Use ARIA State Modifiers?

ARIA state modifiers help you:

  • Style accessible components: Apply styles based on ARIA attributes used by screen readers
  • Avoid JavaScript class toggling: Let ARIA attributes drive both accessibility and visual presentation
  • Build inclusive UIs: Keep visual state in sync with the accessibility tree
  • Follow WAI-ARIA patterns: Style disclosure widgets, tabs, accordions, and more using standard ARIA attributes

useAriaBusyModifier

The useAriaBusyModifier() function creates a modifier that applies styles when aria-busy="true".

CSS Selector

Modifier NameCSS Selector
aria-busy&[aria-busy="true"]

useAriaCheckedModifier

The useAriaCheckedModifier() function creates a modifier that applies styles when aria-checked="true".

CSS Selector

Modifier NameCSS Selector
aria-checked&[aria-checked="true"]

useAriaDisabledModifier

The useAriaDisabledModifier() function creates a modifier that applies styles when aria-disabled="true".

styleframe.config.ts
import { styleframe } from "styleframe";
import { useOpacityUtility, useCursorUtility } from "@styleframe/theme";
import { useAriaDisabledModifier } from "@styleframe/theme";

const s = styleframe();

const ariaDisabled = useAriaDisabledModifier(s);

useOpacityUtility(s, { 50: '0.5' }, [ariaDisabled]);
useCursorUtility(s, { 'not-allowed': 'not-allowed' }, [ariaDisabled]);

export default s;

CSS Selector

Modifier NameCSS Selector
aria-disabled&[aria-disabled="true"]

useAriaExpandedModifier

The useAriaExpandedModifier() function creates a modifier that applies styles when aria-expanded="true".

styleframe.config.ts
import { styleframe } from "styleframe";
import { useDisplayUtility, useRotateUtility } from "@styleframe/theme";
import { useAriaExpandedModifier } from "@styleframe/theme";

const s = styleframe();

const ariaExpanded = useAriaExpandedModifier(s);

useDisplayUtility(s, {
    block: 'block',
    none: 'none',
}, [ariaExpanded]);

useRotateUtility(s, {
    180: '180deg',
}, [ariaExpanded]);

export default s;

CSS Selector

Modifier NameCSS Selector
aria-expanded&[aria-expanded="true"]

useAriaHiddenModifier

The useAriaHiddenModifier() function creates a modifier that applies styles when aria-hidden="true".

CSS Selector

Modifier NameCSS Selector
aria-hidden&[aria-hidden="true"]

useAriaPressedModifier

The useAriaPressedModifier() function creates a modifier that applies styles when aria-pressed="true".

styleframe.config.ts
import { styleframe } from "styleframe";
import { useColor } from "@styleframe/theme";
import { useBackgroundColorUtility } from "@styleframe/theme";
import { useAriaPressedModifier } from "@styleframe/theme";

const s = styleframe();
const { ref } = s;

const { colorPrimary } = useColor(s, { primary: '#006cff' } as const);

const ariaPressed = useAriaPressedModifier(s);

useBackgroundColorUtility(s, {
    primary: ref(colorPrimary),
    muted: '#e9ecef',
}, [ariaPressed]);

export default s;

CSS Selector

Modifier NameCSS Selector
aria-pressed&[aria-pressed="true"]

useAriaReadonlyModifier

The useAriaReadonlyModifier() function creates a modifier that applies styles when aria-readonly="true".

CSS Selector

Modifier NameCSS Selector
aria-readonly&[aria-readonly="true"]

useAriaRequiredModifier

The useAriaRequiredModifier() function creates a modifier that applies styles when aria-required="true".

CSS Selector

Modifier NameCSS Selector
aria-required&[aria-required="true"]

useAriaSelectedModifier

The useAriaSelectedModifier() function creates a modifier that applies styles when aria-selected="true".

styleframe.config.ts
import { styleframe } from "styleframe";
import { useColor } from "@styleframe/theme";
import { useBackgroundColorUtility, useBorderColorUtility } from "@styleframe/theme";
import { useAriaSelectedModifier } from "@styleframe/theme";

const s = styleframe();
const { ref } = s;

const { colorPrimary } = useColor(s, { primary: '#006cff' } as const);

const ariaSelected = useAriaSelectedModifier(s);

useBackgroundColorUtility(s, {
    primary: ref(colorPrimary),
    white: '#ffffff',
}, [ariaSelected]);

useBorderColorUtility(s, {
    primary: ref(colorPrimary),
}, [ariaSelected]);

export default s;

CSS Selector

Modifier NameCSS Selector
aria-selected&[aria-selected="true"]

useAriaStateModifiers

The useAriaStateModifiers() function registers all ARIA state modifiers at once and returns them as a destructurable object.

Returned Modifiers

KeyModifier NameCSS Selector
ariaBusyaria-busy&[aria-busy="true"]
ariaCheckedaria-checked&[aria-checked="true"]
ariaDisabledaria-disabled&[aria-disabled="true"]
ariaExpandedaria-expanded&[aria-expanded="true"]
ariaHiddenaria-hidden&[aria-hidden="true"]
ariaPressedaria-pressed&[aria-pressed="true"]
ariaReadonlyaria-readonly&[aria-readonly="true"]
ariaRequiredaria-required&[aria-required="true"]
ariaSelectedaria-selected&[aria-selected="true"]

Examples

Accessible Accordion

styleframe.config.ts
import { styleframe } from "styleframe";
import { useDisplayUtility, useRotateUtility, useOpacityUtility } from "@styleframe/theme";
import { useAriaStateModifiers } from "@styleframe/theme";

const s = styleframe();

const { ariaExpanded, ariaHidden } = useAriaStateModifiers(s);

useDisplayUtility(s, {
    block: 'block',
    none: 'none',
}, [ariaExpanded, ariaHidden]);

useRotateUtility(s, {
    180: '180deg',
}, [ariaExpanded]);

export default s;

Tab Panel with Selected State

styleframe.config.ts
import { styleframe } from "styleframe";
import { useColor } from "@styleframe/theme";
import {
    useBackgroundColorUtility,
    useTextColorUtility,
    useBorderColorUtility,
} from "@styleframe/theme";
import { useAriaSelectedModifier } from "@styleframe/theme";

const s = styleframe();
const { ref } = s;

const { colorPrimary } = useColor(s, { primary: '#006cff' } as const);

const ariaSelected = useAriaSelectedModifier(s);

useBackgroundColorUtility(s, {
    primary: ref(colorPrimary),
    transparent: 'transparent',
}, [ariaSelected]);

useTextColorUtility(s, {
    white: '#ffffff',
    dark: '#212529',
}, [ariaSelected]);

useBorderColorUtility(s, {
    primary: ref(colorPrimary),
    transparent: 'transparent',
}, [ariaSelected]);

export default s;

Best Practices

  • Use ARIA modifiers for custom components: Native form elements have built-in pseudo-classes; use ARIA modifiers for custom widgets
  • Keep ARIA attributes in sync: Ensure JavaScript updates ARIA attributes so styles reflect the current state
  • Prefer semantic HTML: When possible, use native elements (like <details>) that have built-in ARIA support
  • Test with screen readers: Verify that ARIA attributes are correctly announced alongside the visual changes
  • Use aria-expanded for disclosure widgets: Accordions, dropdowns, and menus should use aria-expanded for both accessibility and styling

FAQ