Complete Guide to Web Accessibility: From Automated Testing with Lighthouse / axe and Defining WCAG Criteria to Keyboard Operation and Screen Reader Support

  • playwright
    playwright
  • cypress
    cypress
  • jest
    jest
  • github
    github
  • testinglibrary
    testinglibrary
Published on 2023/11/21

Introduction

Web accessibility is an essential element to ensure that all users can use websites comfortably. In particular, for elderly users and users with visual or hearing impairments, if appropriate accessibility measures are not implemented, their access to information will be restricted.

This article explains in detail concrete methods for improving web accessibility, such as automating accessibility tests using Lighthouse and axe, establishing evaluation criteria based on WCAG guidelines, improving screen reader support, optimizing color contrast, and introducing ARIA landmarks. By continuously implementing these efforts, you can create a website that is easier to use for a wider range of users.

Automating Accessibility Testing (Monitoring with Lighthouse / axe)

By automating accessibility testing, you can ensure continuous quality assurance. In particular, Lighthouse and axe-core are representative tools that are easy to integrate into your development flow.

Accessibility testing with Lighthouse

Lighthouse is an open-source auditing tool provided by Google that can automatically check the following points:

  • Accessibility (usability of web content)
  • Performance (page speed)
  • SEO (search engine optimization)
  • Best Practices (security and mobile support)
  • PWA (progressive web app compliance)

How to run Lighthouse

  • Open the target page in Chrome.
  • Open DevTools with F12 or Cmd + Option + I (Mac) / Ctrl + Shift + I (Windows).
  • Select the Lighthouse tab and check "Accessibility".
  • Click Analyze page load to run the analysis.

Accessibility testing with axe-core

axe-core, developed by Deque Systems, is an accessibility testing tool for developers with the following features:

  • Detects accessibility violations on web pages in detail
  • Can be integrated with test frameworks such as Jest and Cypress
  • Also available as a browser extension (axe DevTools)

1. Combining Cypress + axe-core

You can also run accessibility tests in the E2E testing tool Cypress by using cypress-axe.

Installing cypress-axe

npm install --save-dev cypress-axe

Using axe-core in Cypress tests

describe("Accessibility check", () => {
  it("Should have no detectable accessibility violations", () => {
    cy.visit("https://example.com");
    cy.injectAxe();
    cy.checkA11y();
  });
});
  • cy.injectAxe(): Loads axe-core into the page.
  • cy.checkA11y(): Detects accessibility violations on the page.

Benefits
✅ Detects accessibility violations across the entire page
✅ Can be validated in a real browser environment
✅ Can also test keyboard operations and focus movement

2. Using Playwright + axe-core

Besides Cypress, you can also use axe-core within E2E tests using Playwright.

Installing Playwright + axe-core

npm install --save-dev @playwright/test @axe-core/playwright

Using axe-core in Playwright tests

import { test, expect } from "@playwright/test";
import { injectAxe, checkA11y } from "@axe-core/playwright";

test("Page should be accessible", async ({ page }) => {
  await page.goto("https://example.com");
  await injectAxe(page);
  await checkA11y(page);
});

How to use Lighthouse and axe-core appropriately

Tool Use / Characteristics
Lighthouse Good at calculating accessibility scores and generating reports. Suitable for understanding overall areas for improvement.
axe-core Detects accessibility violations in detail and is suitable for automated tests with Jest or Cypress.

Establishing Accessibility Evaluation Criteria (Defining Criteria Based on WCAG Guidelines)

Web accessibility evaluation criteria are defined based on WCAG (Web Content Accessibility Guidelines). WCAG is an international guideline to ensure that all users can access web content, and it is based mainly on four principles.

The four principles of WCAG

1. Perceivable

Ensure that users can perceive content through vision, hearing, touch, etc.

  • Examples
    • Set alternative text (alt attribute) for images.
    • Provide captions or transcripts for videos and audio.
    • Ensure sufficient contrast ratio (e.g., contrast ratio of at least 4.5:1 between text and background colors).
    • Mark up content so that information is read correctly by screen readers.

