WCAG 성공 기준 · Level AAA
WCAG 2.4.13: 포커스 외형
WCAG 2.4.13은 키보드 포커스 표시기가 최소 크기와 명도 대비 요구 사항을 충족하여 사용자가 어떤 요소에 포커스가 있는지 명확하게 볼 수 있도록 할 것을 요구합니다. 이 기준은 키보드나 보조 기술에 의존하는 사람들이 현재 위치를 놓치지 않고 인터페이스를 탐색할 수 있도록 보장합니다.
- Level AAA
- Wcag
- Wcag 2 2 aaa
- 작동 가능한
- 접근성
이 규칙의 의미
WCAG 2.4.13 Focus Appearance는 WCAG 2.2에서 도입된 AAA 레벨 기준으로, 키보드 포커스 표시의 시각적 형태에 대해 정확하고 측정 가능한 요구 사항을 제시합니다. 더 낮은 레벨 기준인 2.4.11(포커스 비가림, AA 레벨)은 포커스된 요소가 완전히 가려지지 않도록 보장하고, 2.4.7(포커스 표시, AA 레벨)은 단순히 어떤 형태로든 포커스 표시가 존재할 것을 요구하는 반면, 2.4.13은 그 표시가 얼마나 잘 보이는지까지 구체적으로 정의합니다.
이 기준을 충족하려면 키보드 포커스 표시는 다음 모든 조건을 만족해야 합니다.
- 최소 면적: 포커스 표시는 포커스되지 않은 컴포넌트의 둘레에 2 CSS 픽셀을 곱한 값 이상에 해당하는 면적을 가져야 합니다. 실질적으로, 일반적인 직사각형 버튼의 경우 포커스 외곽선의 면적이 버튼 둘레 × 2px 이상이어야 한다는 의미입니다. 즉, 전체 경계를 둘러싸는 두께 2px 이상의 포커스 링이면 요건을 충족합니다.
- 포커스 표시의 명도 대비: 포커스 표시를 구성하는 픽셀은 포커스된 상태와 포커스되지 않은 상태 사이에 최소 3:1의 명도 대비를 가져야 합니다. 예를 들어 버튼의 기본 상태 배경이 흰색이라면, 그 주위에 그려지는 포커스 링은 해당 흰색 배경과 최소 3:1의 대비를 가져야 합니다.
- 포커스된 요소 내부 콘텐츠 대비 저하 금지: 포커스 표시는 포커스된 컴포넌트 내부의 텍스트나 기타 콘텐츠의 대비를 4.5:1(18pt 미만 / 14pt 볼드 미만 텍스트) 또는 3:1(큰 텍스트 및 비텍스트 콘텐츠) 아래로 떨어뜨려서는 안 됩니다.
세 가지 조건이 모두 동시에 충족되어야 컴포넌트가 통과합니다. 크기는 충분하지만 대비가 부족한 포커스 표시는 실패입니다. 마찬가지로, 대비는 높지만 너무 작은 표시도 실패입니다.
WCAG 명세는 한 가지 중요한 예외를 정의합니다. 브라우저의 기본 포커스 표시(사용자 에이전트 기본값)가 요구 사항을 충족하는 경우, 저자는 커스텀 스타일을 추가할 필요가 없습니다. 그러나 브라우저 기본값은 상당히 다릅니다. Chromium 기반 브라우저는 일반적으로 파란색 외곽선을 제공하는 반면, Safari는 특정 색 구성에서 대비가 충분하지 않은 링을 렌더링할 수 있습니다. 저자는 기본 표시가 기준을 충족하는지 확인하거나, 견고한 커스텀 스타일을 제공해야 합니다.
이 기준은 모든 인터랙티브하고 포커스 가능한 컴포넌트에 적용됩니다. 링크, 버튼, 폼 입력, 셀렉트 메뉴, 체크박스, 라디오 버튼, ARIA role로 만든 커스텀 위젯 컴포넌트, 그리고 tabindex를 통해 포커스 가능하게 만든 모든 요소가 포함됩니다. 또한, CSS의 의사 요소만으로 생성된 포커스 표시나 JavaScript로 제어되는 클래스 변경을 통해 생성된 포커스 표시에도 적용됩니다.
왜 중요한가
포커스 가시성은 다양한 사용자에게 매우 중요한 내비게이션 단서입니다. 포커스 표시가 얇거나, 대비가 낮거나, 아예 없을 경우, 이러한 사용자는 페이지 내에서 공간적 방향 감각을 잃게 됩니다. 자신이 어디에 있는지, 다음에 어디로 갈 수 있는지 알 수 없습니다.
키보드만 사용하는 사용자 — 떨림, 마비, 반복성 긴장 장애와 같은 운동 장애가 있는 사람들을 포함해 — 는 내비게이션을 전적으로 키보드에 의존합니다. 이들에게 보이지 않거나 거의 보이지 않는 포커스 표시는 단순한 불편을 넘어, 전체 인터페이스를 사용 불가능하게 만듭니다. 세계보건기구(WHO)에 따르면 약 13억 명이 어떤 형태로든 장애를 가지고 있으며, 이 중 상당수가 마우스를 피하거나 사용할 수 없는 운동 장애에 해당합니다.
저시력 사용자 중 화면 낭독기를 완전히 사용하지 않고 확대 소프트웨어만 사용하는 사람들도 포커스 링에 의존해 자신의 위치를 파악합니다. 높은 확대 수준에서는 1px 기본 외곽선이 뷰포트에 의해 잘리거나, 비슷한 색 배경 위에서 사실상 보이지 않을 수 있습니다. 이들은 높은 배율에서 정밀한 마우스 조작이 어렵기 때문에, 오히려 키보드 내비게이션을 선호하는 경우가 많습니다.
ADHD, 불안 장애, 외상성 뇌 손상과 같은 인지 및 주의 관련 장애는 페이지 전체에 걸친 시각 정보를 추적하는 것을 어렵게 만들 수 있습니다. 매우 잘 보이고 명확히 구분되는 포커스 표시는 사용자의 현재 위치에 대한 분명한 기준점을 제공함으로써 내비게이션의 인지적 부담을 줄여 줍니다.
상황적 장애도 중요합니다. 야외에서 밝기가 낮은 노트북 화면으로 테스트하는 개발자나, 연령 관련 대비 감도 저하가 있는 고령 사용자는 임상적 진단이 없더라도 얇거나 대비가 낮은 포커스 링을 인지하는 데 어려움을 겪을 수 있습니다.
현실적인 사례를 생각해 봅시다. 자금 이체를 위한 은행의 온라인 폼에 10개의 입력 필드와 4개의 액션 버튼이 있습니다. 파킨슨병이 있는 사용자가 키보드로 탭을 눌러 폼을 이동합니다. 포커스 표시가 흰색 배경 위의 연한 회색 1px 점선 기본 외곽선이라면, 사용자는 현재 어느 필드를 편집 중인지 안정적으로 파악할 수 없습니다. 수신인 필드를 지나 포커스가 이동한 것을 보지 못해, 잘못된 계좌로 이체를 제출할 수도 있습니다. 강력하고 고대비의 포커스 외곽선이 있었다면 이런 문제는 완전히 예방되었을 것입니다.
접근성을 넘어, 명확한 포커스 표시는 모든 사용자에게 사용성을 향상시킵니다. 폼과 메뉴를 키보드로 자주 탐색하는 파워 유저 — 개발자, 데이터 입력 담당자, 화면 낭독기 사용자 등 — 는 빠르고 신뢰할 수 있는 위치 파악의 이점을 누립니다. 또한 간접적인 SEO 신호도 있습니다. 접근성이 뛰어난 사이트는 이탈률이 낮고 과업 완료율이 높은 경향이 있으며, 이는 모두 긍정적인 검색 순위 요인과 상관관계를 가집니다.
관련 Axe-core 규칙
WCAG 2.4.13은 수동 테스트가 필요합니다. 자동화 도구는 모든 가능한 브라우저 렌더링 컨텍스트에서 포커스 표시의 크기와 대비를 완전히 평가할 수 없기 때문입니다. Axe-core에는 2.4.13 실패를 직접적으로 표시하는 단일 자동 규칙이 없습니다. 그 이유는 기술적입니다.
- 자동화가 불충분한 이유: 포커스 표시의 정확한 픽셀 면적을 계산하려면 모든 인터랙티브 요소에 대해 키보드 포커스를 시뮬레이션하고, 렌더링된 외곽선 기하(브라우저, OS, 확대 수준, CSS에 따라 달라짐)를 측정하고, 표시 픽셀과 주변 픽셀 간의 명도 대비를 계산하며, 이 중 어느 것도 내부 콘텐츠 대비 요구 사항을 위반하지 않는지 확인해야 합니다. 현재 어떤 자동 접근성 엔진도 모든 컴포넌트에 대해 이 모든 단계를 신뢰성 있게 수행하지 못합니다. Axe-core는 포커스 스타일의 부재(2.4.7 관련)는 감지할 수 있지만, 존재하는 스타일이 2.4.13의 면적 및 대비 기준을 충족하는지 측정할 수는 없습니다.
- 포커스 관련 규칙을 통한 부분적 커버리지: Axe-core의
focus-visible규칙은 요소에 포커스 표시가 보이는지 여부를 검사합니다. 요소에outline: none또는outline: 0이 설정되어 있고 대체 시각 표시가 없다면, 이 규칙이 이를 플래그합니다. 그러나 이 규칙을 통과했다고 해서 2.4.13 준수를 보장하지는 않습니다. 기술적으로는 보이지만 여전히 너무 얇거나 대비가 낮은 외곽선일 수 있기 때문입니다. - 수동 테스트가 최종 기준: 테스터는 포커스된 상태의 모든 인터랙티브 컴포넌트를 시각적으로 검사하고, 외곽선의 치수를 측정하거나 추정하며, 색 대비 분석기를 사용해 명도 대비를 검증해야 합니다. 이러한 이유로 WCAG는 axe-core 관점에서 2.4.13을 수동 테스트 전용 기준으로 분류합니다.
테스트 방법
- 자동 스캔(부분 신호만 제공): 페이지에서 axe DevTools 또는 Lighthouse를 실행합니다.
focus-visible또는focus-order-semantics관련 실패가 있는지 확인합니다. 이 규칙들이 2.4.13 위반을 직접적으로 표시하지는 않지만, 포커스 스타일이 완전히 억제된 요소(선행 실패)를 드러낼 수 있습니다. Chrome DevTools에서 접근성 패널을 열고 "Tab" 검사 모드를 사용해 포커스 가능한 요소를 순환합니다. - 시각적 키보드 내비게이션 테스트: 마우스를 분리하거나 옆에 둡니다. Tab 키를 눌러 페이지의 모든 인터랙티브 요소를 이동합니다. 각 포커스된 요소에 대해 포커스 표시를 시각적으로 검사합니다. 분명히 보이는 링 또는 다른 표시가 있는가? 두께가 최소 2px 정도로 보이는가? 주변 배경과 강하게 대비되는가? 포커스 위치를 찾는 데 망설이거나 어려움을 겪는 요소를 기록합니다.
- 대비 측정: WebAIM Contrast Checker 또는 Colour Contrast Analyser 데스크톱 도구를 사용합니다. 컴포넌트에 포커스를 둔 상태에서 스크린샷을 찍습니다. 포커스 표시 픽셀의 색상과 바로 인접한 배경 색상을 샘플링합니다. 명도 대비가 최소 3:1인지 확인합니다.
- 치수 측정: 브라우저 DevTools(Chrome 또는 Firefox)를 사용합니다. 포커스된 요소를 선택하고 계산된 스타일을 검사합니다.
outline-width,outline-offset, 포커스 링으로 사용되는box-shadow를 확인합니다. 요소의 둘레(2 × 너비 + 2 × 높이)에 2px을 곱해 최소 면적을 계산합니다. 표시의 렌더링된 면적이 이 값 이상인지 확인합니다. - 스크린 리더 + 키보드 테스트(NVDA + Firefox): Firefox에서 NVDA를 실행한 상태로 페이지를 엽니다. Tab과 화살표 키로 내비게이션합니다. 시각적 포커스 표시가 NVDA가 알리는 포커스와 동기화되어 움직이는지 확인합니다. 포커스 관리가 JavaScript로 처리될 수 있는 캐러셀, 모달, 아코디언 같은 커스텀 위젯에 특히 주의를 기울입니다.
- VoiceOver + Safari(macOS/iOS): Command + F5로 VoiceOver를 활성화합니다. Tab 키로 인터랙티브 요소를 탐색합니다. VoiceOver 커서(검은색 외곽선 상자)가 적절한 CSS 포커스 표시를 대체하지 않는다는 점을 확인합니다. 페이지 자체가 독립적으로 포커스 표시를 제공해야 합니다.
- 고대비 모드 테스트: Windows에서 고대비 모드(설정 → 접근성 → 고대비)를 활성화합니다. 페이지를 새로고침하고 키보드 내비게이션 테스트를 반복합니다. 일부 CSS 포커스 스타일은 고대비 모드에서 운영체제에 의해 덮어써집니다. 여전히 보이는 표시가 나타나는지 확인합니다. 필요하다면
forced-colors: activeCSS 미디어 쿼리를 사용해 조건부로 스타일을 조정합니다.
수정 방법
기본 브라우저 외곽선 제거 — 잘못된 예
<!-- Many stylesheets globally suppress the default focus outline -->
<style>
* {
outline: none; /* Removes ALL focus indicators site-wide */
}
a:focus, button:focus {
outline: 0; /* Redundant removal; no replacement provided */
}
</style>
<button>Submit Payment</button>
기본 브라우저 외곽선 제거 — 올바른 예
<!-- Remove the default only when providing a superior custom indicator -->
<style>
/* Only suppress default outline when :focus-visible applies, then provide a strong replacement */
:focus-visible {
outline: 3px solid #0057b8; /* 3px ensures area requirement is met for typical elements */
outline-offset: 2px; /* Offset separates indicator from element edge for clarity */
}
/* Respect forced-colors (Windows High Contrast) by using system keywords */
@media (forced-colors: active) {
:focus-visible {
outline: 3px solid ButtonText;
}
}
</style>
<button>Submit Payment</button>
색 배경 위의 저대비 포커스 링 — 잘못된 예
<style>
.cta-button {
background-color: #0057b8;
color: #ffffff;
}
.cta-button:focus {
outline: 2px solid #3399ff; /* Light blue outline on dark blue background: contrast ratio ~1.4:1 — fails */
}
</style>
<button class='cta-button'>Book Now</button>
색 배경 위의 저대비 포커스 링 — 올바른 예
<style>
.cta-button {
background-color: #0057b8;
color: #ffffff;
}
.cta-button:focus-visible {
/* White outline contrasts strongly against the dark blue button (contrast ~8:1) */
outline: 3px solid #ffffff;
outline-offset: 2px;
/* A dark offset box-shadow behind the white ring ensures contrast against light page backgrounds */
box-shadow: 0 0 0 5px #0057b8;
}
</style>
<button class='cta-button'>Book Now</button>
포커스 스타일이 없는 div 기반 커스텀 인터랙티브 위젯 — 잘못된 예
<style>
.tab-item { cursor: pointer; padding: 12px 20px; }
/* No :focus or :focus-visible style defined for custom tab */
</style>
<div role='tab' tabindex='0' class='tab-item'>Reservations</div>
포커스 스타일이 없는 div 기반 커스텀 인터랙티브 위젯 — 올바른 예
<style>
.tab-item {
cursor: pointer;
padding: 12px 20px;
border-radius: 4px;
}
/* Explicit :focus-visible style — outline-width 3px with offset meets area threshold */
.tab-item:focus-visible {
outline: 3px solid #d4550a; /* 3:1+ contrast against white background */
outline-offset: 3px;
}
</style>
<div role='tab' tabindex='0' class='tab-item'>Reservations</div>
얇은 box-shadow를 포커스 표시로 사용 — 잘못된 예
<style>
.form-input:focus {
outline: none;
/* 1px box-shadow spread: likely too small in area for most input sizes */
box-shadow: 0 0 0 1px #005fcc;
}
</style>
<input type='text' class='form-input' placeholder='Your email' />
얇은 box-shadow를 포커스 표시로 사용 — 올바른 예
<style>
.form-input:focus-visible {
outline: none;
/*
3px spread provides sufficient area around a typical 300px-wide input.
#005fcc on white background yields ~5.9:1 contrast — passes both 2.4.13 (3:1) and 1.4.3 (4.5:1).
*/
box-shadow: 0 0 0 3px #005fcc;
}
</style>
<input type='text' class='form-input' placeholder='Your email' />
자주 발생하는 실수
- CSS 리셋에서
outline: none을 사용하면서 대체 포커스 표시를 제공하지 않는 경우. Normalize.css의 예전 버전이나 커스텀 리셋 등 많은 인기 CSS 리셋이 외곽선을 일괄 제거합니다. 제거 시에는 항상 크기와 대비 요구 사항을 충족하는:focus-visible대체 스타일을 함께 제공해야 합니다. :focus에만 포커스 스타일을 제공하고:focus-visible에는 제공하지 않아, 마우스로 클릭한 버튼에 포커스 링이 나타나 시각 사용자에게 불편을 주는 경우 — 이로 인해 개발자가 올바른 의사 클래스 분리를 사용하기보다는 포커스 표시를 완전히 제거해 버리는 결과로 이어집니다.- 컴포넌트 배경색과 거의 비슷한 색의 포커스 링을 선택하는 경우. 예를 들어 흰색(
#ffffff) 배경 위의 연한 파란색#99ccff링은 명도 대비가 약 1.5:1로, 요구되는 3:1보다 훨씬 낮습니다. - 아이콘 버튼이나 체크박스 같은 작은 컴포넌트에
outline-width: 1px를 사용하는 경우. 24×24px 아이콘 주위의 1px 링은 면적이 약 96 제곱 픽셀에 불과하지만, 24×24 요소의 최소 요구 면적은 (24+24+24+24) × 2 = 192 제곱 픽셀로, 정확히 두께 2px에 해당합니다. 1px 외곽선은 이 계산에서 실패합니다. role='combobox',role='listbox',role='slider'와 같은 커스텀 ARIA 위젯의 포커스 표시 테스트를 잊는 경우. 이들 컴포넌트는 종종 네이티브 CSS 의사 클래스를 우회하는 JavaScript 기반 포커스 관리를 사용하므로, 명시적으로 처리하지 않으면 포커스 스타일이 적용되지 않을 수 있습니다.- 포커스 스타일을
a와button태그에만 적용하고input,select,textarea, 그리고tabindex='0'이 있는 모든 요소를 간과하는 경우. - 컴포넌트 라이브러리나 서드파티 위젯 깊은 곳에서 포커스 스타일을 오버라이드하면서, 그 오버라이드가 가시적인 표시를 제거한다는 사실을 인지하지 못하는 경우. 흔한 예로 Bootstrap 4 같은 UI 키트는
box-shadow를 미묘한 글로우로 설정하는데, 이는 2.4.13 기준을 충족하지 못할 수 있습니다. - Windows 고대비 모드에서 포커스 표시를 테스트하지 않는 경우. 일부 CSS outline 및 box-shadow 기법은 고대비 모드에서 보이지 않게 렌더링됩니다.
@media (forced-colors: active)블록을 사용해 시스템 색 기반의 가시적인 폴백을 제공해야 합니다. outline-offset에 매우 큰 음수 값을 사용해 외곽선을 요소의 테두리 안쪽으로 이동시키는 경우. 이는 표시가 요소 배경과 겹치게 만들어 실질적인 대비를 3:1 아래로 떨어뜨릴 수 있습니다.- 부모 컨테이너의 포커스 표시만으로 자식 인터랙티브 요소에 충분하다고 가정하는 경우. 각 포커스 가능한 요소는 독립적으로 기준을 충족해야 합니다. 테이블의 강조된 행은 그 행 안의 링크 셀에 대한 요구 사항을 충족하지 못합니다.
터키 접근성 규정과의 관계
2025년 6월 21일 관보 제32933호에 게재된 터키 대통령령 2025/10은 터키에서 활동하는 광범위한 주체에 대해 웹 및 모바일 접근성 의무를 설정합니다. 이 대통령령은 WCAG 2.2를 기술적 참조 표준으로 채택하고, 해당 주체에 대해 AA 레벨의 준수를 의무화합니다. WCAG 2.4.13 Focus Appearance는 AAA 레벨 기준이므로, 표준 준수를 위해 대통령령에서 직접적으로 의무화되지는 않습니다.
그러나 대통령령의 적용 범위는 매우 광범위합니다. 적용 대상에는 공공 기관 및 정부 부처, 은행 및 금융 서비스 제공자, 병원 및 의료 기관, 가입자 200,000명 이상인 통신 사업자, 전자상거래 플랫폼, 여행사, 민간 운송 회사, 그리고 교육부(MoNE)의 인가를 받은 사립 학교가 포함됩니다. 이들 모든 조직에 대해, 2.4.13을 포함한 해당 가능한 기준에서 AAA 레벨 준수를 입증하는 것은 법적 기준을 넘어선 최고 수준의 접근성에 대한 의지를 보여 줍니다.
터키 내 적용 대상 기관이 2.4.13을 자발적으로 구현해야 할 실질적·평판상의 이유도 있습니다. 특히 은행과 금융 서비스 제공자는 키보드 내비게이션에 의존해 안전한 거래를 수행하는 운동 장애 고객을 상대합니다. 2.4.13을 충족하는 터키 은행의 온라인 뱅킹 포털은 규제 요구 사항을 초과할 뿐 아니라, 사용자 오류 위험을 줄이고 기업의 사회적 책임을 보여 줍니다. 마찬가지로, 환자가 진료 예약을 하거나 의무 기록에 접근하는 병원 및 의료 포털은 미세 운동 능력이 떨어지거나 저시력을 가진 고령 환자를 포함한 모든 사용자가 자신 있게 인터페이스를 탐색할 수 있도록 해야 합니다.
대규모 가입자 기반을 가진 통신 사업자는 터키에서 가장 트래픽이 많은 디지털 서비스 중 하나입니다. 이들의 고객 포털과 셀프 서비스 애플리케이션은 수백만 명의 사용자에게 도달하며, 이 중에는 고령자와 장애 사용자가 상당수 포함됩니다. 이러한 플랫폼 전반에 걸쳐 2.4.13을 자발적으로 구현하는 것은 모든 가입자에게 공평한 접근을 보장하고, AAA 기준에 대한 의무 준수가 향후 규제 강화로 확대될 경우 유리한 위치를 선점하는 효과가 있습니다.
조달 요구 사항, 유럽 접근성법(European Accessibility Act)의 적용을 받는 EU 시장 수출, 또는 내부 접근성 정책 등으로 인해 WCAG 2.2 AAA 레벨의 완전한 준수를 목표로 하는 조직의 경우, 2.4.13 구현은 필수 구성 요소입니다. Accsible의 오버레이 SDK는 이 글에서 설명한 저자 수준 CSS 수정과 더불어, 인터페이스 전반에 강력하고 기준을 충족하는 포커스 표시를 제공할 수 있도록 구성 가능한 포커스 향상 기능을 제공합니다.
