GitHub
FE-INTERVIEW

웹 접근성(a11y), 왜 신경 써야 하나요?

Updated On : 2025.09.07
Accessibility
Frontend
A11y

답변

접근성(a11y)은 누구나 웹을 불편 없이 사용할 수 있게 만드는 것을 의미합니다.

예를 들어 다음과 같은 사용자가 있습니다:

  • 시각 장애인: 화면 낭독기(스크린 리더) 사용
  • 마우스 사용이 불가능한 사용자: 키보드만 사용
  • 색각 이상 사용자: 특정 색상 구분 어려움

이런 사용자를 위해 WCAG(Web Content Accessibility Guidelines)을 기준으로 접근성을 고려합니다. WCAG의 핵심 4원칙은 다음과 같습니다:

  1. 볼 수 있게(Perceivable): 텍스트 크기, 색상 대비 확보
  2. 쓸 수 있게(Operable): 키보드 조작 가능
  3. 이해할 수 있게(Understandable): 명확한 라벨, 직관적 UI
  4. 튼튼하게(Robust): 다양한 브라우저·보조기기에서 호환

Q. 실무에서 접근성은 어떻게 적용할 수 있나요?

1. 시멘틱 태그 사용

  • 클릭 가능한 요소는 div 대신 button 또는 a 태그를 사용합니다.

2. 이미지에 대체 텍스트 달기

  • 시각 장애 사용자가 화면 낭독기로 이해할 수 있도록 alt 속성을 작성합니다.
  • 장식용 이미지 같은 경우에는 빈 텍스트로 남겨두셔도 됩니다.

3. 키보드 접근성 보장

  • Tab, Enter, Esc 키만으로 메뉴 열기·닫기 조작이 가능해야 합니다.

Q. label을 사용할 때 고려해야할 점은?

접근성을 확보하려면 모든 인터랙티브 요소(button, input, select 등)에 명확한 이름(Label)고유한 맥락(Context)을 제공해야 합니다.

예를 들어, 시각장애 사용자는 스크린 리더를 통해 요소의 이름을 듣고 그 기능을 이해합니다. 이때 이름이 없거나 모호하면 혼란이 생기므로 다음 원칙을 지켜야 합니다.

1. label 제공

  • 가장 권장되는 방법은 <label> 태그를 사용해 for 속성으로 요소와 연결하는 것입니다.
  • 디자인상 레이블을 표시할 수 없을 경우, aria-label 또는 aria-labelledby 속성을 사용해 보이지 않는 이름을 제공할 수 있습니다.
  • 버튼(<button>), 링크(<a>)처럼 내부 텍스트가 이미 이름 역할을 하는 경우에는 별도의 label 없이 텍스트 자체를 이름으로 활용할 수 있습니다.

2. 동일한 이름의 요소는 고유하게 구분

  • 예를 들어, 상품 목록의 모든 버튼이 "구매"라고만 되어 있다면, 스크린 리더 사용자는 어떤 상품의 구매 버튼인지 알 수 없습니다.
  • 이때는 aria-label="아이폰 15 구매"처럼 고유한 맥락을 포함해 구분 해야 합니다.

Q. 키보드 접근성 보장에 대해 구체적으로 말씀해주세요

접근성을 확보하려면 모든 사용자가 키보드만으로도 웹 페이지의 주요 기능을 문제없이 사용할 수 있어야 합니다.
이를 위해 다음 원칙을 지켜야 합니다.

1. 버튼은 반드시 시맨틱 요소 사용

  • 클릭 이벤트만 있는 <div> 대신 <button> 요소를 사용하면 자동으로 키보드 포커스(Tab)와 Enter/Space 키 이벤트가 지원됩니다.
  • 가짜 버튼(div + onClick)은 스크린 리더가 버튼으로 인식하지 않으므로 피해야 합니다.
<button onclick="handleClick()">저장</button>

2. 불가피하게 div를 쓸 경우 보완 방법

디자인 제한 등으로 div에 버튼 기능을 구현해야 한다면 다음 속성을 추가해야 합니다.

  • role="button": 스크린 리더에 버튼임을 알려줌
  • tabIndex="0": 키보드 포커스 가능하게 함
  • onKeyDown: Enter 와 같이 키로 실행 가능하게 처리

3. 폼 요소는 반드시 <form> 태그로 감싸기

사용자는 입력 후 Enter 키로 폼 제출이 되길 기대합니다. <form> 태그를 사용하면 자동으로 키보드 제출, 스크린 리더 탐색, 오류 안내 등 브라우저 기본 기능이 활성화됩니다.

<form aria-label="로그인" onsubmit="event.preventDefault();">
  <label for="id">아이디</label>
  <input id="id" name="id" type="text" />
  <label for="password">패스워드</label>
  <input id="password" name="password" type="password" />
  <button type="submit">로그인</button>
</form>
댑댑댑