2. Operable

Ensure that all users can operate the content.

  • Examples
    • Support keyboard operation (usable without a mouse).
    • Set focus management appropriately (clear navigation with the Tab key).
    • Provide leeway for time-limited operations (give enough time for auto-logout or pop-ups).
    • Suppress flashing or strong animations (to avoid triggering photosensitive seizures).

3. Understandable

Ensure that users can understand the content.

  • Examples
    • Use concise and easy-to-understand language.
    • Clearly convey form error messages (e.g., instead of "Input required", use "Please enter a valid email address").
    • Maintain consistency in navigation (avoid different layouts on each page).

4. Robust

Ensure compatibility with assistive technologies and future usability.

  • Examples
    • Use appropriate HTML markup (proper use of heading tags h1–h6, use of ARIA attributes).
    • Support modern web technologies (e.g., basic operations should be possible even without JavaScript).
    • Test with multiple assistive technologies (screen readers, voice input software, etc.).

Benefits for companies in establishing accessibility evaluation criteria

  1. Improved user experience (UX)
    Improving accessibility allows more people to use your site comfortably.

  2. Compliance with legal regulations
    Japan: Provide reasonable accommodation based on the “Act for Eliminating Discrimination against Persons with Disabilities”.
    EU: Comply with the “European Accessibility Act (EAA)”.
    USA: Standards such as “ADA (Americans with Disabilities Act)” and “Section 508”.

  3. Impact on SEO (search engine optimization)
    Proper HTML structure and alt text settings also benefit SEO.

  4. Corporate social responsibility (CSR)
    Inclusive design contributes to enhancing corporate brand value.

Steps for establishing evaluation criteria within a company

1. Decide on the WCAG conformance level

WCAG has three conformance levels: A, AA, and AAA.

  • A (minimum level): Meets minimum accessibility requirements (e.g., setting alt text for images).
  • AA (recommended level): Criteria that allow many users to use the content (e.g., ensuring color contrast ratio).
  • AAA (high level): Ensures a high level of accessibility (e.g., providing sign language interpretation).

2. Document evaluation criteria suitable for your products

  • Define criteria according to your company’s business and target users.
  • Create an evaluation criteria document and share it with relevant stakeholders within the company.

Example) Documenting evaluation criteria

Item Description Conformance Level
Alt attribute for images Set appropriate alt text for all images A
Keyboard operation All UI elements must be operable via keyboard AA
Color contrast ratio 4.5:1 or higher (between text and background) AA
Form labels Attach clear labels to input fields AA
Video captions Provide captions for all videos AAA

3. Conduct regular evaluations combining automated and manual tests

  • Automated tests
    • Regularly scan using tools such as Axe, Lighthouse, and WAVE.
  • Manual tests
    • Check operation using keyboard only.
    • Validate with screen readers (NVDA, VoiceOver, JAWS).
    • Conduct usability tests (evaluation by actual users).

4. Document audit results and establish an improvement cycle

  • Create audit reports and clarify issues and improvement measures.
  • Develop an improvement plan and review it regularly (e.g., quarterly accessibility reviews).

Checking Keyboard Operation (Verify That All Functions Are Operable via Keyboard)

Checking keyboard operation is essential for improving accessibility (A11Y). In particular, users who cannot use a mouse or who use screen readers need to be able to use all functions with the keyboard alone.

Key points for checking keyboard operation

1. Can you move through all interactive elements with the Tab key?

  • When pressing the tab key, focusable elements on the page such as buttons, links, and input fields must be reachable.
  • Also check that you can move in reverse order with Shift + Tab.
  • Elements with tabindex="-1" cannot receive focus, so set tabindex="0" as needed.

2. Can buttons be activated with Enter / Space?

  • Check that buttons (<button>, <a href>, <input type="submit">) can trigger actions with Enter or Space.
  • If you are using div or span instead of a button, adding role="button" alone is not enough. You also need to handle Enter and Space in the keydown event.

