Files
game-fe-agent/skills/verify-a11y/SKILL.md

4.0 KiB

name, description
name description
verify-a11y Vue 3 / HTML 코드를 WCAG 2.1 AA 기준으로 자동 감사하고 ARIA 레이블 누락, 키보드 포커스 순서, 색상 대비 비율 등의 문제와 코드 레벨 개선 방안을 제시합니다. 다음 상황에서 반드시 사용하세요: - "접근성 검증해줘", "WCAG 체크해줘", "a11y 확인해줘" - ARIA 속성이 빠진 것 같을 때 - QA 전 접근성 관련 반려를 사전에 방지하고 싶을 때

접근성 검증 (verify-a11y)

Vue 3 / HTML → WCAG 2.1 AA 자동 감사 → 코드 레벨 개선 방안 리포트.

언제 사용하는가

  • 마크업 완료 후 접근성 기준 충족 여부를 확인할 때
  • 스크린 리더 사용자를 위한 ARIA 적용이 필요할 때
  • 키보드 전용 사용자 지원이 필요할 때

검사 기준: WCAG 2.1 AA

원칙 핵심 항목
인식 가능 이미지 대체 텍스트, 색상 대비 비율, 캡션
운용 가능 키보드 접근성, 포커스 순서, 충분한 시간
이해 가능 레이블, 오류 식별, 일관된 네비게이션
견고성 유효한 HTML, ARIA 역할

작업 순서

Phase 1: 코드 수집

  1. 검증 대상 파일을 읽는다. (.vue, .html, 템플릿 코드)
  2. 검증 범위가 넓으면 화면 단위로 분리해 진행한다.

Phase 2: 체크리스트 점검

이미지 & 미디어

  • 의미 있는 <img>: alt 텍스트 존재
  • 장식용 <img>: alt=""
  • <video>: 자막(captions) 또는 스크립트 제공

색상 대비

  • 일반 텍스트: 대비 비율 4.5:1 이상
  • 대형 텍스트 (18px+ 또는 14px+ bold): 3:1 이상
  • 아이콘/그래픽 UI: 3:1 이상

키보드 접근성

  • 모든 인터랙션 요소가 키보드로 접근 가능
  • 포커스 순서가 시각적 레이아웃과 일치
  • 포커스 링(outline) 가시성 확보 (:focus-visible)
  • 모달/드롭다운 열릴 때 포커스 이동, 닫힐 때 원래 요소로 복귀

ARIA 적용

  • <button> 아이콘 전용: aria-label 또는 aria-labelledby
  • 모달: role="dialog", aria-modal="true", aria-labelledby
  • 폼 에러: aria-describedby → 에러 메시지 연결
  • 로딩 영역: aria-live="polite" 또는 aria-busy="true"
  • 탭 UI: role="tablist", role="tab", role="tabpanel", aria-selected
  • 아코디언: aria-expanded, aria-controls
  • 드롭다운 메뉴: aria-haspopup, aria-expanded

  • 모든 입력 필드에 연결된 <label> 존재
  • 필수 필드: aria-required="true" 또는 required
  • 에러 메시지: role="alert" 또는 aria-live="assertive"

제목 계층

  • h1h2h3 순서 준수 (건너뛰기 없음)
  • 페이지에 h1 1개만 존재

랜드마크

  • <header>, <nav>, <main>, <footer> 적절히 사용
  • 여러 <nav>가 있으면 aria-label로 구분

Phase 3: 개선 방안 코드 제시

<!-- Before: 아이콘 버튼 접근성 없음 -->
<button @click="close">
  <IconClose />
</button>

<!-- After: aria-label 추가 -->
<button @click="close" aria-label="닫기">
  <IconClose aria-hidden="true" />
</button>
<!-- Before:  에러 접근성 없음 -->
<input type="email" />
<p class="text-red-500">올바른 이메일을 입력하세요</p>

<!-- After -->
<input
  type="email"
  :aria-describedby="hasError ? 'email-error' : undefined"
  :aria-invalid="hasError"
/>
<p v-if="hasError" id="email-error" role="alert">
  올바른 이메일을 입력하세요
</p>

출력 형식

## 접근성 검증 리포트: <파일명>

### 🚨 Critical — WCAG 위반 (N건)
- [라인 NN] 문제 설명 + 수정 코드

### ⚠️ Warning — 개선 권장 (N건)
- [라인 NN] 문제 설명 + 수정 방향

### 💡 Info — 선택 개선 (N건)
- [라인 NN] 개선 사항

### ✅ 적절히 처리된 항목
- ARIA 레이블 적용됨, 색상 대비 충족 등