accessibility

Accessibility utilities for Tailwind CSS

Forced Color Adjust Utilities

Tailwind CSS provides utilities for opting in and out of forced colors. These are particularly useful for Windows High Contrast Mode.


ForcedColorAdjust


def ForcedColorAdjust(
    args:VAR_POSITIONAL, kwds:VAR_KEYWORD
):

Forced color utility values

Exported source
class ForcedColorAdjust(Enum):
    """Forced color utility values"""
    AUTO = "auto"
    NONE = "none"

# Create forced color adjust factory
forced_color_adjust = enums_to_simple_factory("forced-color-adjust", [ForcedColorAdjust], "Forced color adjust utilities for opting in and out of forced colors (e.g., Windows High Contrast Mode)") # The forced color adjust factory

test_accessibility_forced_color_adjust_examples


def test_accessibility_forced_color_adjust_examples(
    
):

Test forced color adjust utilities.

Exported source
def test_accessibility_forced_color_adjust_examples(
):
    """Test forced color adjust utilities."""
    # Test forced color adjust utilities with dot notation
    assert str(forced_color_adjust.auto) == "forced-color-adjust-auto"
    assert str(forced_color_adjust.none) == "forced-color-adjust-none"

# Run the tests
test_accessibility_forced_color_adjust_examples()

Screen Reader Utilities

Utilities for controlling visibility of elements for screen readers vs visual display.


test_accessibility_screen_reader_examples


def test_accessibility_screen_reader_examples(
    
):

Test screen reader utilities imported from layout module.

Exported source
# Screen reader utilities
sr_only = SingleValueFactory("sr-only", "Hide element visually but keep it available to screen readers")
not_sr_only = SingleValueFactory("not-sr-only", "Undo sr-only, making element visible again")
Exported source
def test_accessibility_screen_reader_examples(
):
    """Test screen reader utilities imported from layout module."""
    # Test screen reader utilities
    assert str(sr_only) == "sr-only"
    assert str(not_sr_only) == "not-sr-only"

# Run the tests
test_accessibility_screen_reader_examples()

Practical Examples

Let’s see how to use these accessibility utilities in real FastHTML components:


test_accessibility_fasthtml_examples


def test_accessibility_fasthtml_examples(
    
):

Test accessibility utilities in practical FastHTML component examples.

Exported source
def test_accessibility_fasthtml_examples(
):
    """Test accessibility utilities in practical FastHTML component examples."""
    from fasthtml.common import Div, Button, Span, Input, Label, Nav, A
    from cjm_fasthtml_tailwind.utilities.layout import position, top, left
    from cjm_fasthtml_tailwind.utilities.backgrounds import bg
    from cjm_fasthtml_tailwind.utilities.spacing import p
    from cjm_fasthtml_tailwind.utilities.borders import rounded, border, border_color
    from cjm_fasthtml_tailwind.utilities.sizing import w, h
    from cjm_fasthtml_tailwind.utilities.typography import font_size, text_color
    from cjm_fasthtml_tailwind.utilities.transitions_and_animation import animate
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import gap, items, grid_display, flex_display
    from cjm_fasthtml_tailwind.core.base import combine_classes
    
    # Skip link for keyboard navigation
    skip_link = A(
        "Skip to main content",
        href="#main-content",
        cls=combine_classes(
            sr_only,
            not_sr_only.focus,
            position.absolute.focus,
            top(4).focus,
            left(4).focus,
            bg.white,
            p(2),
            rounded.full
        )
    )
    assert "sr-only" in skip_link.attrs['class']
    assert "focus:not-sr-only" in skip_link.attrs['class']
    
    # Form with screen reader only label
    form_field = Div(
        Label("Search", cls=str(sr_only), for_="search"),
        Input(
            type="search",
            id="search",
            placeholder="Search...",
            cls=combine_classes(w.full, p.x(4), p.y(2), border._1, rounded.full)
        )
    )
    assert form_field.children[0].attrs['class'] == "sr-only"
    
    # Icon button with screen reader text
    icon_button = Button(
        # Icon would go here (e.g., SVG)
        Span("Close dialog", cls=str(sr_only)),
        cls=combine_classes(p(2), rounded.full, bg.gray._100.hover),
        aria_label="Close dialog"
    )
    assert icon_button.children[0].attrs['class'] == "sr-only"
    
    # Navigation with forced color adjustments
    high_contrast_nav = Nav(
        A("Home", href="/", cls=combine_classes(forced_color_adjust.none, text_color.blue._600)),
        A("About", href="/about", cls=combine_classes(forced_color_adjust.none, text_color.blue._600)),
        A("Contact", href="/contact", cls=combine_classes(forced_color_adjust.none, text_color.blue._600)),
        cls=combine_classes(forced_color_adjust.auto, flex_display, gap(4))
    )
    assert high_contrast_nav.attrs['class'] == "forced-color-adjust-auto flex gap-4"
    assert "forced-color-adjust-none" in high_contrast_nav.children[0].attrs['class']
    
    # Loading spinner with screen reader text
    loading_spinner = Div(
        Div(cls=combine_classes(
            animate.spin,
            h(5),
            w(5),
            border._2,
            border_color.gray._900,
            rounded.full,
            border_color.t.transparent
        )),
        Span("Loading...", cls=str(sr_only)),
        cls=combine_classes(flex_display.inline, items.center)
    )
    assert loading_spinner.children[1].attrs['class'] == "sr-only"
    
    # Return all examples in a grid layout
    return Div(
        skip_link,
        form_field,
        icon_button,
        high_contrast_nav,
        loading_spinner,
        cls=combine_classes(grid_display, gap(5))
    )

# Run the tests
test_accessibility_fasthtml_examples()
Skip to main content
Loading...
test_func = test_accessibility_fasthtml_examples
app, rt = create_test_app()

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

Helper Functions

Convenient functions for common accessibility patterns:


visually_hidden


def visually_hidden(
    focusable:bool=False, # Whether the element should be visible when focused
)->str: # CSS classes for hiding element visually

Hide an element visually but keep it available to screen readers.

Args: focusable: If True, element becomes visible when focused (useful for skip links)

Returns: CSS classes for visual hiding with optional focus visibility


high_contrast_safe


def high_contrast_safe(
    classes:str, # Additional CSS classes to combine
)->str: # CSS classes including forced color adjust

Create classes that work well with high contrast mode.

Args: *classes: Additional CSS classes to include

Returns: Combined CSS classes with forced-color-adjust-auto


test_accessibility_helper_examples


def test_accessibility_helper_examples(
    
):

Test helper functions for common accessibility patterns.

Exported source
def test_accessibility_helper_examples(
):
    """Test helper functions for common accessibility patterns."""
    # Test visually_hidden helper
    assert visually_hidden() == "sr-only"
    assert visually_hidden(focusable=True) == "sr-only focus:not-sr-only"
    
    # Test high_contrast_safe helper
    assert high_contrast_safe() == "forced-color-adjust-auto"
    assert high_contrast_safe("bg-blue-500", "text-white") == "forced-color-adjust-auto bg-blue-500 text-white"

# Run the tests
test_accessibility_helper_examples()

Export