How do you ensure accessibility when writing semantic HTML and CSS?
answer
I ensure accessibility by using semantic HTML elements, correct heading hierarchy, and ARIA attributes for interactive components. Focus order is logical, visible focus indicators are present, and color contrast meets WCAG standards. Keyboard navigation, skip links, and screen reader announcements are implemented. CSS avoids purely visual cues; dynamic content uses aria-live. Forms have labels and validation messages associated programmatically. Testing includes screen readers, keyboard-only navigation, and automated audits.
Long Answer
Building accessible HTML and CSS requires a combination of semantic markup, ARIA attributes, focus management, and adherence to WCAG 2.1 standards. The goal is to make interactive components perceivable, operable, understandable, and robust for all users.
1) Semantic HTML
I prioritize native HTML elements: <button>, <a>, <input>, <nav>, <header>, <main>, <section>. Proper headings (<h1>–<h6>) create a logical document structure. Semantic markup reduces reliance on ARIA and ensures assistive technologies can interpret the page correctly.
2) ARIA roles and states
When semantics are insufficient (custom dropdowns, tabs, modals), I apply ARIA roles (role="dialog", role="tablist"), states (aria-expanded, aria-selected), and properties (aria-labelledby, aria-describedby) to convey purpose and state changes. Dynamic updates use aria-live="polite" or assertive as appropriate.
3) Keyboard navigation
All interactive components must be keyboard operable. I use logical tabindex ordering, ensure focusable elements are reachable, and provide Escape or arrow key support for custom widgets. Skip links allow bypassing repetitive content. Focus management for modals or dialogs ensures focus is trapped and returned on close.
4) Visual cues and focus indicators
Focus outlines are visible and distinguishable. CSS avoids relying solely on color; text, icons, or borders supplement visual cues. Contrast ratios meet WCAG AA for text and AAA for critical content. Hover and focus states are clearly defined.
5) Form accessibility
All inputs have <label> associations (for attribute or wrapping). Validation errors are conveyed programmatically (aria-invalid, aria-describedby). Instructions are clear, and optional/required fields are communicated. Input masking and live validation messages do not rely solely on color.
6) Dynamic content updates
Single-page applications or interactive widgets update DOM dynamically. I announce changes using aria-live, focus shifting, or role alerts. Animations respect prefers-reduced-motion. CSS transitions and animations do not convey essential information without textual or programmatic alternatives.
7) Color, contrast, and typography
Colors meet minimum contrast ratios (4.5:1 for normal text, 3:1 for large text). Avoid color-only cues for errors or status. Text sizes are scalable; rem/em units support zoom. High-contrast mode is considered, and decorative images use empty alt="".
8) Testing and validation
Automated tools (axe-core, Lighthouse, WAVE) audit accessibility. Manual testing includes keyboard-only navigation, screen readers (NVDA, VoiceOver), and mobile accessibility features. Focus order, announcements, and ARIA attributes are verified. Edge cases with dynamic content and modals are tested thoroughly.
9) Robust CSS practices
CSS is modular, avoids absolute positioning that breaks tab order, and respects pointer-events for interactive elements. Focus outlines are preserved; visually hidden elements use sr-only patterns for screen readers. Flexbox, grid, and media queries maintain layout without sacrificing accessibility.
10) Documentation and component design
Accessible components are documented with usage guidance, required ARIA attributes, keyboard interactions, and focus behavior. Designers and developers receive specifications to maintain accessibility during implementation.
By combining semantic HTML, ARIA roles, keyboard operability, proper color contrast, focus management, dynamic content announcements, and rigorous testing, interactive components remain fully WCAG-compliant, providing a usable experience for all users.
Table
Common Mistakes
Using <div>s or <span>s for interactive elements without roles or keyboard support. Neglecting focus outlines or using color-only indicators. Missing label associations or proper aria-describedby in forms. Overlooking dynamic content announcements or modals focus management. Ignoring prefers-reduced-motion. Relying solely on automated tools without manual testing. Using absolute positioning that breaks tab order. Insufficient color contrast or small touch targets. Not documenting accessibility requirements for reusable components.
Sample Answers
Junior:
“I use semantic HTML elements for buttons, links, and forms. Focus outlines are visible and logical, and color is not the only cue. Labels are associated with inputs, and dynamic content uses aria-live for screen readers. I test manually with keyboard navigation.”
Mid-level:
“I enforce semantic markup and ARIA roles where necessary. Components are keyboard operable with logical tab order, focus traps for modals, and skip links. Color contrast meets WCAG AA, and dynamic updates are announced with aria-live. Forms validate programmatically and errors are linked to inputs. I combine automated and manual testing.”
Senior:
“I design interactive components with semantic HTML and proper heading hierarchy. Custom widgets use ARIA roles, states, and aria-live for dynamic updates. Keyboard navigation is fully operable, including focus management for modals and menus. Visual cues meet WCAG contrast, animations respect prefers-reduced-motion, and forms are fully labeled and validated. I perform automated audits (axe-core, Lighthouse) and screen reader testing. Components are documented to ensure accessibility consistency.”
Evaluation Criteria
Look for use of semantic HTML as primary structure, ARIA roles for custom widgets, and proper heading hierarchy. Strong answers include keyboard operability, visible focus, skip links, color contrast, dynamic content announcements, accessible forms, and robust CSS practices. Testing with automated tools plus manual screen reader and keyboard testing is expected. Red flags: interactive <div>s without roles, missing labels, no focus management, color-only cues, ignoring dynamic updates, or lack of testing and documentation.
Preparation Tips
- Use semantic HTML: <button>, <a>, <input>, <nav>, <main>.
- Apply ARIA roles, states, and properties for custom components.
- Ensure full keyboard navigation: tab order, focus trap, skip links.
- Provide visible focus indicators and sufficient color contrast.
- Label all form controls; associate error messages programmatically.
- Announce dynamic content with aria-live and manage modal focus.
- Respect prefers-reduced-motion and scalable typography.
- Test with screen readers (NVDA, VoiceOver), keyboard-only navigation, and automated audits (axe-core, Lighthouse).
- Use modular CSS that preserves focus and layout.
- Document accessibility requirements for all components and patterns.
Real-world Context
A web app redesign applied semantic HTML for navigation, buttons, and forms. Custom modals and tabs used ARIA roles and focus traps. RxJS-driven dynamic content was announced via aria-live. Focus indicators were visible, color contrast exceeded 4.5:1, and touch targets met minimum sizes. Forms had <label> associations and programmatic error messages. Automated audits with axe-core and manual screen reader testing identified remaining gaps, which were resolved before release. Component documentation ensured consistent accessibility in future development. The result: fully WCAG-compliant interactive components usable for keyboard and screen reader users.
Key Takeaways
- Use semantic HTML as the foundation for accessibility.
- Apply ARIA roles, states, and aria-live for custom interactive components.
- Ensure keyboard operability, focus management, and skip links.
- Maintain sufficient color contrast and visible focus cues.
- Associate all form fields with labels and validation messages programmatically.
- Handle dynamic content and animations responsibly.
- Test with screen readers, keyboard navigation, and automated tools.
- Write modular, robust CSS that preserves layout and focus.
- Document accessibility patterns for consistency across the codebase.
Practice Exercise
Scenario:
You are building a component library for an interactive web application. Components include modals, dropdown menus, tabs, buttons, and form elements. They must comply with WCAG 2.1 standards for accessibility.
Tasks:
- Use semantic HTML for each component; provide headings, lists, and form elements appropriately.
- Apply ARIA roles, states, and properties for custom widgets (modals, tabs, dropdowns).
- Implement keyboard navigation: logical tab order, focus traps in modals, and skip links for repetitive content.
- Ensure visible focus indicators and minimum 4.5:1 contrast ratios.
- Label all form fields programmatically; associate validation messages using aria-describedby.
- Announce dynamic content updates using aria-live regions.
- Respect prefers-reduced-motion and scalable typography units.
- Test components with screen readers (NVDA/VoiceOver), keyboard-only navigation, and automated audits (axe-core, Lighthouse).
- Clean up CSS to preserve layout and focus states; avoid relying solely on color cues.
- Document accessibility patterns, keyboard interactions, and ARIA requirements for each component.
Deliverable:
A WCAG-compliant component library in HTML/CSS that supports keyboard and screen reader users, ensures focus and contrast visibility, manages dynamic content accessibly, and includes documentation for consistent accessibility practices across future development.

