Communitygithub.com

chandra-pangea/plugin-ax-ai-ts-full-stack

대화형 컴포넌트, 폼, 대화상자, 페이지를 구축하거나 유지보수할 때 사용합니다. WCAG 2.1 AA를 준수하도록 합니다 — 의미론적 HTML 우선, 의미론이 부족한 경우에만 ARIA 사용, 전체 키보드 동작, 가시적 포커스, 대비 비율, 레이블이 있는 입력, 모션 환경 설정 준수 등이 포함됩니다. 모달 추가, 드롭다운 구축, 폼 유효성 검사, 키보드 탐색, 스크린 리더, 대비, 접근성 감사 시 트리거됩니다.

plugin-ax-ai-ts-full-stack란 무엇인가요?

이 스킬은 프론트엔드 컴포넌트와 페이지가 WCAG 2.1 Level AA 접근성 기준을 충족하도록 보장합니다. 의미론적 HTML을 최우선으로 사용하고, HTML로 해결할 수 없는 경우에만 ARIA 속성을 추가하는 '의미론적 HTML 우선' 접근 방식을 강조합니다. 모든 대화형 요소는 키보드로 접근 가능해야 하며, 포커스가 항상 표시되어야 하고, 색상과 대비에 대한 엄격한 기준을 적용합니다. 또한 prefers-reduced-motion을 존중하고, 이미지에 대체 텍스트를 제공하며, 폼 입력에 오류 메시지를 연결하는 등의 세부 규칙을 포함합니다. 이 스킬은 Claude Code, Cursor 등과 같은 AI 에이전트와 함께 사용하도록 설계되었으며, STACK-PROFILE.md 파일을 기반으로 프로젝트별 설정을 해결하고, 참조 컴포넌트 패턴(버튼, 폼 입력, 대화상자, 리스트박스, 스킵 링크)을 제공합니다. 접근성 테스트는 키보드, 스크린 리더, 색상, 모션, 자동화된 스캔(Axe-in-Playwright)을 포함한 체크리스트를 통해 수행됩니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/chandra-pangea/plugin-ax-ai-ts-full-stack/tree/HEAD/claude/skills/frontend-accessibility

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

프론트엔드 접근성

<ui-packages-dir> 디렉토리의 컴포넌트와 <web-dir>/src/ 디렉토리의 페이지에 적용됩니다. 목표는 WCAG 2.1 Level AA이며, 이는 최소 기준이지 목표가 아닙니다.

프로젝트 규칙 확인

꺾쇠 괄호 안의 값은 프로젝트의 스택 프로파일에서 가져옵니다. 다음 순서로 확인하세요.

  1. 리포지토리 루트에 있는 STACK-PROFILE.md를 읽고 값을 그대로 사용합니다.
  2. 파일이 없거나 키가 누락된 경우, 리포지토리에서 추론합니다 — css-strategy와 ui-framework는 웹 애플리케이션의 종속성에서 가져옵니다.
  3. 여전히 해결되지 않은 경우, 리포지토리에 이미 존재하는 지배적인 규칙을 따릅니다.
  4. 리포지토리가 비어 있는 경우에만 이 스킬의 기본값을 사용합니다. 그런 다음 선택한 값을 STACK-PROFILE.md에 기록합니다.

리포지토리에 이미 규칙이 있는 경우 새로운 규칙을 절대 만들지 마세요.


엄격한 규칙

1. 의미론적 HTML 우선

  • <button>은 동작, <a>는 탐색에 사용합니다. <div>에 클릭 핸들러를 절대 사용하지 마세요.
  • 제목 수준은 건너뛰지 않고 내려갑니다.
  • 모든 폼 필드에 <label>을 사용하고 htmlFor로 연결합니다.
  • 그룹화된 컨트롤에는 <fieldset>과 <legend>를 사용합니다.
  • 모든 페이지에 <nav>, <main>, <footer>, <aside>와 같은 랜드마크를 사용합니다.

2. HTML로 해결할 수 없는 경우에만 ARIA 사용

선호 순서는 의미론적 요소, 그다음 ARIA 속성, 마지막으로 사용자 정의 동작입니다. 이미 요소가 가지고 있는 의미를 덮어쓰기 위해 ARIA를 절대 사용하지 마세요. <div>에 role="button"을 사용하는 것은 <button>이 무료로 제공하는 것을 나쁘게 재구현하는 것입니다.

잘못된 ARIA는 없는 것보다 worse합니다. 잘못된 aria-label은 스크린 리더가 올바르게 계산했을 접근 가능한 이름을 조용히 대체합니다.

