Community Wiki & Forum
Frontend Development
January 2024
42 active contributors
Build inclusive web experiences for everyone
Use semantic HTML elements to provide meaning and structure to your content for screen readers and assistive technologies.
<!-- Bad: Non-semantic -->
<div class="header">
<div class="nav">
<div class="nav-item">Home</div>
</div>
</div>
<!-- Good: Semantic -->
<header>
<nav>
<a href="/">Home</a>
</nav>
</header>
<main>
<article>
<h1>Article Title</h1>
<p>Article content...</p>
</article>
</main>
<footer>
<p>© 2025 Site Name</p>
</footer>Use ARIA attributes to enhance accessibility when semantic HTML isn't enough.
<!-- Button with ARIA label -->
<button aria-label="Close dialog" onClick={closeDialog}>
<X className="icon" aria-hidden="true" />
</button>
<!-- Custom dropdown -->
<div role="listbox" aria-label="Select option">
<div role="option" aria-selected="true">Option 1</div>
<div role="option" aria-selected="false">Option 2</div>
</div>
<!-- Loading state -->
<div aria-live="polite" aria-busy="true">
Loading content...
</div>
<!-- Form with error -->
<input
type="email"
aria-label="Email address"
aria-invalid="true"
aria-describedby="email-error"
/>
<span id="email-error" role="alert">
Please enter a valid email
</span>Ensure all interactive elements are keyboard accessible and have visible focus states.
/* Visible focus indicators */
button:focus-visible,
a:focus-visible {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
/* Skip to main content link */
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: var(--primary);
color: white;
padding: 8px;
text-decoration: none;
}
.skip-link:focus {
top: 0;
}
/* Keyboard trap for modals */
function Modal({ onClose, children }) {
const modalRef = useRef(null);
useEffect(() => {
const focusableElements = modalRef.current.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const firstElement = focusableElements[0];
const lastElement = focusableElements[focusableElements.length - 1];
firstElement?.focus();
const trapFocus = (e) => {
if (e.key === 'Tab') {
if (e.shiftKey && document.activeElement === firstElement) {
lastElement?.focus();
e.preventDefault();
} else if (!e.shiftKey && document.activeElement === lastElement) {
firstElement?.focus();
e.preventDefault();
}
}
};
document.addEventListener('keydown', trapFocus);
return () => document.removeEventListener('keydown', trapFocus);
}, []);
return <div ref={modalRef} role="dialog">{children}</div>;
}No comments yet. Be the first to join the discussion!