
많은 개발자들이 접근성(Accessibility)을 어렵고 복잡한 작업으로 여기며, 이를 위해 많은 추가 노력이나 전문 지식이 필요하다고 생각합니다.
하지만 사실 몇 가지 기본 원칙만 적용해도 사용자 경험(UX)을 크게 개선할 수 있습니다.
이 글에서는 프런트엔드 개발자가 컴포넌트를 개발할 때 반드시 고려해야 할 주요 접근성 원칙들을 자세히 다룹니다.
예제 코드와 그림 설명을 곁들여 실습에 바로 적용할 수 있도록 돕겠습니다.
접근성 개선은 단순히 보조 기술을 사용하는 사용자만을 위한 것이 아닙니다.
올바른 접근성 구현은 전체 사용자 경험(UX) 향상과 SEO 개선에도 긍정적인 영향을 미칩니다.
<div>에 onClick 핸들러를 사용하는 것은 피하고, <button>과 <a> 같은 네이티브 요소를 활용해야 합니다.
<select>, <input>, <textarea> 등 기본 HTML 요소는 접근성이 이미 고려된 상태로 제공됩니다.
ARIA 속성은 마지막 수단으로 신중하게 사용해야 하며, 잘못 적용하면 오히려 접근성을 해칠 수 있습니다.
aria-label과 aria-hidden 같은 속성은 올바르게 사용하면 큰 도움이 됩니다.
접근성은 나중에 해결하는 것이 아니라, 개발 초기부터 포함되어야 합니다.
기본적인 접근성 원칙을 지키는 것만으로도 사용자 경험과 웹사이트의 전반적인 품질을 향상시킬 수 있습니다.
접근성은 시맨틱 HTML에서 시작됩니다.
HTML5 요소를 의도된 용도에 맞게 사용하면 브라우저와 보조 기술(예: 스크린 리더)이 페이지 구조를 쉽게 이해할 수 있습니다.
게다가 SEO(검색 엔진 최적화)에도 긍정적인 영향을 미칩니다.
<button>과 <a>는 가장 중요한 인터랙티브 요소입니다.
이들은 기본적으로 키보드 지원과 스크린 리더에 시맨틱한 의미를 제공합니다.
안티 패턴: <div>에 onClick 사용
웹 애플리케이션에서 흔히 보이는 실수는 <div>에 onClick 핸들러를 붙여 버튼처럼 사용하는 경우입니다.
이는 절대 피해야 합니다.
<div>는 접근성 기능이 없어 키보드 탐색이나 스크린 리더에서 제대로 작동하지 않습니다.
<!-- 잘못된 예 -->
<div onClick={handleClick}>클릭하세요</div>
<!-- 올바른 예 -->
<button onClick={handleClick}>클릭하세요</button>
.custom-button {
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
}
<select>, <input>, <textarea> 같은 네이티브 요소는 기본 접근성을 갖추고 있습니다.
예를 들어, <select> 드롭다운은 키보드와 스크린 리더에서 추가 작업 없이도 잘 작동합니다.
커스텀 드롭다운을 만들고 싶을 때 접근성을 완벽히 구현하는 것은 어렵습니다.
이런 경우 react-select 같은 성숙한 라이브러리를 사용하는 것이 효율적입니다.
import Select from 'react-select';
const options = [
{ value: 'react', label: 'React' },
{ value: 'vue', label: 'Vue' },
];
function MyComponent() {
return <Select options={options} />;
}
폼은 사용자와의 상호작용에서 핵심적인 역할을 합니다.
접근성을 높이기 위해 몇 가지 간단한 규칙을 따르세요.
모든 폼 필드는 <form> 안에 포함되어야 하며, onSubmit 핸들러와 제출 버튼을 갖추는 것이 좋습니다.
이는 Enter 키로 제출하거나 모바일 화면 키보드에서 필드 간 이동을 가능하게 합니다.
<form onSubmit={handleSubmit}>
<label htmlFor="name">이름:</label>
<input type="text" id="name" name="name" />
<button type="submit">제출</button>
</form>
모든 입력 필드에는 <label>이 있어야 하며, htmlFor 속성으로 입력과 연결하세요.
암시적 연결(라벨 안에 입력을 감싸는 방식)은 일부 스크린 리더에서 제대로 지원되지 않을 수 있으니 주의하세요.
// 추천
<label htmlFor="email">이메일:</label>
<input type="email" id="email" />
// 비추천 (일부 스크린 리더에서 문제 발생 가능)
<label>이메일: <input type="email" /></label>
React에서는 useId 훅을 사용해 ID 충돌을 방지할 수 있습니다.
import { useId } from 'react';
function FormField() {
const id = useId();
return (
<>
<label htmlFor={id}>이름:</label>
<input type="text" id={id} />
</>
);
}
플레이스홀더는 라벨을 대체할 수 없습니다.
입력이 시작되면 사라지고, 대비가 낮아 읽기 어려울 수 있습니다.
<!-- 잘못된 예 -->
<input type="text" placeholder="이름" />
<!-- 올바른 예 -->
<label for="name">이름:</label>
<input type="text" id="name" placeholder="홍길동" />
키보드 탐색은 접근성의 핵심입니다.
사용자가 Tab 키로 논리적 순서대로 이동하고, Enter 키로 동작을 실행할 수 있어야 합니다.
포커스 표시기를 절대 비활성화하지 마세요.
:focus-visible 선택자를 사용하면 마우스 사용자에게는 표시기를 숨기고, 키보드 사용자에게만 보이게 할 수 있습니다.
button:focus-visible {
outline: 2px solid #007bff;
outline-offset: 2px;
}
모달은 흔히 사용되지만 접근성 문제가 많습니다.
<dialog> 요소를 활용하면 쉽게 해결할 수 있습니다.
function Modal({ isOpen, onClose }) {
const dialogRef = useRef(null);
useEffect(() => {
if (isOpen) dialogRef.current.showModal();
else dialogRef.current.close();
}, [isOpen]);
return (
<dialog ref={dialogRef}>
<p>모달 내용</p>
<button onClick={onClose}>닫기</button>
</dialog>
);
}
<dialog>를 사용하지 않는 경우
import FocusLock from 'react-focus-lock';
function CustomModal({ isOpen, onClose }) {
if (!isOpen) return null;
return (
<FocusLock>
<div role="dialog" aria-label="커스텀 모달">
<p>모달 내용</p>
<button onClick={onClose}>닫기</button>
</div>
</FocusLock>
);
}
>img< 태그에는 반드시 alt 속성을 추가하세요.
장식용 이미지는 alt=""로 설정합니다.
<img src="cat.jpg" alt="검은 고양이가 나무 위에 앉아 있음" />
<img src="deco-border.png" alt="" />
버튼과 링크는 충분한 크기와 패딩을 가져야 합니다.
.button {
padding: 12px 24px;
}
prefers-reduced-motion을 존중하세요.
@media (prefers-reduced-motion: reduce) {
.slide-in {
animation: none;
}
}
em과 rem 단위를 사용해 사용자 설정을 반영하세요.
.container {
font-size: 1rem;
padding: 1em;
max-width: 50em;
}
ARIA는 시맨틱 HTML로 해결되지 않을 때 사용하세요.
<button aria-label="검색">
<SearchIcon />
</button>
<div>React <ReactLogo aria-hidden="true" /></div>
접근성은 개발 과정의 일부로 처음부터 고려해야 합니다.
위 원칙들은 보조 기술 사용자뿐 아니라 모든 사용자의 경험을 개선하며, SEO에도 긍정적입니다.