3. Can you close modals with the Escape key?

  • Check that pressing Escape when a modal window is open will close it.
  • Check that aria-hidden and aria-modal="true" are set appropriately.

4. Is the focus indicator (outline) displayed appropriately?

  • Check that outline: none is not specified (it is important not only for appearance but also for visibility).
  • When applying custom focus styles, using :focus-visible allows you to hide them during mouse operation.
button:focus-visible {
  outline: 2px solid #005fcc; /* Accessible focus color */
  border-radius: 4px;
}

Checking via manual testing

Use the tab key to check focus movement.

Checking via automated testing

Cypress is a convenient tool for E2E testing and can also test keyboard operations.

describe('Keyboard Navigation Test', () => {
  it('should allow navigation via Tab key', () => {
    cy.visit('https://example.com');
    cy.get('button').first().focus().should('have.css', 'outline');
    cy.tab().should('have.focus'); // Move to the next element with the Tab key
  });

  it('should close modal on Escape key press', () => {
    cy.get('#open-modal').click();
    cy.get('#modal').should('be.visible');
    cy.get('body').type('{esc}');
    cy.get('#modal').should('not.exist');
  });
});

Playwright can test detailed keyboard operations using keyboard.press().

import { test, expect } from '@playwright/test';

test('Keyboard navigation works correctly', async ({ page }) => {
  await page.goto('https://example.com');

  // Focus the button with the Tab key
  await page.keyboard.press('Tab');
  await expect(page.locator('button')).toBeFocused();

  // Press Enter to click and show the modal
  await page.keyboard.press('Enter');
  await expect(page.locator('#modal')).toBeVisible();

  // Press Escape to close the modal
  await page.keyboard.press('Escape');
  await expect(page.locator('#modal')).not.toBeVisible();
});

Optimizing Color Contrast (Ensuring High Contrast for Color Blind and Low-Vision Users)

Importance of color contrast

  • It is necessary to create a site that is easy to read and distinguish for people with visual impairments or color vision deficiencies (color blindness). If the contrast between text color and background color is insufficient, the text becomes difficult to distinguish.
  • It is also effective for elderly people and those with reduced vision, allowing text information to be conveyed clearly and improving accessibility.
  • WCAG (Web Content Accessibility Guidelines) 2.1 recommends adhering to specific contrast ratios to improve text readability and distinguishability.

Such considerations form the foundation for creating a website that is “comfortable and easy to read for everyone who views it.” By understanding this value and working carefully, you will help many users and, as a result, improve overall satisfaction with the service.

  • Normal text: Contrast ratio of at least 4.5:1
  • Large text (18px or larger, or 14px bold): Contrast ratio of at least 3:1

“Contrast ratio” is a numerical representation of the difference in brightness between the background color and the foreground color (text color). The higher this ratio, the more clearly the two colors can be distinguished, meaning better readability.

