접근성
시맨틱, 상호작용, 색상, 크기, 리플로, 모션, 검증에 접근성을 처음부터 반영해요.
접근성은 마무리 작업이 아니라 시스템 제약
시각, 색상, 정밀한 포인터 입력, 모션, 넓은 화면 없이도 기능을 쓸 방법부터 정한 뒤 시각 표현을 선택하세요. 네이티브 HTML과 Tinyrack 컴포넌트 규약에서 시작하고, HTML만으로 표현할 수 없는 정보에만 ARIA를 더하세요. 토큰은 올바른 결정을 일관되게 이어 주지만, 잘못된 구조를 접근 가능하게 바꾸지는 못해요.
WCAG 검사는 완성된 제품 흐름의 인수 조건으로 다루세요. 토큰이나 컴포넌트 하나로 페이지 전체가 기준을 충족한다고 볼 수는 없어요. 콘텐츠, 조합, 애플리케이션 상태, 보조 기술 동작을 함께 검증해야 해요.
시맨틱과 접근 가능한 이름
동작에 맞는 요소를 선택하세요. 동작에는 버튼, 이동에는 링크, 문서 구조에는 제목, 폼 컨트롤에는 레이블을 사용해요. 모든 상호작용 컨트롤의 이름은 결과를 설명해야 해요. 보이는 텍스트가 보통 가장 좋은 이름이에요. 아이콘만 있는 컨트롤에는 aria-label을 사용하고 장식 아이콘은 접근성 트리에서 숨기세요.
아이콘 버튼과 파운데이션 토큰이 사용 가능하도록 전역 스타일시트에 다음을 추가하세요.
@import "@tinyrack/ui/core.css";
@import "@tinyrack/ui/components/icon-button.css";
그 다음 아이콘 버튼을 렌더링해요.
import { TRIconButton } from '@tinyrack/ui/components/icon-button';
<TRIconButton aria-label="랙 상태 새로 고침">
<span aria-hidden="true">↻</span>
</TRIconButton>
도움말과 오류 문구를 해당 필드에 연결하세요. Tinyrack의 필드 가이드에서 레이블, 설명, 오류, 컨트롤 조합을 확인할 수 있어요. 필수 안내를 플레이스홀더나 툴팁에만 넣지 마세요.
키보드 조작과 보이는 포커스
모든 포인터 동작에는 키보드 경로가 필요해요. 메뉴, 탭, 라디오 그룹 같은 복합 위젯은 컴포넌트에 정리된 키 규약을 따르고 클릭 가능한 div로 다시 만들지 마세요. 포커스 순서는 읽는 흐름과 맞추고, 오버레이를 닫은 뒤 포커스를 되돌리며, 양수 tabIndex는 피하세요.
Tinyrack 컴포넌트는 공통 :focus-visible 표현에 --tinyrack-focus, --tinyrack-focus-width, --tinyrack-focus-offset을 사용해요. 컴포넌트를 꾸밀 때 이 포커스 표시를 유지하세요. 사용자 정의 상호작용 요소가 꼭 필요하다면 같은 시맨틱 토큰을 적용하세요.
포커스 위치는 컨트롤 경계에 맞춰요. 텍스트 입력, 텍스트 영역, Select 트리거처럼 필드 테두리가 있는 컨트롤은 2px 표시를 테두리 안쪽에 그려요. 테두리가 없거나 작은 선택 컨트롤과 독립적인 동작은 텍스트, 아이콘, 상태 표시를 가리지 않도록 외곽 포커스를 유지해요. 유효성 오류가 있는 필드는 같은 인셋 위치에 danger 테두리 색을 사용하고, 연결된 오류 문구로 문제를 함께 설명해요.
.rack-action:focus-visible {
outline: var(--tinyrack-focus-width) solid var(--tinyrack-focus);
outline-offset: var(--tinyrack-focus-offset);
}
Tinyrack은 이 표시를 키보드 포커스에만 그려요. 텍스트 필드는 포커스가 어떻게 들어왔든 :focus-visible에 매칭되기 때문에, 그대로 두면 마우스 클릭에도 Tab과 똑같은 링이 그려져요. WCAG가 요구하는 것은 키보드 포커스 표시이므로, 컴포넌트가 입력 방식을 추적해 문서 요소에 data-tr-focus-modality로 게시하고 컴포넌트 CSS가 그 속성을 읽어요.
입력 방식에 의존하는 컴포넌트는 마운트되어 있는 동안 추적기를 실행해요. 해당 컴포넌트 없이 스타일시트만 쓰거나 첫 컨트롤이 마운트되기 전부터 실행해야 한다면 직접 시작하세요.
import { TRFocusModalityProvider } from '@tinyrack/ui/providers/focus-modality';
export function App({ children }: { children: React.ReactNode }) {
return <TRFocusModalityProvider>{children}</TRFocusModalityProvider>;
}
추적기가 없으면 속성이 없는 상태가 되고, 포커스 표시는 포인터 포커스에도 그려져요. 표시를 숨기는 쪽이 아니라 접근성 동작을 유지하는 쪽으로 떨어져요.
대비와 색상 이외의 단서
--tinyrack-surface 위의 --tinyrack-text, --tinyrack-primary 위의 --tinyrack-on-primary, 서로 짝이 맞는 상태 텍스트·표면·테두리 역할을 선택하세요. 지원하는 모든 테마와 상태에서 렌더링된 조합을 검사하세요. WCAG 중심 검토에서는 일반 텍스트 4.5:1 이상, 큰 텍스트 3:1 이상, 핵심 컨트롤 경계와 상태 표시 3:1 이상을 기준으로 삼으세요.
색상은 의미를 보강해야 하며 혼자 의미를 전달하면 안 돼요. 위험 색상에는 오류 문구를, 경고 색상에는 아이콘이나 레이블을, 선택 색상에는 aria-selected 같은 프로그래밍 상태를 함께 제공하세요. Tinyrack 시맨틱 역할은 색상과 테마에서 확인하세요.
대상 크기
포인터 대상은 24×24 CSS 픽셀 이상으로 만들거나 WCAG 2.2 최소 대상 규칙이 허용하는 간격을 제공하세요. 자주 터치하는 동작에는 더 큰 대상을 권장해요. Tinyrack 컨트롤 높이는 md 32px, lg 40px예요. 입력 환경에 맞는 크기를 선택하고 아이콘 전용 컨트롤과 사용자 정의 컨트롤의 가로·세로를 모두 검사하세요. 보이는 아이콘은 작게 유지하면서 패딩으로 활성 영역을 넓힐 수 있어요.
빽빽한 한 줄에 맞추려고 인접 동작을 줄이지 마세요. 줄바꿈하거나, 보조 동작을 메뉴로 옮기거나, 간격을 늘리세요. 공통 크기 레시피는 컨트롤과 상태에서 확인할 수 있어요.
확대, 리플로, 현지화
1280px 너비 화면을 400%로 확대했을 때와 같은 320 CSS 픽셀 뷰포트에서도 작업이 리플로되도록 설계하세요. 텍스트 줄바꿈을 허용하고, 콘텐츠 높이를 고정하지 말고, 레이블이 길어져도 동작에 접근할 수 있게 하세요. 데이터 표는 레이블이 있는 자체 영역에서 가로로 스크롤할 수 있지만 페이지와 주변 본문까지 이차원 스크롤이 필요하면 안 돼요.
영어, 한국어, 일본어를 브라우저 확대와 좁은 뷰포트에서 검사하세요. 영어 문구 길이만 기준으로 공간을 정하지 마세요. 열이 쌓일 때 소스 순서를 유지하고, 안전한 위치에서는 끊기지 않는 긴 값을 줄바꿈하며, 레이블이 두 줄이 되어도 의미를 유지하세요. 반응형 결정은 반응형 레이아웃, 읽기 좋은 줄 길이는 타이포그래피를 참고하세요.
모션 감소
모션은 상태나 공간 변화를 설명할 때 사용하고 유일한 신호로 사용하지 마세요. 운영체제가 모션 감소를 요청하면 필수적이지 않은 움직임을 제거하세요. 움직임을 만들지 않는 즉시 불투명도 또는 색상 변화는 감소된 표현에서도 유지할 수 있어요.
.rack-panel {
transition: transform var(--tinyrack-duration-normal)
var(--tinyrack-ease-out);
}
@media (prefers-reduced-motion: reduce) {
.rack-panel {
transition: none;
}
}
지속 시간과 이징 선택은 모션에서 이어서 확인하세요.
실무 검증 체크리스트
로딩, 비어 있음, 오류, 비활성화, 유효성 검사 상태를 포함한 빌드 결과를 검증하세요.
- 키보드만으로 앞뒤로 이동하세요. 포커스가 보이는지, 키 동작이 예상과 맞는지, 오버레이를 닫은 뒤 포커스가 자연스러운지 확인하세요.
- 접근성 트리를 검사하세요. 랜드마크, 제목 순서, 컨트롤 이름, 설명, 상태, 라이브 알림을 확인하세요.
- 대비 도구로 밝은·어두운 테마와 호버, 포커스, 선택, 비활성화, 상태 표현을 검사하세요. 색상이 없어도 정보가 남는지 확인하세요.
- 좁은 화면과 터치 또는 거친 포인터 에뮬레이션에서 포인터 대상과 간격을 검사하세요.
- 텍스트를 200%로 확대하고 400% 확대에 해당하는 좁은 뷰포트에서도 콘텐츠가 제대로 재배치되는지 확인하세요. 페이지 수준의 가로 스크롤 없이 콘텐츠와 동작을 사용할 수 있는지 확인하세요.
- 모션 감소를 켜고 모든 상태 변화가 계속 전달되는지 확인하세요.
- 현지화 콘텐츠를 확인하고, 중요한 흐름은 지원하는 대표 스크린 리더와 브라우저 조합에서 검사하세요.
자동 검사는 마크업과 대비 계산의 회귀를 찾지만 키보드, 확대, 스크린 리더, 작업 단위 검토를 대신하지 못해요.