Accessibility
Comprehensive keyboard navigation, native ARIA semantics, and systemic respect for prefers-reduced-motion across all components.
Accessibility Requirements and Guarantees
- Keyboard Navigation & Focus Management: All interactive components are accessible and operable via keyboard following the logical DOM order, without focus traps. The focus ring is guaranteed. Upon closing a floating component (menu, drawer, dialog), focus is restored to its trigger element, and the Escape key consistently dismisses overlay views.
- WAI-ARIA Semantics & Dynamic Announcements: Each component implements the appropriate ARIA pattern for its role, reflecting its dynamic states and structural relationships between sub-elements. Screen reader announcements prioritize function and behavior over visual appearance. Contextual updates are broadcast to assistive technologies via ARIA live regions.
- Compile-time Constraints for Accessible Names: Visual controls relying solely on icons mandate an accessible name via their props. Omitting this label results in a compile-time typing error rather than a silent failure at runtime.
- Contrast Ratios & State Tokens: Text contrast adheres to the minimum WCAG AA threshold in both light and dark themes. Disabled states are managed through dedicated color tokens rather than reduced opacity, preserving their legibility regardless of the underlying surface.
Nearly half of the design system's behavioral JavaScript logic is dedicated exclusively to accessibility mechanisms (focus management, ARIA attributes, keyboard trapping). Components are designed with an accessibility-first paradigm: accessibility serves as the foundation before any interactive layer is added. Finally, the codebase is explicitly tagged so this proportion can be factually measured and audited, guaranteeing a quantifiable commitment rather than mere intent.
Focus
The focus indicator is materialized as a 2px outline with a 2px offset, drawn outside the element's box (outline). This out-of-flow rendering guarantees zero reflow cost (no layout shift). When the parent component clips its content (overflow: hidden), the indicator is automatically inset (notably for action buttons nested within inputs, accordion summaries, or animated tree branches). Indeed, an outline projected outside a container with a clipping mask is truncated and becomes invisible.
Validation
Error management relies on the native :user-invalid pseudo-class rather than :invalid. Visual error feedback is only triggered once input is interrupted and the field loses focus (blur), preventing partial inputs (e.g., a half-typed email address) from being prematurely marked as invalid. For business rules that can only be validated by the server, the invalid prop allows programmatically forcing the component's error state.
Motion
When the prefers-reduced-motion system preference is active, state transitions are removed (transition: none), while looping animations are slowed down instead of being stopped. A loading spinner, for example, has its cycle extended from 1s to 3s. Maintaining this minimal motion prevents display ambiguity: a completely frozen status component is perceived by users as an application crash.
Forced Colors
Vectis UI incorporates two architectural choices specifically designed for Windows Forced Colors Mode (High Contrast):
- Icon Rendering: Icons are exclusively integrated as
<svg>tags usingfill="currentColor". The use of CSS background masks (mask-image) is prohibited, as they are completely hidden by the system in forced colors mode. - Dividers and Separators: Dividers are implemented using genuine CSS borders (
border) rather than thin containers with a background color (background-color). The system resets backgrounds to the Canvas system color (identical to the page background, rendering the component invisible), whereas borders fallback toCanvasText, ensuring their visibility.