3. 키보드 동작은 필수

  • 모든 대화형 요소는 Tab 키로 접근 가능해야 합니다.
  • Tab 순서는 시각적 순서를 따릅니다.
  • 포커스는 항상 표시되어야 합니다. 대체 수단 없이 아웃라인을 제거하지 마세요.
  • Escape는 대화상자와 팝오버를 닫습니다. Enter와 Space는 컨트롤을 활성화합니다. 화살표 키는 복합 위젯 내에서 이동합니다.
  • 사용자 정의 위젯은 포커스를 명시적으로 관리합니다.

4. 색상과 대비

  • 일반 텍스트는 4.5:1, 큰 텍스트(18px 또는 14px 굵게)와 의미 있는 UI 경계는 3:1을 유지합니다.
  • 색상만으로 의미를 전달하지 마세요. 텍스트, 아이콘 또는 패턴과 함께 사용합니다.
  • 기본 테마뿐만 아니라 두 테마 모두 확인합니다.

5. 이미지와 미디어

  • 모든 이미지에 alt 속성이 있어야 합니다. 콘텐츠 이미지는 설명을, 장식 이미지는 alt=""를 사용합니다.
  • "이미지", "사진" 또는 파일 이름을 절대 사용하지 마세요.
  • 복잡한 이미지는 aria-describedby 또는 캡션을 통해 긴 설명을 제공합니다.
  • 동영상에는 자막이, 오디오에는 대본이 있어야 합니다.

6. 폼

  • 모든 입력에 레이블이 있어야 합니다.
  • 오류는 aria-describedby로 연결하고 role="alert"로 알립니다.
  • 유효하지 않은 필드는 aria-invalid로 표시합니다.
  • 필수 필드는 required 속성으로 표시합니다. 별표(*)를 표시하는 경우 그 의미가 어딘가에 텍스트로 명시되어야 합니다.
  • 제출 실패 시 포커스가 첫 번째 유효하지 않은 필드로 이동합니다.

7. 대상 크기

WCAG 2.1 AA에는 최소 대상 크기가 없습니다. (2.2 AA는 24×24 CSS px로 설정합니다. 44×44 수치는 2.1 AAA 및 플랫폼 HIG 규칙입니다.) 터치 표면의 기본 작업에 대해 44×44를 최소 기준으로 간주하고 다음과 같이 적용합니다.

  • 기본 및 파괴적 작업, 그리고 휴대폰에서 사용자가 손을 뻗는 모든 것: 44×44.
  • 조밀한 데스크톱 크롬(툴바, 테이블 행 작업, 컴팩트 폼 컨트롤)은 24×24까지 작아질 수 있습니다. 단, 대상이 다른 대상과 인접하지 않고 동등한 전체 크기 컨트롤이 다른 곳에 있어야 합니다.
  • 간격도 중요합니다. 32px 컨트롤에 각 측면에 6px의 빈 공간이 있으면 2.2 기준을 충족하지만, 이웃과 맞닿은 32px 컨트롤은 충족하지 않습니다.

공급업체 컴포넌트 라이브러리는 일반적으로 이 기준 미만으로 제공됩니다. — 기본 버튼 높이가 32 또는 36 CSS px인 것이 일반적입니다. 공급업체 파일을 직접 수정하여 해결하지 말고, 불일치를 기본적으로 허용 가능한 것으로 간주하지 마세요. <wrappers-pkg>에서 기본값을 높여 모든 소비자가 규격을 준수하는 크기를 상속받도록 하고, 조밀한 컨텍스트를 위한 명시적 옵트인으로 더 작은 크기를 유지하세요. 이렇게 하면 접근 가능한 선택이 생각하지 않고 얻는 기본값이 됩니다.

프로젝트에서 어떤 해결 방안을 취했는지 STACK-PROFILE.md에 기록하세요. 명시되지 않은 면제는 6개월마다 버그로 재발견됩니다.

8. 모션

  • prefers-reduced-motion을 존중합니다.
  • 자동 재생 콘텐츠에는 일시 중지 컨트롤이 있어야 합니다.
  • 초당 3회 이상 깜빡이지 않습니다.

9. 테스트는 작업의 일부입니다.

  • 키보드만으로 기능을 작동시켜 보세요.
  • 스크린 리더로 들어보세요. macOS에서는 VoiceOver, Windows에서는 NVDA를 사용합니다.
  • 엔드투엔드 스위트에서 자동화된 스캔을 실행하세요.

자동화 도구는 실제 문제의 약 1/3만 발견합니다. 이는 최소 기준이지 합격 기준이 아닙니다.


패턴

