WCAG 성공 기준 · Level A
WCAG 1.3.1: 정보 및 관계
WCAG 1.3.1은 시각적 표현을 통해 전달되는 정보, 구조, 그리고 관계를 프로그래밍 방식으로도 파악할 수 있거나 텍스트로 제공되도록 요구하여, 보조 기술 사용자들이 시각 사용자와 동일한 구조적 맥락을 제공받을 수 있도록 보장한다.
- Level A
- Wcag
- Wcag 2 2 a
- 지각 가능
- 접근성
이 규칙의 의미
WCAG 1.3.1 — 정보 및 관계는 지각 가능(Perceivable) 원칙 아래의 레벨 A 기준이다. 핵심 요구사항은 단순하지만 영향 범위는 매우 넓다. 시각적으로 전달되는 모든 정보나 관계는 보조 기술이 감지하고 사용자에게 전달할 수 있는 방식으로도 표현되어야 한다. 디자인에서 들여쓰기를 사용해 목록을 암시하거나, 굵은 글씨로 필수 입력 필드를 표시하거나, 색으로 오류를 나타내거나, 크기로 제목을 구분하는 등 시각적 단서를 사용한다면, 동일한 의미가 반드시 기저 코드에도 존재해야 한다.
이 기준은 웹 콘텐츠가 표현을 통해 정기적으로 전달하는 의미의 세 가지 범주에 적용된다.
- 정보(Information) — 어떤 입력 필드가 필수인지, 어떤 표 셀들이 서로 관계를 맺는지와 같이 페이지에서 전달되는 사실이나 데이터.
- 구조(Structure) — 제목 계층, 순서 있는/없는 목록, 데이터 표와 같은 콘텐츠의 조직 구조.
- 관계(Relationships) — 레이블과 그 입력 필드, 표 헤더와 데이터 셀, 용어와 그 정의처럼 요소들 사이의 연관성.
시각 사용자에게 제공되는 모든 구조적 또는 관계적 정보가 유효한 시맨틱 HTML로 인코딩되어 있거나, 보조 기술이 해석할 수 있는 올바른 ARIA 역할(role), 속성(property), 상태(state)를 통해 노출되어 있을 때 페이지는 1.3.1을 충족한다. 반대로, 시각적 구조가 CSS나 이미지에만 존재하거나, ARIA 마크업이 DOM 구조와 모순되거나 누락되어 있을 때 페이지는 실패한다.
공식적인 예외는 매우 제한적이다. 이 기준은 모든 시각적 장식에 시맨틱 의미를 부여할 것을 요구하지 않는다. 장식용 테두리나 배경색처럼 순수하게 미적인 서식은 프로그래밍 방식의 대응 요소가 필요 없다. 그러나 사용자가 의미를 전달한다고 합리적으로 해석할 수 있는 모든 서식(필수 항목을 나타내는 별표, 용어집의 굵은 용어, 번호가 매겨진 단계)은 이에 상응하는 프로그래밍 표현을 가져야 한다.
왜 중요한가
정보와 관계는 사용자가 웹 페이지와 상호작용하는 거의 모든 순간의 기반을 이룬다. 그 구조가 시각적 표현 안에만 갇혀 있을 때, 인구의 상당 부분은 사실상 콘텐츠를 전혀 이해하지 못한 채 배제된다.
스크린 리더 사용자(대개 시각장애인 또는 저시력인)는 시맨틱 HTML과 ARIA로부터 구축되는 접근성 트리를 조회하며 페이지를 탐색한다. 개발자가 실제 <h2> 대신 제목처럼 보이도록 스타일링한 <div>를 사용할 경우, H 키로 제목 사이를 이동하는 스크린 리더 사용자는 그 요소를 완전히 건너뛴다. 그 섹션을 영영 찾지 못할 수도 있다. 세계보건기구(WHO)에 따르면 전 세계 약 22억 명이 어떤 형태로든 시각 장애를 가지고 있으며, 수천만 명이 매일 스크린 리더에 의존한다.
인지 장애가 있는 사용자도 명확한 구조로부터 동일하게 큰 이득을 얻는다. 올바르게 중첩된 제목, 의미 있는 목록 마크업, 레이블이 지정된 폼 컨트롤은 예측 가능한 패턴을 제공함으로써 인지적 부담을 줄여 준다. 스크린 리더가 "제목 레벨 2, Products", 이어서 "제목 레벨 3, Laptops"라고 읽어 주면 페이지의 인지적 지도가 형성된다. 구조적 기준점 없이 스타일만 적용된 평평한 텍스트 덩어리는 모든 사용자에게 혼란스럽지만, 특히 주의력이나 기억에 어려움이 있는 사용자에게 더 그렇다.
키보드 내비게이션, 스위치 액세스, 음성 제어 소프트웨어에 의존하는 운동 장애 사용자도 프로그래밍 구조에 의존한다. Dragon NaturallySpeaking 같은 음성 제어 소프트웨어는 레이블과 역할에서 파생된 접근 가능한 이름으로부터 클릭 가능한 타깃을 생성한다. 레이블이 연결되지 않은 폼 입력은 음성 명령으로는 신뢰성 있게 타깃팅할 수 없다.
구체적인 상황을 생각해 보자. 한 병원 환자 포털이 예정된 진료 일정을 표로 보여 준다. 이 표는 날짜와 의사를 연결하기 위해 시각적 정렬과 배경색을 사용하지만, <th> 요소에는 scope 속성이 없고 데이터 셀은 헤더를 참조하지 않는다. 스크린 리더를 사용하는 시각장애인은 "9:00 AM", "Dr. Ayşe Kaya", "Cardiology"처럼 서로 떨어진 셀 값만 듣게 되며, 어떤 값이 어떤 열에 속하는지 알 수 없다. 진료 시간을 잘못 이해하거나 잘못된 진료과에 갈 수도 있다. 헤더에 scope='col'을 올바르게 사용하고 셀에 headers 속성을 추가했다면 이러한 관계가 소리로도 전달되었을 것이다.
접근성을 넘어, 구조적 HTML은 SEO에도 상당한 가치를 지닌다. 검색 엔진 크롤러는 제목 계층을 사용해 페이지 주제를 이해하고, 목록 마크업으로 열거된 콘텐츠를 식별하며, 레이블 연관성을 통해 폼의 목적을 파악한다. 1.3.1을 충족하는 페이지는 거의 항상 검색 엔진이 더 정확하게 파싱하고 순위를 매길 수 있는 페이지이기도 하다.
관련 Axe-core 규칙
다음 axe-core 규칙들은 WCAG 1.3.1 위반과 직접적으로 매핑된다. 각 규칙은 프로그래밍 구조나 관계의 특정 측면을 대상으로 한다.
- aria-required-children — 특정 ARIA 역할을 가진 요소가 필수 자식 역할을 포함하는지 확인한다. 예를 들어
role='list'는role='listitem'을 가진 자식을 포함해야 한다. 올바른 자식 구조가 없으면 컨테이너와 그 항목 사이의 관계가 보조 기술에 대해 깨진다. - aria-required-parent — 위의 반대 개념으로, 특정 부모 컨텍스트를 요구하는 역할을 가진 요소가 실제로 그 부모를 가지고 있는지 확인한다.
role='listitem'이role='list'나<ul>/<ol>안에 있지 않다면 관계 컨텍스트가 없기 때문에 플래그가 설정된다. - aria-roles — 모든
role속성 값이 유효한 ARIA 역할인지 검증한다. 잘못되었거나 오타가 있는 역할(예: 제목 요소 대신role='heading'을 사용하거나, 완전히 임의로 만든 역할)은 보조 기술이 유용한 정보를 받지 못하게 하며, 요소를 완전히 무시할 수도 있다. - definition-list —
<dl>요소가 허용된 자식만 포함하는지 확인한다. 허용된 자식은<dt>,<dd>,<div>,<script>,<template>이다.<dl>안에<p>같은 다른 요소를 직접 넣으면 용어-정의 관계 구조가 무효화된다. - dlitem —
<dt>와<dd>요소가 오직<dl>요소 안에서만 사용되는지 확인한다. 필수 부모 컨텍스트 밖에서 이 요소들을 사용하면 용어-정의 쌍의 시맨틱 의미가 사라진다. - heading-order — 문서 개요에서 건너뛴 제목 레벨(예:
<h2>에서 바로<h4>로 점프)을 표시한다. 항상 엄격한 실패는 아니지만, 레벨을 건너뛰면 페이지의 계층 구조에 대해 보조 기술을 오도하고, 제목으로 탐색하는 사용자에게 혼란을 준다. - label — 모든 폼 입력에 프로그래밍 방식으로 연결된 레이블이 있는지 확인한다. 이는
<label for='...'>,aria-label,aria-labelledby, 또는 감싸는<label>요소를 통해 가능하다. 접근 가능한 레이블이 없는 입력은 시각장애인과 음성 제어 사용자에게 어떤 값을 입력해야 하는지에 대한 정보를 제공하지 못한다. - list —
<ul>과<ol>요소가 직접 자식으로 오직<li>요소(그리고<script>,<template>)만 포함하는지 확인한다. 유효하지 않은 자식 요소는 스크린 리더가 항목 개수와 위치를 알리는 데 사용하는 목록 구조를 깨뜨린다. - listitem —
<li>요소가 오직<ul>,<ol>, 또는role='list'컨테이너 안에서만 사용되는지 확인한다. 고아 상태의 목록 항목은 시맨틱 의미를 완전히 잃는다. - scope-attr-valid —
<th>요소의scope속성이 허용된 값(col,row,colgroup,rowgroup)만 포함하는지 검증한다. 복잡한 데이터 표에서 잘못되었거나 누락된 scope 값은 스크린 리더가 어떤 헤더가 특정 데이터 셀에 적용되는지 신뢰성 있게 알리지 못하게 만든다. - td-headers-attr — 데이터 셀이
headers속성을 사용할 때, 참조된 모든 ID가 동일한 표 안에 실제로 존재하며 헤더 셀에 속하는지 확인한다. 끊어졌거나 누락된 참조는 데이터와 그 설명 헤더 사이의 프로그래밍 관계를 끊어, 스크린 리더 사용자에게 맥락을 제공하지 못하게 한다.
axe-core 같은 자동화 도구가 1.3.1의 모든 위반을 잡아낼 수 있는 것은 아니라는 점에 유의해야 한다. 예를 들어, 개발자가 시각적으로 스타일링된 <div>에 role='list'를 부여하고, 올바르게 구조화된 자식 role='listitem' 요소를 사용했다면 — axe는 이를 통과시킬 것이다 — 그러나 사람 테스트는 시각적 들여쓰기가 ARIA 구조에 반영되지 않은 중첩 하위 목록을 암시한다는 사실을 발견할 수 있다. 시각적 계층이 복잡할수록, 수동 점검과 스크린 리더 테스트는 자동 스캔을 보완하는 필수 절차다.
테스트 방법
- axe DevTools 또는 Lighthouse를 사용한 자동 스캔: axe DevTools 브라우저 확장 프로그램(Chrome 또는 Firefox)을 설치한다. 테스트할 페이지를 연 뒤 DevTools를 열고 axe 탭으로 이동해 전체 페이지 스캔을 실행한다. 결과를
wcag131태그로 필터링하거나 "Info and Relationships" 아래에 태그된 모든 이슈를 검토한다. 위에 나열된 11개 axe 규칙 위반이 있는지 특히 확인한다. Lighthouse(Chrome DevTools Audits 패널)에서는 접근성 감사(a11y audit)를 실행하고 "Accessibility" 카테고리에서 제목 순서, 레이블, 목록 관련 실패를 확인한다. 수정 작업을 위해 플래그된 모든 요소와 그 DOM 셀렉터를 기록한다. - 수동 제목 구조 검토: HeadingsMap 브라우저 확장 프로그램이나 axe DevTools의 "Headings" 패널을 사용해 페이지의 전체 제목 개요를 확인한다. 개요가 논리적이고 계층적인지 — 잘 구조화된 목차처럼 읽히는지 — 검증한다. 제목 레벨이 건너뛰어지지 않았는지, 제목 텍스트가 의미를 담고 있으며 단순히 비제목 요소에 적용된 시각적 스타일링만이 아닌지 확인한다.
- 폼 레이블 검증: 페이지의 모든 인터랙티브 폼 요소를 Tab 키로 순회한다. 각 input, select, textarea에 대해 눈에 보이는 레이블이 존재하는지, 그리고 프로그래밍 방식으로 연결되어 있는지(DevTools에서 요소를 확인해 일치하는
for/id쌍 또는aria-label/aria-labelledby를 찾는다) 확인한다. Chrome DevTools의 접근성 트리(Elements 패널 → Accessibility 탭)를 사용해 각 컨트롤의 계산된 접근 가능한 이름을 확인한다. - NVDA + Firefox로 스크린 리더 테스트: NVDA를 실행하고 Firefox에서 페이지를 연다. H를 눌러 제목 사이를 순환하며, 읽어 주는 제목 레벨이 시각적 계층과 일치하는지 확인한다. F를 눌러 폼 필드 사이를 이동하며 각 필드의 레이블이 제대로 읽히는지 확인한다. T를 눌러 표로 이동한 뒤 셀을 화살표 키로 이동하며 헤더가 어떻게 읽히는지 듣는다. L을 눌러 목록 사이를 순환하며 항목 개수가 제대로 안내되는지 확인한다.
- VoiceOver + Safari(macOS/iOS)로 스크린 리더 테스트: VoiceOver를 활성화한다(macOS에서는 Cmd+F5). Rotor를 연다(Ctrl+Option+U) 후 Headings, Links, Form Controls, Tables를 확인한다. 모든 구조적 요소가 Rotor에 나타나는지, 그리고 읽어 주는 이름이 의미 있고 정확한지 확인한다.
- JAWS + Chrome으로 스크린 리더 테스트: JAWS와 Chrome에서 페이지를 연다. JAWS의 제목 목록(Insert+F6)을 사용해 제목 트리를 검토한다. Insert+F5로 폼 필드 목록을 열어 레이블 연관성을 확인한다. 표를 화살표 키로 탐색하며 JAWS가 각 데이터 셀에 대해 열 및 행 헤더를 읽어 주는지 확인한다.
- 표 헤더 관계 점검: 페이지의 모든 데이터 표를 식별한다. 단순한 표의 경우,
<th>요소에 적절한scope속성이 있는지 확인한다. 다단계 헤더가 있는 복잡한 표의 경우, 데이터 셀이 올바른id값을 참조하는headers속성을 사용하는지 확인한다. 각 셀을 시각적으로 따라가며 논리적인 행 및 열 헤더를 찾은 뒤, 동일한 경로가 코드에도 표현되어 있는지 확인한다.
수정 방법
스타일링된 div로 구현된 시각적 제목 — 잘못된 예
<!-- Heading conveyed only through CSS font-size and font-weight -->
<div class='section-title'>Our Services</div>
<div class='subsection-title'>Web Development</div>
<p>We build fast, accessible websites.</p>
스타일링된 div로 구현된 시각적 제목 — 올바른 예
<!-- Semantic heading elements expose hierarchy to assistive technologies -->
<h2>Our Services</h2>
<h3>Web Development</h3>
<p>We build fast, accessible websites.</p>
연결된 레이블이 없는 폼 입력 — 잘못된 예
<!-- The placeholder is not a substitute for a label; it disappears on input -->
<p>Email Address *</p>
<input type='email' placeholder='Enter your email' />
연결된 레이블이 없는 폼 입력 — 올바른 예
<!-- The for attribute ties the label to the input by matching id -->
<label for='email'>Email Address <span aria-hidden='true'>*</span><span class='sr-only'>(required)</span></label>
<input type='email' id='email' aria-required='true' />
scope 속성이 없는 데이터 표 — 잘못된 예
<!-- Headers have no scope; screen readers cannot associate columns with data -->
<table>
<tr>
<th>Tarih</th>
<th>Doktor</th>
<th>Klinik</th>
</tr>
<tr>
<td>15 Temmuz 2025</td>
<td>Dr. Ayşe Kaya</td>
<td>Kardiyoloji</td>
</tr>
</table>
scope 속성이 없는 데이터 표 — 올바른 예
<!-- scope='col' tells screen readers each th describes its entire column -->
<table>
<caption>Yaklaşan Randevular</caption>
<thead>
<tr>
<th scope='col'>Tarih</th>
<th scope='col'>Doktor</th>
<th scope='col'>Klinik</th>
</tr>
</thead>
<tbody>
<tr>
<td>15 Temmuz 2025</td>
<td>Dr. Ayşe Kaya</td>
<td>Kardiyoloji</td>
</tr>
</tbody>
</table>
목록 컨테이너 밖에서 사용된 목록 항목 — 잘못된 예
<!-- li elements without a parent ul or ol have no semantic meaning -->
<div class='features'>
<li>Fast performance</li>
<li>WCAG compliant</li>
<li>Mobile friendly</li>
</div>
목록 컨테이너 밖에서 사용된 목록 항목 — 올바른 예
<!-- Wrapping ul gives screen readers item count and navigation context -->
<ul class='features'>
<li>Fast performance</li>
<li>WCAG compliant</li>
<li>Mobile friendly</li>
</ul>
자주 발생하는 실수
<div>나<span>요소에font-size와font-weightCSS만 사용해 시각적으로 제목처럼 보이게 만들고,role='heading'과aria-level을 추가하거나 실제<h1>–<h6>요소로 전환하지 않는 경우 — 스크린 리더는 이를 탐색 가능한 제목으로 인식할 수 없다.- 폼 입력의 유일한 레이블로
placeholder텍스트를 사용하는 경우. 사용자가 입력을 시작하는 순간 placeholder는 사라져, 입력하는 동안 필드가 레이블 없이 남게 된다. 항상 입력 요소에는 지속적으로 보이는<label>요소를 함께 사용해야 한다. - 필수 필드를 폼 상단의 시각적 범례에서만 설명되는 빨간 별표(*)로 표시하고,
aria-required='true'를 추가하지 않거나 "required"라는 단어를 프로그래밍 레이블에 포함하지 않는 경우 — 스크린 리더 사용자는 동일한 정보를 받지 못한다. <ul>에list-style: none을 CSS로 적용하면서, 일부 스크린 리더(특히 Safari + VoiceOver)가 그 요소를 더 이상 목록으로 읽지 않을 수 있다는 점을 이해하지 못하는 경우 — 목록 시맨틱이 의미가 있다면, 이를 보존하기 위해role='list'를 명시적으로 추가해야 한다.- 디자이너가 더 작은 텍스트를 원한다는 이유로
<h2>바로 다음에<h4>를 배치하는 등 제목 레벨을 건너뛰는 경우 — 올바른 제목 레벨을 사용하고 시각적 모양은 CSS로 제어해야 한다. colspan/rowspan으로 병합된 셀을 가진 복잡한 데이터 표를 만들면서, 데이터 셀에headers속성을 추가하지 않는 경우. 이로 인해 스크린 리더 사용자는 어떤 헤더가 모호한 병합 셀을 지배하는지 알 수 없게 된다.- 레이아웃 목적으로
<table>요소를 사용한 뒤role='presentation'을 일관성 없이 추가하는 경우 — 일부 셀에는 여전히 헤더가 포함되어 맥락 없이 읽히며, 표가 순수하게 장식용이라는 사실을 볼 수 없는 사용자에게 혼란을 준다. - HTML5에서
<dl>안에는<div>래퍼만 허용된다는 점을 이해하지 못한 채,<dt>/<dd>쌍을<p>나<div>로 감싸고 그 요소를<dl>의 직접 자식으로 두는 경우. 다른 블록 요소를 섞으면 정의 목록 구조가 깨진다. - DOM에 존재하지 않는 ID를 참조하는
aria-labelledby를 입력 요소에 추가하거나, 텍스트가 아닌 요소의 ID를 참조하는 경우 — 계산된 접근 가능한 이름이 비어 있게 되어, 해당 입력은 보조 기술에 대해 사실상 레이블이 없는 상태가 된다. - 페이지가 시각적으로 올바르게 보이고 Lighthouse 점수가 90 이상이기 때문에 1.3.1을 준수한다고 가정하는 경우 — 자동화 도구는 ARIA 역할 계층에 반영되지 않은 시각적 중첩 관계 같은 모든 구조적 위반을 감지할 수 없으므로, 수동 및 스크린 리더 검증이 필수적이다.
터키 접근성 규정과의 관계
2025년 6월 21일 관보 제32933호에 게재된 터키 대통령령 2025/10은 터키에서 활동하는 광범위한 주체에 대해 WCAG 2.2와 정렬된 의무적 웹 접근성 의무를 수립한다. WCAG 1.3.1은 레벨 A 기준으로, 준수의 기초 단계 — 최소 허용 접근성 수준 — 에 해당하며, 따라서 이 대통령령의 적용을 받는 모든 주체에게 전면적으로 의무 사항이다.
대통령령은 두 가지 준수 기한을 정의한다. 중앙 정부 기관, 지방자치단체, 국립 대학, 공공 병원을 포함한 공공 기관은 대통령령 발효일로부터 1년 이내에 레벨 A 전면 준수를 달성해야 한다. 규제 대상 민간 부문은 준수를 위해 2년의 기간을 가진다. 그러나 어느 쪽에도 이 의무는 선택 사항이 아니다. 비준수는 규제 당국의 조사와 잠재적 집행 조치에 노출되는 결과를 초래한다.
대통령령에 명시적으로 포함된 민간 부문에는 전자상거래 플랫폼, 은행 및 금융 기관, 민간 병원 및 의료 서비스 제공자, 가입자 200,000명 이상을 보유한 통신 회사, 허가받은 여행사, 민간 운송 회사, 그리고 국립교육부(MoNE)의 인가를 받아 운영되는 민간 학교가 포함된다. 이들 중 어느 주체든 대중이 이용하는 웹사이트나 모바일 웹 애플리케이션을 운영한다면, 그 디지털 자산 전반에서 1.3.1이 충족되도록 해야 한다.
실질적인 준수 관점에서 1.3.1은 페이지의 기본 구조를 규율하기 때문에 가장 영향력이 큰 레벨 A 기준 중 하나다. 제품 카테고리 페이지에서 제목을 스타일링된 <div> 요소로 구현하고, 결제 폼 입력에 레이블 연관성이 없으며, 주문 요약이 scope 속성이 없는 비구조적 표로 되어 있는 터키의 한 전자상거래 사이트는 1.3.1을 전반적으로 위반하게 된다. 시정 조치는 단순한 법적 의무를 넘어, 온라인으로 쇼핑하고, 은행 업무를 보고, 의료 서비스를 이용하며, 정부 서비스에 접근하기 위해 보조 기술에 의존하는 터키 내 추정 70만 명 이상의 시각장애인 및 저시력인의 경험을 직접적으로 개선한다.
준수를 입증하려는 조직은 디지털 콘텐츠 전 범위를 대상으로 자동 axe-core 스캔과 수동 스크린 리더 감사를 모두 수행하는 것이 권장된다. 1.3.1이 강제하는 구조적 접근성은 일회성 시정 작업이 아니라, 콘텐츠가 생성·갱신될 때마다 준수가 유지되도록 디자인 시스템과 컴포넌트 라이브러리에 내재화되어야 한다.
