Overview
Source: ./src/documentation/development/interactive-elements-and-shadow-dom.mdx
Interactive elements and Shadow DOM
OTTO Components has transitioned from managing interactive elements within Shadow DOM to using a slot-based architecture. This architectural change addresses accessibility issues, reduces complexity, and provides teams with the full power of native HTML elements.
Skip to:
- The problem with Shadow DOM
- The solution
- Benefits of the slot-based approach
- The aria-label="auto" pattern
The problem with Shadow DOM
Managing interactive elements (buttons, inputs, links, checkboxes, radio buttons) within Shadow DOM created significant challenges for both component maintainers and consuming teams.
Accessibility limitations
Interactive elements encapsulated within Shadow DOM experienced several accessibility issues:
- Limited support for ARIA attributes across the Shadow DOM boundary
- Screen readers and assistive technologies had difficulty accessing properly connected labels and descriptions
- Complex ARIA relationships (such as
aria-labelledby,aria-describedby,aria-controls) required proxying across boundaries - Password managers and browser autofill features could not detect form inputs hidden in Shadow DOM
Increased implementation complexity
Components using Shadow DOM required substantial additional code:
- Form handling: Manual FormData integration, validation proxying, and custom validity management
- Single selection coordination: Custom logic for radio button groups and select emulation
- Focus management: Proxying focus and keyboard events across the Shadow DOM boundary
- Event handling: Managing event propagation and delegation across component boundaries
Testing difficulties
Teams testing components with Shadow DOM faced additional challenges:
- Required Shadow DOM-specific APIs to access interactive elements
- Standard DOM testing utilities could not query elements within shadow roots
- Testing tools needed special configuration to traverse shadow boundaries
The solution
OTTO Components adopted a slot-based architecture where teams provide their own interactive HTML elements within component slots. Components orchestrate these slotted elements rather than managing internal interactive elements within Shadow DOM.
This approach shifts responsibility for providing interactive elements to consuming teams while the component handles visual styling, layout, and coordinated behavior.
Benefits of the slot-based approach
Full power of native HTML
Teams gain direct access to all native HTML element features:
- Complete ARIA attribute support without proxying
- All form element attributes (
autocomplete,pattern,minlength,maxlength) - Native browser features (password managers, autofill, validation)
- Full control over element behavior and attributes
Improved accessibility
Accessibility compliance becomes straightforward:
- Screen readers and assistive technologies have direct access to form elements
- Label-input connections work natively through
forandidattributes - Complex ARIA relationships are supported without custom logic
- Static accessibility analysis tools correctly identify accessible patterns
Reduced component complexity
Component implementation simplifies significantly:
- No custom form handling code needed
- No radio button group coordination required
- No focus and keyboard event proxying
- Native browser features handle form behavior automatically
Better developer experience
Teams working with components benefit from:
- Easier testing using standard DOM APIs
- Ability to use existing CSS utilities on slotted elements
- Familiar HTML patterns instead of component-specific APIs
- Greater flexibility to customize element behavior
The aria-label="auto" pattern
To balance developer experience with accessibility requirements, OTTO Components introduced the aria-label="auto" pattern.
This pattern provides automatic accessibility attribute management while passing static analysis tools.
How aria-label="auto" works
When teams add aria-label="auto" to a slotted interactive element, the component automatically:
- Generates and applies appropriate accessibility attributes (
aria-labelledby,aria-describedby) - Connects form inputs with their labels using generated IDs
- Maintains these connections even when slotted content changes through mutation observation
Overriding automatic behavior
Teams can override automatic attribute management by:
- Providing their own
aria-labelvalue (without"auto") - Setting specific
aria-labelledbyoraria-describedbyattributes directly - Using explicit
idandforattributes for label connections
Why this approach works
The aria-label="auto" pattern provides several advantages:
- Explicit opt-in: The automation is visible in the markup, making developer intent clear
- Static analysis compatibility: Accessibility linting tools recognize the attribute and do not flag false positives
- Full control when needed: Teams can completely bypass automation by setting their own attributes
- Clear upgrade path: Existing code continues working while teams adopt the new pattern incrementally