전체 구현은 references/component-patterns.md에 있습니다. 각 패턴이 보장하는 것은 다음과 같습니다.

  • 버튼 — 포커스 링이 키보드 사용자에게는 표시되지만 마우스 클릭 시에는 표시되지 않는(focus-visible) 의미론적 <button>, 모션 안전 전환, 아이콘 전용 사용을 위한 ariaLabel prop.
  • 폼 입력 — 오류 텍스트가 aria-describedby로 프로그래밍 방식으로 연결되고, role="alert"로 알려지며, aria-invalid로 표시된 레이블이 있는 입력; 필수 별표는 aria-hidden입니다.
  • 대화상자 — 네이티브 <dialog>를 showModal()과 함께 사용하여 무료 포커스 트래핑, Escape 처리, 비활성 배경 제공; 열릴 때 포커스가 안으로 이동하고 닫힐 때 트리거로 복원됩니다.
  • 리스트박스 — 로빙 화살표 키 탐색과 올바른 ARIA 연결(aria-activedescendant, role="listbox")을 갖춘 사용자 정의 선택; 네이티브 <select>가 적합하지 않을 때만 구축합니다.
  • 스킵 링크 — 키보드 사용자가 탐색을 건너뛸 수 있게 하며, 포커스될 때만 표시됨; 대상은 tabIndex={-1}을 가지므로 포커스가 실제로 그곳에 위치합니다.

WCAG 빠른 참조

원칙요구 사항실제 적용
지각 가능모든 감각으로 콘텐츠 이용 가능대체 텍스트, 자막, 색상 + 아이콘
작동 가능모든 것을 키보드로 접근 가능Tab 순서, Escape로 닫기, 포커스 표시
이해 가능예측 가능하고 명확하게 표현일관된 탐색, 평이한 언어
견고함보조 기술과 함께 작동유효한 HTML, 올바른 ARIA, 의미론적 요소
문제해결 방법
레이블이 없는 입력<label htmlFor> 추가
낮은 대비일반 텍스트 4.5:1, 큰 텍스트 3:1 충족
키보드 경로 없음실제 대화형 요소, 포커스 관리
대체 텍스트 누락설명, 또는 장식용이면 alt=""
색상만으로 의미 전달텍스트 또는 아이콘 추가
아이콘 전용 버튼aria-label 추가
깜빡이는 콘텐츠초당 3회 미만으로 유지

모션 환경 설정

순수 CSS로 축소 모션을 처리하세요. motion-safe:와 같은 유틸리티 클래스 변형은 모션이 허용될 때만 적용되므로, 축소 모션 쿼리 내부에 배치하면 절대 일치할 수 없는 규칙이 생성됩니다.

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

0에 가까운 값(none 대신)은 전환 종료 이벤트가 계속 발생하도록 하여, 이를 기다리는 컴포넌트가 멈추지 않도록 합니다.

컴포넌트별 제어를 위해, 애니메이션 유틸리티 자체에 motion-safe: 변형을 적용하세요. 위 버튼 예제의 motion-safe:transition-colors와 같이.

시각적으로 숨겨진 콘텐츠

대부분의 유틸리티 프레임워크는 이미 sr-only와 not-sr-only를 제공합니다. 그것들을 사용하고, 다시 정의하지 마세요. 프레임워크에 없다면 참조 구현이 references/component-patterns.md에 있습니다.


테스트 체크리스트

키보드

  • 모든 대화형 요소가 Tab으로 접근 가능
  • Tab 순서가 시각적 순서와 일치
  • 포커스가 항상 표시됨
  • Escape로 대화상자와 팝오버가 닫힘
  • 복합 위젯에서 화살표 키가 작동
  • 대화상자가 닫힐 때 포커스가 트리거로 돌아감

스크린 리더

  • 모든 콘텐츠에 접근 가능
  • 컨트롤의 목적이 주변 컨텍스트 없이 명확함
  • 레이블이 해당 필드와 함께 알려짐
  • role="alert"를 통해 오류가 알려짐
  • 랜드마크가 존재함
  • 장식 요소가 aria-hidden으로 숨겨짐

색상

  • 일반 텍스트 4.5:1, 큰 텍스트 및 UI 경계 3:1
  • 색상만으로 의미 전달하지 않음
  • 두 테마 모두 확인됨

모션

  • 축소 모션이 존중됨
  • 초당 3회 이상 깜빡이지 않음
  • 자동 재생 콘텐츠를 일시 중지 가능

자동화

스캔은 Playwright 스위트 내에서 실행됩니다. 자세한 내용은 frontend-testing을 참조하세요. Axe-in-Playwright 코드 조각은 references/component-patterns.md에 있습니다.

참조 문서

심층 분석참조
접근 가능한 컴포넌트 구현: 버튼, 폼 입력, 모달, 리스트박스, 스킵 링크references/component-patterns.md

관련 스킬

  • frontend-architecture — 컴포넌트 계층화 및 테마 설정
  • frontend-testing — 이러한 검사가 실행되는 곳
  • frontend-component-docs — 컴포넌트의 접근성 계약 문서화

관련 스킬