Skip to content

Accessibility

To ensure that all button variants meet accessibility standards across platforms, follow the implementation checklist below. These recommendations align with WCAG 2.1 AA, support keyboard navigation, and are compatible with assistive technologies.

  • All button states (rested, hover, active, disabled, focus) must maintain accessible contrast in both light and dark background contexts.
  • Focus styles must remain visible and meet WCAG AA contrast requirements across all supported surfaces. Focus should be clearly distinguishable from hover. Use a high-contrast outline or border (e.g. #0072F0 against adjacent backgrounds).
  • Hover, focus and pressed states must be clearly differentiated using more than colour alone. Examples: colour change plus border or shadow; icon or text emphasis.
  • All buttons must show a visible focus style (not just a colour change) on keyboard navigation. Never remove the browser’s default outline unless replaced with an accessible alternative.
  • Disabled buttons must not be focusable and must not trigger actions. Maintain sufficient visual contrast for recognition (ideally ≥ 3:1, or provide a clear visual separation).
  • Absolute minimum: 24 × 24 px — the lowest technical requirement. It ensures the element can still be reached but does not guarantee an optimal experience.
  • Recommended best practice: 44 × 44 px — follows WCAG 2.5.5 Target Size (Level AA) and EN 301549 guidance. Provides a more comfortable interaction area for users with motor difficulties, touch devices, or when using a device outdoors. Should be the default requirement.
  • The minimum target size applies regardless of the visual size of the component. If the visual element is smaller, additional spacing or invisible padding must be added. Consistency is key: the same rule applies across all sizes (LG, MD, SM).

To ensure buttons meet WCAG 2.1 AA and support assistive technologies, follow these implementation standards:

  1. Semantic HTML
    • Always use the native <button> element (not <div> or <a> without role). If an <a> element must be used as a button, ensure role="button" is set, that it is focusable with tabindex="0", and that it supports Enter/Space keypress events. This should be considered a fallback only.
  2. Keyboard Navigation
    • All buttons must be reachable with Tab and activatable with Enter and Space.
    • Icon-only buttons must include accessible labelling: aria-label="Edit" or aria-labelledby="..." when referencing visible text elsewhere.
    • Ensure keyboard shortcuts follow platform conventions (Enter/Space on desktop, tap on mobile).
  3. Focus Ring / Visible Focus
    • All buttons must show a visible focus style (not just a colour change) on keyboard navigation.
    • Use a high-contrast outline or border (e.g. #0072F0 against adjacent backgrounds).
    • Focus must remain persistent and highly visible, not replaced by hover styles.
    • Never remove the browser’s default outline unless replaced with an accessible alternative.
  4. Screen Reader Support
    • Each button must include a clear and concise text label (e.g. <button>Edit</button>).
    • For icon-only buttons: use aria-label or title to describe the action (e.g. “Download PDF”).
    • Avoid redundant roles or aria-hidden="true" on interactive buttons.
  5. Disabled State
    • Use the disabled attribute on <button> rather than visually faking it.
    • Disabled buttons must not be focusable and must not trigger actions.
    • Maintain sufficient visual contrast for recognition (ideally ≥ 3:1, or provide a clear visual separation).
    • Note: contrast may fall below 4.5:1 if disabled buttons are visibly distinguishable and not interactive, as per WCAG 2.1 SC 1.4.3.
  6. Interaction Feedback
    • Hover, focus and pressed states must be clearly differentiated using more than colour alone.
    • Examples: colour change plus border or shadow; icon or text emphasis.
  7. Responsive and Tap Targets
    • Touch targets must meet minimum sizes (WCAG + mobile UX best practices).
    • Ensure icon-only or small buttons are not too small on touch devices.
    • Use spacing tokens to maintain consistency across breakpoints.
  • Use <button> for actions (submit, toggle, open dialog). Use <a> for navigation. Both can be styled with .tng-button, but only <button> responds to Space and has implicit role="button".
  • Never use <a href="#"> as a button substitute — screen readers announce it as a link.
  • Disabled — prefer the native disabled attribute. It removes the button from tab order and communicates the state automatically.
  • Focusable disabled — if a disabled button must remain focusable (e.g. to show a tooltip), use aria-disabled="true" instead and prevent the click in JavaScript.
  • Toggle buttons — use aria-pressed="true" / "false" for on/off toggles. Use aria-expanded when the button controls a collapsible region.

All button variants use the tng-touch-target utility to meet the WCAG 2.5.8 minimum target size of 44×44 CSS pixels.

Case✅ Good❌ Bad
Semantic Structure<button>Save</button><div onclick="save()">
Keyboard NavigationActivatable using Enter / SpaceOnly activatable with pointer click
Focus VisibilityClear, high-contrast focus ringFocus removed or replaced by hover-only styling
Disabled State<button disabled> with muted stylingVisually greyed but still interactive
Screen Reader<button aria-label="Download PDF"> for iconIcon button with no accessible name