HTML, CSS

웹 접근성 ✅ 키보드 네비게이션 (Tab, Focus, Role, ARIA)

jonbeo 2025. 12. 1. 11:07
반응형

 

 

사용자는 마우스뿐 아니라 키보드(Tab, Enter, Space),
심지어 스크린리더로도 웹사이트를 탐색합니다.

 

하지만 HTML 구조가 잘못되어 있거나,
포커스가 사라지는 UX를 제공한다면 접근성 점수는 0점 😭

 

이번 포스팅에서는 실무에서 자주 쓰이는
키보드 네비게이션 UX 설계 원칙과 실무 예제를 정리합니다.


⌨️ 1. Tab 키 순서 제어

모든 인터랙티브 요소는 기본적으로 Tab 키로 접근 가능합니다.

 
<button>로그인</button>
<a href="#">회원가입</a>
<input type="text" placeholder="이메일 입력" />

 

📌 Tab 순서는 HTML 구조 순서에 따릅니다.
따라서 DOM 순서 = 시각적 순서로 유지하는 것이 중요합니다.


⚙️ tabindex 속성

 
<div tabindex="0">포커스 가능</div>
<div tabindex="-1">프로그램만 포커스 가능</div>
설명
0 Tab 순서에 포함됨
-1 Tab으로는 접근 불가 (스크립트로만 접근)

📌 tabindex="0"커스텀 UI 요소(예: div 버튼) 를 포커스 가능하게 만듭니다.


🎯 2. Focus 스타일 명확하게 제공하기

사용자는 포커스가 어디 있는지를 시각적으로 인식할 수 있어야 합니다.

 
:focus {
  outline: 3px solid #00bcd4;
  outline-offset: 2px;
}

 

outline 제거 금지!
outline: none;은 접근성 파괴의 대표 사례입니다 ⚠️

 

📌 디자인적으로 부담된다면 :focus-visible로 조절 가능:

 
:focus-visible {
  outline: 3px solid #1e88e5;
}

🧩 3. 스킵 네비게이션(Skip Navigation)

키보드 사용자에게 본문으로 바로가기 링크를 제공해야 합니다.

 
<a href="#main" class="skip-link">본문 바로가기</a>

<header>...</header>
<main id="main">...</main>
.skip-link {
  position: absolute;
  top: -50px;
  left: 0;
  background: #333;
  color: #fff;
  padding: 8px;
}

.skip-link:focus {
  top: 0;
}

 

📌 Tab으로 접근 시 화면 상단에 나타나도록 설계합니다.


🧠 4. ARIA 속성으로 의미 강화

ARIA(Attribute for Accessible Rich Internet Applications)는
요소의 역할(role), 상태(state), 이름(name) 을 보조기기에 전달합니다.

 
<button aria-pressed="true">즐겨찾기</button>
<div role="dialog" aria-labelledby="dialog-title" aria-modal="true">
  <h2 id="dialog-title">설정창</h2>
</div>

 

📌 자주 쓰는 ARIA 속성

속성 설명
aria-label 대체 텍스트 제공
aria-expanded 메뉴 열림/닫힘 상태 표시
aria-hidden 보조기기에 숨김 처리
role="button" div를 버튼처럼 인식시킴

🧭 5. 실무 예제 – 접근성 좋은 드롭다운 메뉴

 
<button aria-expanded="false" aria-controls="menu" id="menuButton">
  메뉴 열기
</button>
<ul id="menu" role="menu" hidden>
  <li role="menuitem" tabindex="0">홈</li>
  <li role="menuitem" tabindex="0">서비스</li>
  <li role="menuitem" tabindex="0">고객센터</li>
</ul>
const btn = document.getElementById("menuButton");
const menu = document.getElementById("menu");

btn.addEventListener("click", () => {
  const expanded = btn.getAttribute("aria-expanded") === "true";
  btn.setAttribute("aria-expanded", !expanded);
  menu.hidden = expanded;
});

 

📌 Tab, Enter, Esc 키로 완전 제어 가능
📌 스크린리더도 열림/닫힘 상태를 정확히 인식


⚡ 6. 실무 체크리스트

outline 제거 금지
tabindex 올바르게 설정
aria-expanded, aria-label 적극 사용
✅ Skip Navigation 반드시 포함
키보드만으로 모든 인터랙션 가능해야 함


🧠 7. 접근성 테스트 툴 추천

  • WAVEhttps://wave.webaim.org
  • axe DevTools (Chrome 확장 프로그램)
  • VoiceOver / NVDA – 스크린리더 테스트

📌 실제 키보드로만 사이트 탐색해보는 게 제일 확실한 테스트입니다.


📝 마무리 정리

  • 키보드 네비게이션은 접근성의 핵심
  • tabindex, aria, :focus만 제대로 써도 UX 10배 개선
  • 모든 사용자가 “포커스를 잃지 않게” 만드는 게 진짜 웹 접근성입니다 ✨
반응형