들어가면서
Storybook은 컴포넌트를 독립적으로 개발하는 것 외에도 많은 베네핏을 준다. 실제로 컴포넌트들이 어떻게 동작하고 변화하는지 시각적으로 빠르게 테스트할 수 있다. 컴포넌트의 use cases, 즉 스토리들을 만들어두면 문서화 역할도 가능하다. 이에 더해 Storybook을 통해 컴포넌트들의 접근성을 테스트하고 개선할 수 있다. 이 과정을 공유해보려고한다.
1. 웹 접근성이란
웹 개발에서 접근성이란 사람들의 능력이 제한되어도, 가능한 많은 사람들이 웹사이트를 사용하게 하는 것입니다.
- MDN
2. Storybook으로 웹 접근성 테스트 환경 구축 (v7.4.0)
1) a11y addon 패키지 설치하기
yarn add --dev @storybook/addon-a11y
npm install @storybook/addon-a11y --save-dev
pnpm add --save-dev @storybook/addon-a11y
2) storybook config에 a11y addon 추가
// .storybook/main.ts
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
framework: '@storybook/your-framework',
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
// Other Storybook addons
'@storybook/addon-a11y', //👈 The a11y addon goes here
],
};
export default config;
3) Storybook 실행
설치한 a11y addon 패키지에서 Axe 라는 접근성 테스트 엔진을 실행시켜 선택된 컴포넌트를 테스팅한다. Accessibility 탭을 통해 컴포넌트의 접근성 이슈와 개선 가이드 라인을 확인할 수 있다.
3. Storybook으로 웹 접근성 개선하기
Accessibility에 Violations, Passes, Incomplete 3가지 항목이 보이는데 Violations, Incomplete 항목 위주로 개선해 나아가면 된다. 회사에서 테스트하면서 가장 많이 마주 쳤던 2가지 이슈를 뽑아 봤다.
1) [Element] must have discernible text
Q. 어떤 문제 인가?
button이나 a 요소에 인식할 수 있는 텍스트가 없어서 접근성에 문제가 생긴 것이다.
텍스트 없이 아이콘만 사용된 로고 버튼을 떠올리면 이해하기 쉬울 것이다.
Q. 버튼에 텍스트가 없으면 왜 문제가 될까?
스크린 리더기를 사용하는 유저 입장에서는 해당 버튼이 어떤 역할을 하는지 모호하다. 아이콘 모양만 보고 버튼을 눌렀을 때 어떤 일이 일어나는지 구체적으로 모르기 때문이다. 이로 인해 스크린 리더를 사용하는 유저는 웹사이트를 사용하기 불편해진다. 다시 말해 접근성이 떨어지게 된다.
Q. 개선 방법은?
// 개선 전
<Button onClick={goToHome}>
<Logo>
<Button>
// 개선 후
<Button aria-label='go to the home' onClick={goToHome}>
<Logo>
<Button>
*aria-label을 통해 버튼이 어떤 역할을 하는지 스크린 리더가 알 수 있게 설명했다. 이로써 스크린 리더는 유저에게 로고 버튼을 누르면 home으로 이동시켜 준다는 의미를 전달 할 수 있다.
*aria-label: 상호작용하는 요소에 string value의 label을 정의하는 요소.
2) Ensures landmarks are unique
Q. 어떤 문제인가?
한 페이지에 landmarks가 중복되는 경우 발생한다. 여기서 landmarks란 header, main, nav, footer 같은 상징이 되는 요소들을 말한다. 나의 경우 header에 있는 nav와 Footer에 nav 요소가 중복되어서 접근성 경고를 받았다.
Q. landmarks 요소들이 중복되었을 때 왜 접근성이 떨어질까?
스크린 리더가 웹페이지 구조를 의미있게 파악하기 어렵게 만들기 때문이다. 이로 인해 사용하는 유저도 웹페이지 탐색이 어려워 질 수 있다. 스크린 리더는 landmarks 요소들을 활용하여 웹 페이지의 구조를 의미있게 파악하여 사용자에게 정보를 전달한다. 웹 페이지의 구조를 의미있고 구체적으로 전달해야 스크린 리더 사용자가 웹 페이지 탐색을 원활히 할 수 있다.
Q. 개선 방법은?
// 개선 전
<body>
<header>
<nav>...</nav> // 중복!
<haeder>
<main>
...
</main>
<footer>
<nav>...</nav> // 중복!
<footer>
</body>
// 개선 후
<body>
<header>
<nav>...</nav>
<haeder>
<main>
...
</main>
<footer>
<nav aria-label='footer'>...</nav>
<footer>
</body>
footer에 있는 nav 요소에 footer라는 label을 넣어주어 header에 있는 nav와 구분하였다. 이로써 스크린 리더 사용자가 더 시맨틱하게 웹페이지 구조를 파악하고 탐색할 수 있다.
4. TMI
- a11y는 accessibility의 약어이다. 11은 a와 y사이에 알파벳들을 의미한다.
- 긴 알파벳을 숫자화하는 기법을 numeric이라고 한다. 사용자들에게 기억이나 소통하기 쉽게 만들어 준다.
- 또 다른 예시로 i18n이 있다. internationalization의 약어이다.
- 웹 접근성 관련 가장 널리 인정받는 표준은 WCAG(Web Content Accessibility Guidelines)이다.
Ref
https://daily-dev-tips.com/posts/a11y-101-ensure-landmarks-are-unique/#google_vignette
https://developer.mozilla.org/en-US/docs/Web/Accessibility
https://storybook.js.org/docs/react/writing-tests/accessibility-testing