fe-a11y

📁 ingpdw/pdw-fe-dev-tool 📅 6 days ago
1
总安装量
1
周安装量
#42620
全站排名
安装命令
npx skills add https://github.com/ingpdw/pdw-fe-dev-tool --skill fe-a11y

Agent 安装分布

mcpjam 1
claude-code 1
replit 1
junie 1
zencoder 1

Skill 文档

FE Accessibility Audit

$ARGUMENTS로 전달된 파일의 접근성을 WCAG 2.1 AA 기준으로 검사한다.

검사 절차

  1. 대상 파일 읽기: 컴포넌트 코드를 분석한다
  2. 체크리스트 기반 검사: 8개 카테고리에 대해 검사한다
  3. 리포트 생성: 위반 사항과 수정 코드를 제시한다

검사 체크리스트

1. 시맨틱 HTML

  • <div>/<span> 남용 대신 적절한 시맨틱 태그 사용
    • <nav>, <main>, <aside>, <header>, <footer>, <section>, <article>
    • <button> (클릭 가능 요소), <a> (네비게이션)
    • <ul>/<ol> (목록), <table> (표형 데이터)
  • 헤딩 계층 순서 (h1 → h2 → h3, 건너뛰기 금지)
  • <img>, <svg>에 대체 텍스트
// Bad
<div onClick={handleClick}>Submit</div>

// Good
<button onClick={handleClick}>Submit</button>

2. ARIA 속성

  • 인터랙티브 커스텀 위젯에 적절한 role + ARIA 속성
  • aria-label, aria-labelledby — 시각적 레이블이 없는 요소
  • aria-describedby — 추가 설명이 필요한 요소
  • aria-expanded, aria-haspopup — 드롭다운/모달
  • aria-live — 동적 콘텐츠 업데이트 알림
  • aria-hidden="true" — 장식용 요소
// 토스트 알림
<div role="alert" aria-live="polite">
  {message}
</div>

// 아이콘 버튼
<button aria-label="Close dialog">
  <XIcon aria-hidden="true" />
</button>

3. 키보드 네비게이션

  • 모든 인터랙티브 요소가 Tab으로 접근 가능
  • 커스텀 위젯에 키보드 핸들러 (Enter, Space, Escape, 화살표키)
  • 포커스 트랩 — 모달/다이얼로그 내 포커스 순환
  • Skip navigation 링크 (메인 콘텐츠로 바로 이동)
  • 논리적인 탭 순서 (tabIndex 양수값 사용 금지)
// 모달 포커스 트랩 (shadcn/ui Dialog는 자동 지원)
<Dialog>
  <DialogContent>
    {/* Tab 키가 이 안에서만 순환 */}
  </DialogContent>
</Dialog>

4. 색상 & 대비

  • 텍스트 대비율 최소 4.5:1 (일반), 3:1 (큰 텍스트 18px+)
  • 색상만으로 정보를 전달하지 않음 (아이콘, 텍스트 병행)
  • 다크 모드에서도 대비율 충족
  • 포커스 표시 (outline) 제거 금지 — focus-visible 사용
// Bad — 색상만으로 상태 표현
<span className={isError ? "text-red-500" : "text-green-500"}>
  {status}
</span>

// Good — 아이콘 + 텍스트 병행
<span className={isError ? "text-red-500" : "text-green-500"}>
  {isError ? <AlertIcon aria-hidden="true" /> : <CheckIcon aria-hidden="true" />}
  {isError ? "Error: " : "Success: "}{status}
</span>

5. 폼 접근성

  • <label> + htmlFor로 입력 필드와 연결
  • 에러 메시지를 aria-describedby로 연결
  • 필수 필드에 aria-required="true" 또는 required
  • 자동완성: autoComplete 속성 적절히 설정
  • 유효성 검사 결과를 스크린리더에 전달
// shadcn/ui Form은 자동으로 접근성 처리
<FormField
  control={form.control}
  name="email"
  render={({ field }) => (
    <FormItem>
      <FormLabel>Email</FormLabel>
      <FormControl>
        <Input {...field} autoComplete="email" />
      </FormControl>
      <FormDescription>We'll never share your email.</FormDescription>
      <FormMessage /> {/* aria-describedby 자동 연결 */}
    </FormItem>
  )}
/>

6. 이미지 & 미디어

  • 정보를 전달하는 이미지: 의미 있는 alt 텍스트
  • 장식용 이미지: alt="" 또는 aria-hidden="true"
  • 복잡한 이미지 (차트, 그래프): 상세 설명 제공
  • Next.js <Image> 컴포넌트에 alt 필수
// 정보 전달 이미지
<Image src="/chart.png" alt="2024년 매출 추이: 1분기 100억, 2분기 150억" />

// 장식용 이미지
<Image src="/bg-pattern.png" alt="" aria-hidden="true" />

7. 동적 콘텐츠

  • 로딩 상태: aria-busy="true", 로딩 안내 텍스트
  • 페이지 전환: 포커스를 새 콘텐츠로 이동
  • 무한 스크롤: 대안 네비게이션 제공 (페이지네이션)
  • 토스트/알림: role="alert" 또는 aria-live="polite"

8. shadcn/ui 접근성 패턴

shadcn/ui는 Radix UI 기반으로 대부분의 접근성이 내장되어 있지만, 확인해야 할 사항:

  • Dialog: DialogTitle + DialogDescription 필수
  • DropdownMenu: 트리거 버튼에 명확한 레이블
  • Toast: aria-live 영역 설정
  • Tooltip: 키보드 포커스로 표시 가능
  • Tabs: 화살표 키 네비게이션 동작 확인
  • Sheet: 포커스 트랩 + ESC로 닫기

리포트 형식

# Accessibility Audit: [파일명]

## 요약
- WCAG 2.1 AA 준수율: [N]%
- 위반: N개 (Critical: N, Major: N, Minor: N)

## Critical (WCAG A 위반)
### [A1] 이슈 제목
- **기준**: WCAG [번호] [이름]
- **위치**: `파일:라인`
- **문제**: 설명
- **수정안**: 코드

## Major (WCAG AA 위반)
...

## Minor (개선 권장)
...

## 통과 항목
- ...

실행 규칙

  1. 인자가 없으면 사용자에게 검사 대상을 질문한다
  2. shadcn/ui 컴포넌트 사용 여부를 확인하고, 내장 접근성 기능을 고려한다
  3. 수정안에는 항상 구체적인 코드를 포함한다
  4. 자동 테스트로 잡을 수 없는 수동 검증 항목도 안내한다