Accessibility Is Not a Nice-to-Have, It's the Job
Practical accessibility wins I reach for on every project — semantic HTML, visible focus, honest ARIA, and real keyboard support — and why each one quietly makes the product better for everyone.
The short answer: accessibility isn't an optional pass you do later — it's part of the definition of "done," and you get most of it for free by using semantic HTML, keeping focus visible, writing honest ARIA only where the platform can't, and making everything keyboard-operable.
I've sat in too many planning meetings where accessibility is the line item that gets cut when the sprint runs hot. "We'll do a pass later." We never did a pass later. After eight years of shipping React, I've come to a blunt conclusion: accessibility isn't a feature you bolt on, it's the definition of "done." A button a keyboard user can't reach isn't a finished button. It's a broken one that happens to look fine on your mouse.
The good news is that the highest-leverage wins are also the cheapest. You don't need an audit budget to get 80% of the way there. You need to stop fighting the platform.
Semantic HTML does most of the work for free
The single biggest thing I police in code review is <div onClick>. A div is a generic box with no role, no keyboard behavior, and nothing to announce to a screen reader. A <button> is focusable, fires on Enter and Space, announces itself as a button, and participates in forms — all without a line of JavaScript from you.
Same instinct for the rest: a list of things is a <ul>, a page section with a heading is a <section> with an <h2>, a toggle in a form is an <input type="checkbox">. When you reach for the right element, the browser hands you focus management, keyboard support, and the accessibility tree for nothing.
Never remove the focus ring — redesign it
The second worst thing in a stylesheet is outline: none. People do it because the default ring looks ugly, then they forget to put anything back, and now a keyboard user is navigating a page with no idea where they are. The fix isn't to hide focus; it's to make focus a thing you designed on purpose.
:focus-visible is the trick that lets you keep a clean mouse experience and a loud, obvious keyboard experience at the same time. There's no tradeoff to make anymore.
ARIA is a last resort, not a sticker
The first rule of ARIA is: don't use ARIA. Every role and aria-* attribute is a promise you're making to assistive tech that you now have to keep in JavaScript. A real <button> keeps that promise automatically; role="button" means you've signed up to wire Enter, Space, and focus yourself.
Where ARIA genuinely earns its place is naming and state that the DOM can't express on its own — an icon-only button, a live region, the expanded state of a custom disclosure.
Note the aria-hidden="true" on the icon — decorative glyphs should be invisible to the accessibility tree so they don't get read as "image" noise.
Test it the way the users do
You don't need a screen reader to catch most problems. Put your mouse down and Tab through the entire flow. Can you reach every control? Does focus move somewhere sane when a modal opens, and come back when it closes? Can you escape a dialog with the Escape key? If any answer is no, that's a bug ticket, same as a crash.
Why this is actually everyone's win
Here's the part product managers warm to: none of this only helps disabled users. Captions help the person watching a video on a silent commute. Keyboard support helps the power user who never touches their trackpad. High-contrast text helps anyone outdoors in the sun. Clear focus helps every user who got distracted and forgot where they were.
Accessible design is just good design with the edge cases taken seriously — and the edge cases are where real products either hold up or fall apart. It's not charity. It's the job.