React
Product interfaces: state ownership, API workflows, forms and accessibility.
- State management
- API integration
- Forms
- Accessibility
Accessibility has become part of how I approach engineering, not a final compliance task. My experience includes accessible development, WCAG implementation, accessibility auditing, remediation and working on accessibility-focused SaaS products.
Semantic HTML · Keyboard & focus · Manual testing · WCAG
How I think about it
Accessibility works best when it is considered during design and engineering. Fixing accessibility after a product is already built is usually slower, more expensive and less consistent.
Key experience
Scope
Deep dive
The most effective accessibility work is choosing the right element. A <button> is focusable, activates with Enter and Space and announces itself as a button — for free. A <div> with a click handler needs all of that rebuilt, and usually doesn't get it.
Links go somewhere; buttons do something. Headings describe the structure of the page, not the font size. Landmarks such as header, nav, main and footer let screen-reader users jump straight to what they need, and every form field needs a programmatic label — placeholder text is not one.
<!-- Focusable, works with Enter and Space, announced as a button -->
<button type="button" aria-expanded="false" aria-controls="filters">
Filters
</button>
<!-- None of that comes for free -->
<div class="btn" onclick="toggleFilters()">Filters</div> ARIA should support semantics, not replace correct HTML. It changes what assistive technology is told, not how the element behaves: role="button" doesn't make anything keyboard-operable, and aria-expanded doesn't open anything. Wrong ARIA is worse than none, because it makes promises the interface doesn't keep.
I reach for ARIA when HTML has no native equivalent: states such as aria-expanded, aria-selected and aria-current; relationships such as aria-describedby for hints and errors; and live regions for status updates. Every attribute added is one more thing the code must keep in sync.
Everything usable with a mouse must be usable with a keyboard, in an order that matches the visual layout. My first test is simple: put the mouse away. Can I reach every control, see where focus is, operate it and leave it again?
Custom controls need the keys people expect — Escape closes, arrow keys move within menus, tabs and listboxes — and focus indicators must be clearly visible. Removing outlines without a replacement is one of the most common regressions I see.
In dynamic interfaces focus has to be managed on purpose. A modal moves focus inside when it opens, keeps it there, closes with Escape and returns focus to the control that opened it. After a client-side route change, focus and an announcement should tell the user the page changed. When content is removed, focus shouldn't silently fall back to the top of the document.
Forms are where accessibility failures cost the most, because they block the task itself. Every field needs a visible label tied to the input, instructions before the field rather than after a failed submission, and required fields indicated in text, not only by colour.
Errors should be specific — “Enter an email address, for example [email protected]” — connected to the field with aria-describedby, and surfaced on submit by moving focus to the first problem, so a screen-reader user knows something went wrong and where.
A screen reader experiences the page through the accessibility tree: names, roles, states and reading order. Testing means listening to what is actually announced. Is the button's name meaningful out of context? Is the new state announced when it changes? Does the reading order match the visual order?
Screen readers and browsers combine differently, so critical flows are tested with real assistive technology rather than assuming correct markup is enough.
React, Vue and other single-page applications make it easy to build interfaces that look right and are silent to assistive technology: content that updates without an announcement, modals that don't contain focus, route changes that leave focus on a link that no longer exists, notifications that disappear before they can be read.
The fix is usually a small set of well-built shared components — dialog, menu, tabs, toast, form field — plus live regions for status messages, used consistently across the product.
Text needs sufficient contrast against its real background, including over images and gradients; interface components — input borders, focus rings, icons that carry meaning — need contrast too. Colour can't be the only signal: an error needs text or an icon as well as red.
Layouts should survive 200% zoom and increased text spacing without clipping or horizontal scrolling, and interactive states — hover, focus, selected, disabled — must be visibly distinct.
Data tables need real table markup with header cells and a caption, not a grid of divs. For complex widgets — dialogs, menus, tabs, accordions, comboboxes — I follow established interaction patterns rather than inventing new ones, because people using assistive technology rely on that predictability.
Automated checkers are good at what can be computed: missing alternative text, missing labels, invalid ARIA, many contrast failures. They can't judge whether alternative text is meaningful, whether focus order makes sense, whether an error message helps, or whether a custom widget can actually be operated.
So every audit I run combines automated scans with manual keyboard testing and screen-reader checks. Many automated results also need human review — a tool can flag text on a gradient, but someone has to decide whether it is readable.
Automated tools are a starting point, not a verdict. A page can pass every automated rule and still be unusable with a keyboard.
WCAG organises its requirements around four principles. The success criteria are testable, which makes them a useful shared language for designers, developers, QA and clients — as long as the goal stays real people completing real tasks, not a ticked checklist.
Accessibility holds up when it's part of the normal workflow rather than a phase at the end.
In practice
Real products
Accessibility runs through products I've delivered — including a platform whose whole purpose is improving accessibility.
Accessibility Technology / SaaS
Accessibility SaaS for identifying, managing and improving digital accessibility — I lead delivery across frontend, backend, QA and design.
Education / Accessibility
Accessible platform for people with print disabilities — accessible web development and WCAG implementation.
Product interfaces: state ownership, API workflows, forms and accessibility.
Vue product interfaces: component boundaries, composables, state and Laravel integration.
Custom themes, plugins and integrations — and knowing when WordPress fits.
Tenancy, permissions, plans, billing and the realities of running SaaS in production.
Identify, document, and fix accessibility issues in modern websites and web applications.
Learn moreBuild reliable web platforms, SaaS products, dashboards, APIs, and internal tools with modern full-stack technologies.
Learn moreWhether it's an architecture decision, a delivery problem or something specific to Web Accessibility, I can help you find a practical path forward.
What happens next
Share your goal
A few lines about the product, problem, or audit need.
Get a quick read
A practical reply on the best technical path forward.
Move forward
A clear scope, estimate, or concrete next step.