# Accessibility

> Build a Shoplazza App everyone can use: keyboard navigation, semantic page structure, labelled form fields, color contrast, media alternatives, and touch targets.

An accessible app can be used by everyone, including people who rely on assistive technology such as screen readers or keyboard-only navigation. These practices follow the [Web Content Accessibility Guidelines (WCAG)](https://www.w3.org/TR/WCAG21/); following them doesn't guarantee full accessibility, but it covers the issues that affect app users most.

Test your app with tools such as [Lighthouse](https://developers.google.com/web/tools/lighthouse), [Accessibility Insights for Web](https://accessibilityinsights.io/en/), or [WAVE](https://wave.webaim.org/).

## Support keyboard navigation

Users with visual or motor impairments often navigate entirely with a keyboard:

- All links, buttons, menus, and form controls must be reachable and operable with `Tab` / `Shift`+`Tab`, `Enter`, and `Space`.
- Keep the focus indicator visible on active elements — don't remove the outline without providing a replacement.
- Don't rely on hover to reveal functionality.
- Don't force focus jumps: avoid `autofocus` and `tabindex` values other than `0` or `-1`, and don't switch context when an element merely receives focus.
- In modals and drawers, move focus into the dialog on open, keep keyboard navigation inside it, and support `Esc` to close and return focus to the element that opened it. Use `role="dialog"`.

## Structure your pages semantically

Screen readers navigate by structure, so use HTML for what it means:

- Set the `lang` attribute on the `html` element so content is pronounced correctly.
- Use heading tags (`h1`–`h6`) in logical order — one `h1` per page, no skipped levels, no headings used purely for styling.
- Use `a` for navigation and `button` for on-screen actions; make link text meaningful on its own.
- Use `table` with `th` and `scope` attributes for tabular data.
- Don't disable zoom: avoid `maximum-scale` and `user-scalable=no` in your viewport meta tag.

## Label every form field

- Every input needs a label — a visible `<label for>` is best; `aria-label` works where a visible label doesn't fit.
- Mark required inputs with the `required` attribute and use `autocomplete` where the browser can help fill data.
- When validation fails, move focus to the error message, describe the problem clearly, and connect the message to the field with `aria-describedby`. Announce errors and success messages to screen readers with `aria-live`.

## Provide sufficient color contrast

Don't convey information through color alone, and keep text contrast at the level defined by [WCAG 1.4.3 Contrast (Minimum, Level AA)](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html) — 4.5:1 for normal text. Check your palette with a [contrast ratio tool](https://contrast-ratio.com/).

## Describe images and media

- Every `img` needs an `alt` attribute: descriptive text for meaningful images, an empty `alt=""` for decorative ones so screen readers skip them.
- Respect the user's `prefers-reduced-motion` setting for animations.
- Anything that plays automatically — carousels, videos — must be pausable, and auto-playing video must be muted.

## Size touch targets generously

Make primary touch targets at least 44 × 44 pixels — see [mobile support](/docs/app/best-practices/mobile-support) for the full mobile guidance.