Examples)

  • Black text (#000000) on a white background (#FFFFFF) has a contrast ratio of 21:1, which is the highest level.
  • Gray text (#767676) on a white background (#FFFFFF) has a relatively low contrast ratio and may not meet the criteria in some cases.

Testing tools

  1. Lighthouse

    • An auditing tool built into Google Chrome DevTools.
    • If there are issues related to color contrast, they will appear under the “Accessibility” section.
  2. axe DevTools

    • A browser extension provided by Deque Systems.
    • Scans the page and automatically lists accessibility issues. It also makes it easy to find contrast violations.
  3. Contrast Checker

    • Online tools such as “WebAIM’s Contrast Checker”.
    • When you manually enter color codes, it checks the contrast ratio and pass/fail.
    • When working with designers, it becomes easier to make concrete suggestions such as “This color has a contrast ratio of 4.2:1, so let’s make it a bit lighter.”

Improving Screen Reader Support (Proper Setting of the alt Attribute)

In particular, setting an appropriate alt attribute for images (<img> tags) is essential for screen reader users. By following the rules below, you can improve accessibility.

Basic rules for the alt attribute

1. Decorative images (purely visual decoration)

  • Use alt="" (leave it empty)
  • Using role="presentation" together makes the screen reader completely ignore it
  • Example: Icon used as background decoration
    <img src="decorative-icon.png" alt="" role="presentation">
    

2. Meaningful images (images intended to provide information)

  • Set an alt that briefly describes the content of the image
  • If you use role="presentation" together, the screen reader will completely ignore it
  • Example: Product image
    <img src="product.jpg" alt="Red sneakers">
    
  • Put text in alt that describes the content of the link destination
  • Example: Company logo used as a link
    <a href="https://example.com">
      <img src="logo.png" alt="Go to Example’s homepage">
    </a>
    

4. Images containing text

  • Write the text in the image directly in the alt attribute
  • Example: Banner image
    <img src="sale-banner.jpg" alt="All items 20% off! Until this weekend">
    

5. Figures and graphs

  • Write a summary in alt and use figcaption or longdesc for detailed descriptions
  • Example: Graph
    <figure>
      <img src="sales-chart.png" alt="Bar chart showing sales trends">
      <figcaption>Sales trends from January to March 2024</figcaption>
    </figure>
    

Enhancing accessibility using ARIA attributes

In cases where the alt attribute alone is not sufficient, you can use ARIA (aria-*) attributes to ensure that screen readers convey information correctly.

aria-label / aria-labelledby

  • aria-label: Attach a label directly to an element

    <button aria-label="Open menu"></button>
    
  • aria-labelledby: Attach a label by referencing another element

    <h2 id="section-title">Product list</h2>
    <section aria-labelledby="section-title">
      <p>Here we introduce our latest product lineup.</p>
    </section>
    

aria-live (live region)

aria-live (live region) is an attribute that instructs the screen reader: “If the content in this area changes, notify the user.”
When content on a web page changes dynamically, the change may be visually apparent but not announced to the screen reader.
Therefore, by applying aria-live, you can notify the screen reader of the change.

<p id="status" aria-live="polite">There are no items in your cart.</p>
<button onclick="document.getElementById('status').textContent = 'An item has been added to your cart!'">
  Add to cart
</button>
  1. When the page is opened, the screen reader reads “There are no items in your cart.”
  2. When the button is pressed, the content of <p> changes to “An item has been added to your cart!”.
  3. Because of aria-live="polite", the screen reader reads “An item has been added to your cart!” at an appropriate timing.

How to test with screen readers

Testing using screen readers

  • Windows: NVDA
  • Mac: VoiceOver (start with Command + F5)
  • iPhone / iPad: VoiceOver (Settings > Accessibility > VoiceOver)

Points to test

  • Whether alt is read out appropriately
  • Operation of aria-label / aria-labelledby
  • Whether important information is properly conveyed via aria-live

Automated testing tools

Using axe-core, you can efficiently detect accessibility issues.

  1. Install the Chrome extension "axe DevTools"
  2. Open DevTools (F12) and run “axe DevTools”
  3. Detect images without alt and errors in aria-* attributes

https://chromewebstore.google.com/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd?pli=1

Introducing ARIA Landmarks

ARIA (Accessible Rich Internet Applications) landmarks play an important role in making the main sections of a web page easier for screen readers and assistive technologies to recognize. By setting them appropriately, users with visual impairments can quickly grasp the structure of the page and efficiently access the information they need.

Types of landmarks and how to apply them

In HTML5, many elements already have implicit ARIA roles, but in some cases you can explicitly specify the role attribute to enhance screen reader behavior.

Element Default role Recommended role Description
<header> banner (conditional) role="banner" Indicates the header of the entire site or a section.
<nav> navigation role="navigation" Indicates a navigation menu.
<main> main role="main" The main content area of the page.
<aside> complementary role="complementary" Provides supplementary information (such as a sidebar).
<footer> contentinfo (conditional) role="contentinfo" Indicates the footer (such as copyright information).

Points

  • For <header> and <footer>, applying role="banner" or role="contentinfo" is recommended only when they are used as the header or footer for the entire page. (Do not apply them when used within a section.)
  • There should be only one <main> element on a page.
  • If you place multiple <nav> elements, it is desirable to use aria-label to clarify which navigation each one represents.

Code example

The following code sets ARIA landmarks appropriately, making the structure easy for screen readers to recognize.

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ARIADetailed landmark example</title>
</head>
<body>

  <!-- Header -->
  <header role="banner">
    <h1>Site title</h1>
  </header>

  <!-- Global Navigation -->
  <nav role="navigation" aria-label="Global Navigation">
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">Products</a></li>
      <li><a href="#">Support</a></li>
    </ul>
  </nav>

  <div style="display: flex;">
    <!-- Main Content -->
    <main role="main">
      <h2>Main Content</h2>
      <p>This section contains the main information of the page.</p>
    </main>

    <!-- Related Information -->
    <aside role="complementary" aria-labelledby="related-info">
      <h3 id="related-info">Related Information</h3>
      <p>Provides supplementary information.</p>
    </aside>
  </div>

  <!-- Sub navigation -->
  <nav role="navigation" aria-label="Side Navigation">
    <ul>
      <li><a href="#">User Guide</a></li>
      <li><a href="#">FAQ</a></li>
    </ul>
  </nav>

  <!-- Footer -->
  <footer role="contentinfo">
    <p>&copy; 2025 Company Name</p>
  </footer>

</body>
</html>

Points

  • Use aria-labelledby="related-info" to clarify what the supplementary information in the aside relates to.
  • Use aria-label="Global Navigation" and aria-label="Side Navigation" to distinguish the roles of different navigation areas.
  • Use a div to adjust the layout and place main and aside side by side.

Improving Form Accessibility

By properly associating form labels and input fields, you can design forms that are easier to use for visually impaired users who use screen readers and for users who operate via keyboard. This not only improves accessibility but also enhances the user experience.

Explicitly associating the label element

By associating the label element with the input element using the for attribute, screen readers can correctly read each input field in the form.

<label for="username">Username</label>
<input type="text" id="username" name="username">

Points

  • Match the value of the for attribute of label with the id of the corresponding input.
  • Placing the label next to the input also makes it visually easier to understand.

Benefits

  • Screen readers will read “Username, input field” appropriately.
  • Clicking the label moves focus to the associated input, making it easier to click.

Using aria-labelledby

By using aria-labelledby, you can associate one label with multiple input fields or use it as an alternative when it is difficult to visually place a label.

<div>
  <span id="email-label">Email Address</span>
  <input type="email" id="email" aria-labelledby="email-label">
</div>

Points

  • Set the id of the element to be associated as the value of aria-labelledby.
  • Useful in situations where you cannot use a label element (for example, for buttons or complex form layouts).

Benefits

  • Even without a label, screen readers can read the field appropriately.
  • You can associate one label with multiple fields.

Using aria-describedby

When providing supplementary explanations, using aria-describedby allows you to convey supplementary explanations for input fields to screen readers.

<input type="text" id="phone" aria-describedby="phone-desc">
<span id="phone-desc">Please enter without hyphens.</span>

Points

  • Set the id of the supplementary explanation as the value of aria-describedby.
  • You can add usage hints or explanations of error messages.

Benefits

  • When the user focuses on the field, the screen reader reads the supplementary explanation.
  • Also effective for conveying error messages.

Checking Modal Window Operation

By properly managing modal windows, you can improve the comfort of keyboard operation and accessibility. This section explains in detail the importance of focus control and how to implement it correctly.

Properly managing focus within a modal

  • Moving initial focus
    Move focus to an appropriate element (such as a close button or input field) when the modal opens.
  • Preventing focus on background content
    While the modal is open, control focus so that pressing the Tab key does not move focus to background elements.
  • Closing the modal with the Esc key
    Allow users to close the modal when they press the Esc key.

Code example (React + TypeScript modal)

components/Modal.tsx
import { useEffect, useRef } from "react";

interface ModalProps {
  isOpen: boolean;
  onClose: () => void;
}

const Modal: React.FC<ModalProps> = ({ isOpen, onClose }) => {
  const modalRef = useRef<HTMLDivElement>(null);
  const closeButtonRef = useRef<HTMLButtonElement>(null);

  useEffect(() => {
    if (isOpen) {
      // Set initial focus when modal opens
      setTimeout(() => {
        closeButtonRef.current?.focus();
      }, 0);

      const handleKeyDown = (event: KeyboardEvent) => {
        if (event.key === "Escape") {
          onClose();
        } else if (event.key === "Tab") {
          // Loop focus
          const focusableElements = modalRef.current?.querySelectorAll(
            'a[href], button, textarea, input, select'
          ) as NodeListOf<HTMLElement>;

          if (!focusableElements) return;

          const firstElement = focusableElements[0];
          const lastElement = focusableElements[focusableElements.length - 1];

          if (event.shiftKey) {
            if (document.activeElement === firstElement) {
              event.preventDefault();
              lastElement.focus();
            }
          } else {
            if (document.activeElement === lastElement) {
              event.preventDefault();
              firstElement.focus();
            }
          }
        }
      };

      document.addEventListener("keydown", handleKeyDown);
      return () => document.removeEventListener("keydown", handleKeyDown);
    }
  }, [isOpen, onClose]);

  if (!isOpen) return null;

  return (
    <div
      ref={modalRef}
      role="dialog"
      aria-hidden={!isOpen}
      aria-labelledby="modal-title"
      className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50"
    >
      <div className="bg-white p-6 rounded-lg shadow-lg w-96">
        <h2 id="modal-title" className="text-lg font-bold mb-4">
          Modal Title
        </h2>
        <p className="mb-4">Modal content goes here.</p>
        <button
          ref={closeButtonRef}
          onClick={onClose}
          className="bg-red-500 text-white px-4 py-2 rounded"
        >
          Close
        </button>
      </div>
    </div>
  );
};

export default Modal;

Points

  • Managing modal open/close with isOpen
    • The modal is displayed only when isOpen is true.
    • When isOpen is false, it returns null and is hidden.
  • Focus management
    • When the modal is opened, initial focus is set to the Close button.
    • Focus loops with the Tab key (firstElementlastElement).
  • Closing with the Esc key
    • Listen for the keydown event and run onClose() when the Escape key is pressed.
  • Accessibility support
    • Set role="dialog" on the <div> and use aria-hidden for screen reader support.
    • Set aria-labelledby="modal-title" so that the title is read out.

Usage example (App.tsx)

Place a button to open/close the modal in App.tsx and manage state using useState.

App.tsx
import { useState } from "react";
import Modal from "./Modal";

const App = () => {
  const [isModalOpen, setIsModalOpen] = useState(false);

  return (
    <div className="flex flex-col items-center justify-center h-screen">
      <button
        onClick={() => setIsModalOpen(true)}
        className="bg-blue-500 text-white px-4 py-2 rounded"
      >
        Open modal
      </button>

      <Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} />
    </div>
  );
};

export default App;

With this code, you can confirm the following behavior:

  1. Clicking the “Open modal” button displays the modal.
  2. Pressing the Tab key moves focus only among elements inside the modal.
  3. Pressing the Esc key closes the modal.
  4. When the modal closes, focus returns to the original “Open modal” button.

Checking Responsive Design

Responsive design is a design approach that adjusts the layout appropriately according to different devices and screen sizes. By especially considering accessibility (ease of use), you can build a website that all users can operate comfortably. Here, we explain in detail media queries and the viewport meta tag, which are the basics of responsive design.

Using media queries

Media queries are a CSS feature that allows you to apply different styles depending on screen size and device characteristics.

@media (max-width: 600px) {
  nav {
    display: block;
  }
}

This media query is applied when the screen width is 600px or less.

  • @media (max-width: 600px) { ... }
    • Applied when the screen width is 600px or less
    • Assumes smartphones and small devices
  • nav { display: block; }
    • Normally, nav is often displayed horizontally with display: flex or display: inline-block.
    • On small screens, changing to display: block; allows vertical display.
    • This prevents menus from becoming cramped and makes them easier for users to operate.
/* Large screens (for desktops) */
@media (min-width: 1024px) {
  body {
    font-size: 18px;
  }
}

/* Medium screens (for tablets) */
@media (max-width: 1023px) and (min-width: 601px) {
  body {
    font-size: 16px;
  }
}

/* Small screens (for smartphones) */
@media (max-width: 600px) {
  body {
    font-size: 14px;
  }
}

You can also apply different designs for each screen size.

Setting the viewport meta tag

<meta name="viewport" content="width=device-width, initial-scale=1.0">

This <meta> tag is used to properly set the display area (viewport) of the page.

Meaning of each attribute:

  • name="viewport"
    • Specifies that viewport settings are being configured
  • content="width=device-width"
    • Automatically adjusts the page width to match the device width
    • Without this, the desktop layout will be displayed as-is, causing text to become extremely small or horizontal scrolling to occur
  • initial-scale=1.0
    • Sets the initial zoom level to 1.0 (100%)
    • Prevents the browser from zooming automatically unless the user zooms in or out

Problems when the viewport meta tag is not set:

  • When viewed on mobile, the desktop design is displayed as-is
  • Text may become small and unreadable without zooming
  • Users may have to scroll or zoom unintentionally to operate the page

Regular Generation of Accessibility Reports

By regularly generating accessibility (A11y) reports, you can keep your web application consistently easy to use for users.
In this process, you use automated testing tools to detect accessibility issues early and help with improvements.

Accessibility testing using axe-core

axe-core is an industry-standard accessibility testing library developed by Deque Systems.
By using @testing-library/react and jest-axe to test React components, you can detect accessibility violations.

Installing jest-axe

npm install --save-dev jest-axe @testing-library/react

Accessibility testing for React components

import React from "react";
import { render } from "@testing-library/react";
import { axe, toHaveNoViolations } from "jest-axe";
import MyComponent from "../MyComponent";

expect.extend(toHaveNoViolations);

test("MyComponent is accessible", async () => {
  const { container } = render(<MyComponent />);
  const results = await axe(container);
  expect(results).toHaveNoViolations();
});

Points

  • axe(container): Checks for accessibility violations in the DOM.
  • toHaveNoViolations(): Confirms that there are no accessibility violations.

Benefits

  • You can run accessibility tests at the component level.
  • You can integrate it into your CI/CD pipeline to automatically check accessibility.

How to integrate Lighthouse into CI/CD

Place lighthouserc.json in the root of your project.

{
  "ci": {
    "collect": {
      "url": ["https://example.com"],
      "numberOfRuns": 3
    },
    "assert": {
      "assertions": {
        "categories:accessibility": ["error", { "minScore": 0.9 }]
      }
    },
    "upload": {
      "target": "temporary-public-storage"
    }
  }
}

Points

  • numberOfRuns: Setting to run the same test multiple times to obtain stable results.
  • assertions: Throws an error if the accessibility score is below 0.9.
  • upload: Uploads results to temporary storage.

Next, use GitHub Actions to run Lighthouse in CI/CD.

name: Lighthouse Accessibility Check

on:
  schedule:
    - cron: '0 0 * * 1' # Run every Monday

jobs:
  lighthouse:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Run Lighthouse
        run: |
          npx lighthouse --config-path=lighthouserc.json

Conclusion

Improving web accessibility is not just about complying with laws or ticking off checklists; the goal is to provide a comfortable and fair experience for all users. By putting into practice the methods introduced in this article—such as using Lighthouse and axe for automated testing, improving keyboard operation and screen reader support, and introducing ARIA landmarks—you can build highly accessible websites.

However, accessibility measures are not something you can set once and forget; continuous improvement is required. It is important to keep improving by regularly generating reports and conducting user tests, incorporating feedback from actual users.

Let’s start working on improving accessibility today, aiming for a web that all users can use comfortably.

Xでシェア
Facebookでシェア
LinkedInでシェア

Questions about this article 📝

If you have any questions or feedback about the content, please feel free to contact us.
Go to inquiry form