Compit
소개문의요금제개인정보처리방침이용약관환불규정

온드(ONDE) | 대표: 노승현 | 사업자등록번호: 778-22-02215

서울특별시 광진구 긴고랑로 133-1, 401호(중곡동, 백림주택) | 전화: 010-7794-3962

© 2026 Compit. All rights reserved.
COMPIT
챌린지연습장쇼케이스학습블로그랭킹가이드보안기초
챌린지연습장쇼케이스학습블로그랭킹가이드보안기초
홈/블로그/웹 접근성(A11y) 기초 — 모두를 위한 웹 만들기
접근성

웹 접근성(A11y) 기초 — 모두를 위한 웹 만들기

시맨틱 HTML, ARIA 속성, 키보드 네비게이션, 색상 대비 등 웹 접근성의 핵심 원칙과 실전 적용법.

2026-02-25·⏱ 10분
접근성A11yARIAHTML

웹 접근성이란?

웹 접근성(Web Accessibility, 줄여서 A11y)은 장애 유무와 관계없이 누구나 웹 콘텐츠를 이용할 수 있도록 만드는 것입니다.

전 세계 인구의 약 15%가 어떤 형태로든 장애를 가지고 있습니다. 시각, 청각, 운동 능력, 인지 능력 등 다양한 영역에서 웹 사용에 어려움을 겪는 사용자들이 있습니다.

접근성은 윤리적인 이유뿐 아니라 실용적인 이유도 있습니다:

  • 법적 요구: 한국의 장애인차별금지법, 미국의 ADA 등
  • SEO 개선: 시맨틱 HTML은 검색엔진에도 좋습니다
  • UX 향상: 접근성 좋은 사이트는 모든 사용자에게 편합니다
  • 시장 확대: 더 많은 사용자가 서비스를 이용할 수 있습니다

시맨틱 HTML이 기본

접근성의 80%는 올바른 HTML을 쓰는 것만으로 해결됩니다.

<!-- 나쁜 예: div를 버튼으로 사용 -->
<div class="btn" onclick="submit()">제출</div>

<!-- 좋은 예: button 태그 사용 -->
<button type="submit">제출</button>

<button>은 자동으로:

  • 키보드로 포커스 가능 (Tab)
  • Enter/Space로 클릭 가능
  • 스크린 리더가 "버튼"이라고 읽어줌

<div>는 이 기능이 전혀 없어서, 하나하나 직접 구현해야 합니다.

올바른 태그 선택

용도올바른 태그잘못된 사용
클릭 가능한 요소<button><div onclick>
페이지 이동<a href><span onclick>
입력 필드<input> + <label><div contenteditable>
네비게이션<nav><div class="nav">
제목<h1>~<h6><div class="title">

이미지와 대체 텍스트

<!-- 정보를 담은 이미지: 의미 있는 alt -->
<img src="chart.png" alt="2026년 프론트엔드 프레임워크 사용률 — React 42%, Vue 18%">

<!-- 장식용 이미지: 빈 alt -->
<img src="decoration.svg" alt="">

<!-- 복잡한 이미지: 상세 설명 -->
<figure>
  <img src="architecture.png" alt="시스템 아키텍처 다이어그램">
  <figcaption>
    클라이언트 → API Gateway → 마이크로서비스 → 데이터베이스 구조
  </figcaption>
</figure>

alt 텍스트 규칙:

  • 이미지가 전달하는 정보를 적으세요 ("사진" "이미지" 같은 말은 불필요)
  • 장식용이면 alt=""로 비워두세요 (스크린 리더가 건너뜀)
  • alt를 아예 생략하면 안 됩니다 (파일명을 읽어버림)

키보드 네비게이션

마우스를 사용할 수 없는 사용자는 키보드만으로 사이트를 탐색합니다.

필수 키보드 동작

키동작
Tab다음 포커스 요소로 이동
Shift + Tab이전 포커스로 이동
Enter / Space클릭/선택
Escape모달/드롭다운 닫기
화살표 키탭, 메뉴, 라디오 버튼 내 이동

포커스 스타일

/* 절대 하지 마세요! */
*:focus { outline: none; }

/* 대신 예쁜 포커스 스타일을 만드세요 */
:focus-visible {
  outline: 2px solid #2dd4bf;
  outline-offset: 2px;
  border-radius: 4px;
}

