웹 접근성 (a11y 라고도 함)은 모든 사람이 사용할 수있는 웹 사이트를 만드는 것입니다. 웹페이지에 대한 접근성을 지원하기 위해서 보조 기술이 필요합니다.
표준 HTML 기술을 이용하여 웹사이트의 접근성 지원이 가능합니다.
웹 사이트를 만들기 위한 웹 콘텐츠 접근성 지침을 제공합니다.
WCAG 체크리스트 관련 내용을 제공합니다.
Web Accessibility Initiative - Accessible Rich Internet Applications 문서에는 접근성을 보장할 수 있는 JavaScript 위젯을 작성하는 기술이 포함되어 있습니다.
모든 aria-*HTML
속성은 JSX
에서 완벽하게 지원됩니다. React의 대부분의 DOM 속성은 camelCase
로 지정하지만, 이 속성은 일반 HTML과 마찬가지로 하이픈 (cbab-case
) 규칙으로 지정합니다. 하이픈 규칙은 리스프 케이스 (lisp-case
)라고도 합니다.
<input
type="text"
aria-label={labelText}
aria-required="true"
onChange={onchangeHandler}
value={inputValue}
name="name"
/>
웹 애플리케이션 접근성 제공은 시맨틱 HTML을 기반으로 합니다. 웹 사이트의 접근성을 제공하기 위해서는 다양한 HTML 요소를 사용하여 웹 사이트에서 정보의 의미를 강화합니다.
React 코드 작성을위해 간혹 JSX
에 <div>
요소를 추가하여 HTML 의미를 깨뜨릴 수 있습니다.
React 코드를 작성하기 위해 JSX
에서 시멘틱 HTML을 깨트리는 경우가 있습니다. 특히 <ol>
, <ul>
, <dl>
, <table>
를 사용할때 발생하며, 이런 경우 React Fragments를 사용 하여 여러 요소를 그룹화 하여 이를 해결할 수 있습니다.
예를 들어
import React, { Fragment } from 'react';
function ListItem({ item }) {
return (
<Fragment>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</Fragment>
);
}
function Glossary(props) {
return (
<dl>
{props.items.map(item => (
<ListItem item={item} key={item.id} />
))}
</dl>
);
}
다른 유형의 요소들처럼 dl
관련 태그들을 배열에 매핑 할 수 있습니다.
function Glossary(props) {
return (
<dl>
{props.items.map(item => (
// Fragments should also have a `key` prop when mapping collections
<Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</Fragment>
))}
</dl>
);
}
툴링 지원이 있다면 Fragment
태그에 props
이 필요 없는 경우 간단한 구문을 사용할 수 있습니다.
function ListItem({ item }) {
return (
<>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</>
);
}
자세한 내용 은 Fragments 문서를 참조하십시오 .
접근성을 위해 <input>
, <textarea>
같은 모든 HTML 폼 컨트롤에는 스크린 리더에 읽히는 설명 라벨을 제공해야합니다.
아래 링크는 관련 방법들을 보여줍니다.
이러한 표준 HTML
사례는 React에서 직접 사용할 수 있지만 for
속성은 JSX
에서 htmlFor
로 작성해야 합니다.
<label htmlFor="namedInput">Name:</label>
<input id="namedInput" type="text" name="name"/>
오류 상황은 모든 사용자가 인지 해야 합니다. 다음 링크는 스크린 리더기에 오류 텍스트를 표시하는 방법을 보여줍니다.
웹 응용 프로그램이 키보드로만 완벽하게 작동 할 수 있는지 확인하십시오.
키보드 포커스는 현재 선택된 DOM
요소를 나타냅니다. 다음 이미지처럼 포커스가 된 요소를 흔히 볼 수 있습니다.
이 선택 효과를 제거 하려 한다면 CSS 만 사용하십시오. 예를 들어 다른 포커스 효과를 주길 원한다면 outline: 0
를 설정합니다.
색션을 건너뛰는 매커니즘을 이용하여 사용자의 키보드 탐색을 지원합니다.
Skiplink
또는 Skip Navigation Links
는 키보드 사용자가 페이지와 상호 작용할 때만 표시되는 숨겨진 탐색 링크입니다. 앵커 태그및 CSS
를 사용한다면 쉽게 구현 가능합니다.
<main>
, <aside>
같은 요소를 사용하여 페이지 영역을 구분한다면 사용자는 관련 세션으로 빠르게 이동할 수 있습니다.
접근성을 높이기 위해 위와 같은 요소를 사용하는 방법에 대해 자세히 알아보십시오.
React 애플리케이션은 런타임 중에 HTML DOM
을 지속적으로 변경합니다. 프로그래밍 방식으로 올바른 포커스 방식으로 이동시켜 키보드 포커스를 잃어 버리거나 의도하지않은 요소로 설정되는 문제를 해결할 수 있습니다. 예를 들어, 모달창을 닫은 후에 모달창을 연 button
태그에 포커스를 다시 설정합니다.
MDN Web Docs
는 탐색 가능한 JavaScript 위젯 제작방법을 설명합니다.
React에서 Refs
를 사용하여 DOM
요소에 대한 포커스를 설정합니다.
이를 참고하여 컴포넌트 클레스의 JSX
에서 요소에 대한 참조를 작성합니다.
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// Create a ref to store the textInput DOM element
this.textInput = React.createRef();
}
render() {
// Use the `ref` callback to store a reference to the text input DOM
// element in an instance field (for example, this.textInput).
return (
<input
type="text"
ref={this.textInput}
/>
);
}
}
이렇게 한다면 필요할때마다 컴포넌트의 요소를 포커스할 수 있습니다.
focus() {
// Explicitly focus the text input using the raw DOM API
// Note: we're accessing "current" to get the DOM node
this.textInput.current.focus();
}
간혹 부모 컴포넌트가 자식 컴포넌트의 요소에 포커스 설정이 필요한 경우가 있습니다. 다음과 같이 자식 컴포넌트에 props
로 DOM Refs
를 부모 컴포넌트의 노출을 전달 하여 자식의 DOM
노드에 설정할 수 있습니다.
function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} />
</div>
);
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.inputElement = React.createRef();
}
render() {
return (
<CustomTextInput inputRef={this.inputElement} />
);
}
}
// Now you can set focus when required.
this.inputElement.current.focus();
HOC
를 사용하여 컴포넌트를 확장 하는 경우, React의 forwardRef
함수를 사용하여 래핑된 컴포넌트로 참조를 전달 하는 것이 좋습니다. 만약 third-party HOC
가 ref전달을 구현하지 않은 경우 위 패턴을 폴백으로 사용할 수 있습니다.
좋은 초점 관리 예는 react-aria-modal입니다. 이것은 포커스로 접근이 불가능한 모달 윈도우의 예입니다. 키보드를 이용하여 모달의 취소 버튼에 초기 초첨을 설정할 뿐만 아니라 키보드 사용자가 잘못된 성공 동작을 활성화 하는 것을 방지 합니다. 또한 처음 모달을 트리거한 요소로 포커스를 다시 설정합니다.
노트
이것은 접근성을위해 매우 중요한 것들이며, 현명하게 사용되어야 하는 기술이기도 합니다.
사용자가 키보드를 이용하여 어플리케이션을 사용하는데 방해받지 않도록 하세요.
키보드만을 이용하여 마우스 또는 포인터 이벤트를 통해 노출되는 모든 기능을 사용할 수 있는지 확인하세요. 포인터 장치로만 사용할 수 있다면 키보드 사용자가 어플리케이션을 사용할 수 없는 경우가 많습니다.
클릭 이벤트로 인해 접근성이 망가지는 경우가 많습니다. 아래는 외부 클릭 패턴이며, 사용자가 요소 외부를 클릭하여 열린 팝업을 제거 하는 동작을 합니다.
이것은 보통 window
객체의 click
이벤트를 이용하여 popover
를 닫는 방식으로 구현합니다.
class OuterClickExample extends React.Component {
constructor(props) {
super(props);
this.state = { isOpen: false };
this.toggleContainer = React.createRef();
this.onClickHandler = this.onClickHandler.bind(this);
this.onClickOutsideHandler = this.onClickOutsideHandler.bind(this);
}
componentDidMount() {
window.addEventListener('click', this.onClickOutsideHandler);
}
componentWillUnmount() {
window.removeEventListener('click', this.onClickOutsideHandler);
}
onClickHandler() {
this.setState(currentState => ({
isOpen: !currentState.isOpen
}));
}
onClickOutsideHandler(event) {
if (this.state.isOpen && !this.toggleContainer.current.contains(event.target)) {
this.setState({ isOpen: false });
}
}
render() {
return (
<div ref={this.toggleContainer}>
<button onClick={this.onClickHandler}>Select an option</button>
{this.state.isOpen ? (
<ul>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
) : null}
</div>
);
}
}
이것은 마우스와 같은 포인터 장치를 사용하는 사용자에게 적합니다. window
객체가 click
이벤트를 받지 못하기 때문에 다음 요소로 이동할때 기능이 키보드 만으로는 모달레이어를 닫을 수없습니다. 때문에 사용자가 어플리케이션을 사용못하게됩니다.
onBlur
및 onFocus
와 같은 적절한 이벤트 처리기를 이용한다면 이를 해결할 수 있습니다.
class BlurExample extends React.Component {
constructor(props) {
super(props);
this.state = { isOpen: false };
this.timeOutId = null;
this.onClickHandler = this.onClickHandler.bind(this);
this.onBlurHandler = this.onBlurHandler.bind(this);
this.onFocusHandler = this.onFocusHandler.bind(this);
}
onClickHandler() {
this.setState(currentState => ({
isOpen: !currentState.isOpen
}));
}
// We close the popover on the next tick by using setTimeout.
// This is necessary because we need to first check if
// another child of the element has received focus as
// the blur event fires prior to the new focus event.
onBlurHandler() {
this.timeOutId = setTimeout(() => {
this.setState({
isOpen: false
});
});
}
// If a child receives focus, do not close the popover.
onFocusHandler() {
clearTimeout(this.timeOutId);
}
render() {
// React assists us by bubbling the blur and
// focus events to the parent.
return (
<div onBlur={this.onBlurHandler}
onFocus={this.onFocusHandler}>
<button onClick={this.onClickHandler}
aria-haspopup="true"
aria-expanded={this.state.isOpen}>
Select an option
</button>
{this.state.isOpen ? (
<ul>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
) : null}
</div>
);
}
}
이 코드는 포인터 장치와 키보드 사용자 모두에게 기능을 제공합니다. 스크린 리더 사용자를 지원하기 위해 추가된 aria-*
props도 참고 하세요. 간략하게 사용하기위해 popover
옵션의 화살표를 이용한 이벤트 처리를 구현되지 않았습니다.
포인터 및 마우스 이벤트만으로 키보드 사용자의 기능을 지원하지 않는 경우의 예시 입니다. 키보드로 항상 테스트를 한다면 문제가되는 부분을 쉽게 찾을수 있습니다.
복잡한 위젯이 안좋은 사용자 경험은 아닙니다. 복잡한 위젯이라도 HTML
을 이용하여 보다 쉽게 접근성을 지원할 수 있습니다.
여기서 우리는 ARIA Roles와 ARIA 상태및 속성에 대한 지식이 필요합니다. JSX
에서 완벽하게 지원되는 HTML
속성으로 접근성이 우수한 React 컴포넌트를 만들 수 있습니다.
스크린 리더기가 페이지에서 사용된 언어의 선택합니다.
현재 페이지 내용을 정확하게 설명하도록 <title>
를 설정한다면 사용자는 현재페이지 문맥을 알 수 있습니다.
React Document Title Component를 사용하여 설정가능합니다.
시력이 약한 사용자가 읽을 수 있도록 웹 사이트에서 읽을 수있는 텍스트의 색 대비가 충분한 지 확인하십시오.
웹 사이트의 모든 경우에 대한 적절한 색상 조합을 수동으로 계산하는 것이 지루할 수 있습니다. 이런경우Colorable
을 사용하여 접근 가능한 색상 팔레트 전체를 계산할 수 있습니다.
아래 언급된 aXe
와 WAVE
도구는 색상 대비 테스트를 포함하고 오류를 알려줍니다.
대비 테스트 기능에 다음 도구를 사용할 수 있습니다.
접근성을 제공하는 웹 어플리케이션을 만드는데 도움이되는 다양한 도구들이 있습니다.
가장 쉬운 방법은 전체 웹사이트를 키보드만을 사용하여 테스트하는 것입니다. 다음을 참고 하세요
Tab
, Shift + Tab
을 사용하여 검색 할 수 있습니다.Enter
를 사용하여 요소를 활성화 합니다.JSX
코드에서 접근성 기능을 확인할 수 있습니다. IDE
툴에서 JSX
코드에서 ARIA
역할과 state
, props
를 인지하여 인텔리 센스 검사 기능을 제공합니다. 관련된 다음도구를 사용할 수 있습니다.
eslint-plugin-jsx-a11y ESLint
용 플러그인, JSX
에서 접근성문제에 관련된 AST linting
피드백을 제공합니다. 많은 IDE
가 이런 결과를 코두 분석 및 코드 소스 창에 직접 통합할수 있도록 합니다.
React Create App은 subset rule로 이러한 플러그인을 갖고 있습니다. 더 많은 접근성 규칙을 사용하길 원한다면 프로젝트 루트에 다음과 같은 .eslintrc
파일을 만들 수 있습니다.
{
"extends": ["react-app", "plugin:jsx-a11y/recommended"],
"plugins": ["jsx-a11y"]
}
브라우저에서 웹 페이지의 접근성 검사를 할 수 있는 여러 도구가 있습니다. HTML 접근성만 테스트 할 수 있으므로 여기에 언급 된 다른 접근성 검사와 함께 사용하십시오.
Dequq Systems가 제공하는 aXe-core는 자동화된 어플리케이션 end-to-end 접근성 테스트를 수행합니다. 이 모듈은 Selenium
과 통합되어 있습니다.
접근성 앤진 또는 aXe
는 ax-core
를 기반으로 만들어진 접근성 검사 브라우저 확장도구 입니다.
또한 react-ax 모듈을 사용하여 개발 및 디버깅 하는동안 접근성 결과를 콘솔에 직접 노출할 수 있습니다.
웹 접근성 평가도구는 또 다른 접근성 브라우저 확장 도구 입니다.
접근성 트리는 스크린 리더기와 같이 보조 기술에 노출되어야하는 모든 DOM 요소에 대한 접근 가능한 객체를 포함하는 DOM 트리의 subset
입니다.
일부 브라우저에서 접근성 트리의 각 요소에 대한 접근성 정보를 쉽게 볼 수 있습니다.
스크린 리더를 사용한 테스트는 접근성 테스트의 일부를 구성해야합니다.
브라우저 / 스크린 리더 조합은 중요합니다. 선택한 스크린 리더에 가장 적합한 브라우저에서 응용 프로그램을 테스트하는 것이 좋습니다.
NonVisual Desktop Access 또는 NVDA
는 널리 사용되는 오픈 소스 Windows
스크린 리더기 입니다.
NVDA를 사용하는 방법에 대한 다음 가이드를 참조하십시오
VoiceOver
는 Apple
기기의 통합 스크린 리더입니다.
VoiceOver
를 활성화및 사용하는 방법에 대한 다음 가이드를 참조하십시오.
Job Access Speech 또는 JAWS
를 사용하여 Windows
에서 자주 사용되는 스크린 리더입니다.
JAWS
사용 방법에 대해서는 다음 안내서를 참조하십시오.
Chrome
의 ChromeVox
ChromeVox 는 Chromebook
의 통합 스크린 리더이며 Chrome
용 확장 프로그램으로 제공 됩니다 .
ChromeVox
를 사용하는 가장 좋은 방법에 대한 다음 가이드를 참조하세요.
번역 감사합니다!