Use semantic HTML elements (<nav>, <main>, <article>, <button>) instead of generic <div> and <span> with click handlers. Screen readers and assistive technology rely on semantic elements to understand page structure — a <div onClick> looks like nothing to a blind user.
Screen readers and assistive technologies parse the DOM for semantic meaning. A <div onClick> has no role, no keyboard behavior, and no accessible name — it is invisible to the 2.2 billion people worldwide with vision impairments who rely on assistive technology. Replacing semantic elements with generic containers breaks navigation landmarks, heading outlines, and form controls for every assistive technology user.
BeforeMerge scans your pull requests against this rule and 4+ others. Get actionable feedback before code ships.
HTML has built-in semantics that assistive technologies depend on. A <button> is focusable, activatable with Enter/Space, announced as "button" by screen readers, and included in the accessibility tree automatically. A <div onClick> has none of these properties.
When developers use <div> and <span> for interactive elements, they must manually recreate every behavior that semantic elements provide for free: focus management, keyboard activation, ARIA roles, and accessible names. In practice, at least one of these is always forgotten.
This is not an edge case. Screen reader users navigate by landmarks (<nav>, <main>, <aside>), headings (<h1>-<h6>), and form controls (<button>, <input>). If your page is built entirely from <div> elements, it is a flat, undifferentiated wall of text to a blind user.
Use the most specific semantic HTML element for every piece of content and interaction. Use <button> for actions, <a> for navigation, <nav> for navigation regions, <main> for primary content, <article> for self-contained content, and <section> for thematic groupings.
// Generic divs with click handlers — invisible to screen readers
<div className="nav">
<div className="nav-item" onClick={() => navigate("/home")}>Home</div>
<div className="nav-item" onClick={() => navigate("/about")}>About</div>
</div>
<div className="main-content">
<div className="card" onClick={() => openArticle(id)}>
<div className="card-title">Article Title</div>
<div className="card-body">Article excerpt...</div>
</div>
</div>// Semantic elements — accessible by default
<nav aria-label="Main navigation">
<a href="/home">Home</a>
<a href="/about">About</a>
</nav>
<main>
<article>
<h2>
<a href={`/articles/${id}`}>Article Title</a>
</h2>
<p>Article excerpt...</p>
</article>
</main>Search for <div or <span elements with click handlers:
grep -rn 'onClick' --include="*.tsx" --include="*.jsx" | grep '<div\|<span'Use the axe DevTools browser extension to audit live pages for missing landmarks and roles.
<div onClick> with <button> for actions or <a> for navigation<div> elements with <nav>, <main>, <article>, <section>, <aside>, or <header>/<footer> as appropriate<h1> through <h6> in order)