:focus-visible은 키보드로 포커스할 때만 표시되고, 마우스 클릭 시에는 표시되지 않습니다.

포커스 트랩 (모달)

모달이 열렸을 때 Tab이 모달 밖으로 나가면 안 됩니다.

function trapFocus(modal) {
  const focusable = modal.querySelectorAll(
    'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
  );
  const first = focusable[0];
  const last = focusable[focusable.length - 1];

  modal.addEventListener('keydown', (e) => {
    if (e.key !== 'Tab') return;

    if (e.shiftKey && document.activeElement === first) {
      e.preventDefault();
      last.focus();
    } else if (!e.shiftKey && document.activeElement === last) {
      e.preventDefault();
      first.focus();
    }
  });
}

ARIA 속성

ARIA(Accessible Rich Internet Applications)는 HTML만으로 표현하기 어려운 접근성 정보를 추가합니다.

원칙: 시맨틱 HTML로 해결 가능하면 ARIA를 쓰지 마세요. ARIA는 보충 수단입니다.

<!-- 아이콘 버튼: 텍스트가 없으므로 aria-label 필수 -->
<button aria-label="메뉴 열기">
  <svg>...</svg>
</button>

<!-- 토글 상태 -->
<button aria-expanded="false" aria-controls="menu">메뉴</button>
<div id="menu" hidden>...</div>

<!-- 로딩 상태 -->
<div aria-live="polite" aria-busy="true">
  로딩 중...
</div>

<!-- 필수 입력 -->
<input type="email" aria-required="true" aria-invalid="false">

자주 쓰는 ARIA 속성

속성용도
aria-label보이지 않는 텍스트 레이블
aria-expanded열림/닫힘 상태
aria-hidden="true"스크린 리더에서 숨김
aria-live동적 변경 알림
aria-required필수 입력
aria-invalid유효성 오류
role요소의 역할 지정

색상 대비

텍스트와 배경의 대비비(contrast ratio)가 충분해야 합니다.

WCAG 기준:

  • 일반 텍스트: 최소 4.5:1
  • 큰 텍스트 (18px bold 또는 24px 이상): 최소 3:1
  • UI 요소 (버튼 테두리 등): 최소 3:1
/* 대비비 부족 (2.1:1) */
.text-low { color: #94a3b8; background: #64748b; }

/* 충분한 대비비 (7.4:1) */
.text-good { color: #e2e8f0; background: #1a2435; }

색상만으로 정보를 전달하지 마세요. 에러 상태를 빨간색으로만 표시하면 색각이상 사용자는 알 수 없습니다. 아이콘이나 텍스트를 함께 사용하세요.

폼 접근성

<!-- label과 input 연결 (필수!) -->
<label for="email">이메일</label>
<input id="email" type="email" required>

<!-- 에러 메시지 연결 -->
<input id="password" type="password" aria-describedby="pw-error">
<p id="pw-error" role="alert">비밀번호는 8자 이상이어야 합니다</p>

<!-- 필드 그룹 -->
<fieldset>
  <legend>결제 방법 선택</legend>
  <label><input type="radio" name="payment" value="card"> 카드</label>
  <label><input type="radio" name="payment" value="bank"> 계좌이체</label>
</fieldset>

접근성 테스트

  1. 키보드만으로 사이트 탐색 — Tab, Enter, Escape로 모든 기능을 사용할 수 있는지
  2. 크롬 Lighthouse — 개발자 도구 > Lighthouse > Accessibility
  3. axe DevTools — 크롬 확장 프로그램, 상세한 접근성 검사
  4. 스크린 리더 — NVDA(Windows, 무료), VoiceOver(Mac, 내장)

정리

웹 접근성 체크리스트:

  1. 시맨틱 HTML 사용 (button, nav, main 등)
  2. 모든 이미지에 alt 텍스트
  3. 키보드로 모든 기능 사용 가능
  4. 포커스 스타일 보이게 유지
  5. 충분한 색상 대비
  6. label과 input 연결
  7. ARIA는 보충 수단으로만

이 원칙만 지키면 접근성 점수가 크게 올라갑니다.

관련 챌린지로 연습하기

기본 버튼
Lv.1 · 버튼
가격표 카드
Lv.3 · 카드
알림 카드
Lv.2 · 카드
← 블로그 목록으로