Utilities

Accessibility

Create accessibility utilities for screen reader visibility and forced color adjustments with full type safety.

Overview

Accessibility utilities help you create inclusive web experiences by controlling visibility for screen readers and managing forced color adjustments for high contrast modes.

Why Use Accessibility Utilities?

Accessibility utilities help you:

  • Support assistive technologies: Hide content visually while keeping it accessible to screen readers
  • Honor user preferences: Respect forced color modes for users who need high contrast
  • Maintain semantic HTML: Keep content accessible without compromising visual design
  • Follow WCAG guidelines: Meet accessibility standards with proven utility patterns

useForcedColorAdjustUtility

The useForcedColorAdjustUtility() function creates utility classes for controlling how elements render in forced color modes (like Windows High Contrast Mode).

styleframe.config.ts
import { styleframe } from "styleframe";
import { useForcedColorAdjustUtility } from "@styleframe/theme";

const s = styleframe();

// Uses built-in defaults: auto, none
useForcedColorAdjustUtility(s);

export default s;

Default Values

The useForcedColorAdjustUtility includes these default values:

KeyValueDescription
autoautoAllow browser to adjust colors in forced color mode
nonenonePrevent color adjustments, preserving original colors
When to use none: Use forced-color-adjust: none sparingly on elements where color is essential for understanding (like data visualizations or status indicators).

useSrOnlyUtility

The useSrOnlyUtility() function creates a utility class that visually hides content while keeping it accessible to screen readers.

styleframe.config.ts
import { styleframe } from "styleframe";
import { useSrOnlyUtility } from "@styleframe/theme";

const s = styleframe();

// Creates sr-only class with default: true
useSrOnlyUtility(s);

export default s;

This pattern visually hides the element but keeps it in the accessibility tree so screen readers can announce it.

Pro tip: Use sr-only for icon-only buttons, skip links, form labels that are visually implied, and any content that provides context for assistive technology users.

useNotSrOnlyUtility

The useNotSrOnlyUtility() function creates a utility class that undoes the sr-only styles, making content visible again.

styleframe.config.ts
import { styleframe } from "styleframe";
import { useSrOnlyUtility, useNotSrOnlyUtility } from "@styleframe/theme";

const s = styleframe();

useSrOnlyUtility(s);
useNotSrOnlyUtility(s);

export default s;

This is useful when you want content to be screen-reader-only by default but visible on certain states (like focus).

Examples

A common accessibility pattern is a "skip to content" link that's only visible when focused:

styleframe.config.ts
import { styleframe } from "styleframe";
import { useSrOnlyUtility, useNotSrOnlyUtility } from "@styleframe/theme";
import { useColor } from "@styleframe/theme";

const s = styleframe();
const { ref, selector, modifier } = s;

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

// Create accessibility utilities
useSrOnlyUtility(s);
useNotSrOnlyUtility(s);

// Create focus modifier
const focus = modifier('focus', ({ declarations }) => ({
    '&:focus': declarations,
}));

// Apply not-sr-only on focus using a selector
selector('.skip-link', {
    position: 'absolute',
    width: '1px',
    height: '1px',
    padding: '0',
    margin: '-1px',
    overflow: 'hidden',
    clip: 'rect(0, 0, 0, 0)',
    whiteSpace: 'nowrap',
    borderWidth: '0',
    '&:focus': {
        position: 'fixed',
        top: '1rem',
        left: '1rem',
        width: 'auto',
        height: 'auto',
        padding: '1rem',
        margin: '0',
        overflow: 'visible',
        clip: 'auto',
        whiteSpace: 'normal',
        backgroundColor: ref(colorPrimary),
        color: 'white',
        zIndex: '9999',
    },
});

export default s;

Icon Button with Accessible Label

styleframe.config.ts
import { styleframe } from "styleframe";
import { useSrOnlyUtility } from "@styleframe/theme";

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

useSrOnlyUtility(s);

// Style for icon button
selector('.icon-button', {
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    padding: '0.5rem',
    border: 'none',
    borderRadius: '0.25rem',
    cursor: 'pointer',
});

export default s;

Usage in HTML:

<button class="icon-button">
    <svg aria-hidden="true" width="24" height="24">
        <path d="..." />
    </svg>
    <span class="_sr-only">Delete item</span>
</button>

Best Practices

  • Always provide text alternatives: Icon buttons, images, and decorative elements should have accessible text
  • Use sr-only for context: Add screen-reader-only text when visual context isn't available to assistive technology users
  • Test with screen readers: Verify your sr-only content is announced correctly
  • Be careful with forced-color-adjust: Only disable it when color is critical to understanding
  • Consider focus states: Make sr-only content visible on focus when appropriate (like skip links)
  • Don't use display: none: It removes content from the accessibility tree entirely

FAQ