목록으로
KRDS 체크리스트 분석

표는 표답게 마크업하라

이번 365편은 데이터의 구조를 적절하게 반영하여 마크업하라는 규칙입니다.

VViewCheck Insight
·2026.07.22 5분 21
표는 표답게 마크업하라
KRDS CP-245 — 데이터의 구조를 적절하게 반영하여 마크업하고 있다.

0. 들어가며 — 보이는 격자를 코드로도

이번 365편은 데이터의 구조를 적절하게 반영하여 마크업하라는 규칙입니다.

표는 행·열의 격자로 데이터 관계를 보여줍니다 — 시각 사용자는 이 격자를 눈으로 보죠. 그런데 스크린 리더 사용 자에게 이 관계가 전달되려면 — 표를 시맨틱하게(<table>/<th>/<td>) 마크업해야 합니다. CSS로 격자처럼 보이게만 만든 <div> 표는 스크린 리더에 관계가 안 전달되죠. CP-245는 데이터 구조에 맞는 시맨틱 마크업을 규정합니다. 이번 편을 풀어냅니다.

1. 규칙 원문 — 데이터 구조 적절 마크업

CP-245 (컴포넌트 > 표) “데이터의 구조를 적절하게 반영하여 마크업하고 있다.”

표 데이터의 구조(행·열·머리글 관계)를 <table>/<tr>/<th>/<td> 등 시맨틱 태그로 정확히 마크업해, 보조 기술이 데이터 관계를 인지하게 하라는 뜻입니다.

정리: 표 데이터 구조를 시맨틱 태그로 정확히 마크업하라. 이게 CP-245입니다.

2. 왜 데이터 구조를 시맨틱하게 마크업하나

표의 핵심은 — ’데이터의 관계’입니다. 어느 값이 어느 행(항목)에 속하고 어느 열(속성)에 해당하는지, 어느 머리글의 데이터인지죠. 시각 사용자는 격자 배치로 이 관계를 한눈에 봅니다 — “이 값은 ‘홍길동’ 행의 ‘전화’ 열”. 하지만 스크린 리더 사용자는 이 시각적 격자가 안 보이므로, 관계가 코드(시맨틱 마크업)로 전달돼야 합니다.

시맨틱 표 마크업의 핵심 요소:

<table> — 표 전체를 감싸 ’이건 데이터 표’임을 알림. 스크린 리더가 “표, N행 N열”로 안내하죠.

<tr> — 각 행.

<th> (머리글 셀) — 열 머리글·행 머리글. scope 속성으로 그것이 열 머리글(scope="col")인지 행 머리글(scope="row")인지 명시하죠. 이게 핵심입니다 — <th scope="col">전화</th>면 그 열의 모든 값이 ‘전화’ 임을, <th scope="row">홍길동</th>면 그 행의 모든 값이 ’홍길동’의 것임을 전합니다.

<td> (데이터 셀) — 일반 데이터 값.

<caption> — 표의 제목/설명. 스크린 리더가 표에 진입할 때 읽어 ‘이게 무슨 표인지’ 알리죠.

(복잡한 표) headers/id — 셀 병합·다단계 머리글 같은 복잡한 표는 headers 속성으로 각 셀이 어느 머리글 들에 속하는지 명시.

이렇게 마크업하면 — 스크린 리더가 각 셀을 읽을 때 관련 머리글을 함께 안내합니다. 예를 들어 “홍길동 행, 전화 열, 010-…” 처럼요. 비시각 사용자가 셀 값만이 아니라 ’이 값이 무엇인지(어느 항목의 어느 속성)’를 알죠. 표 내비게이션(스크린 리더의 표 모드)으로 셀 사이를 이동하며 관계를 파악합니다.

잘못된 마크업 가짜 표. 흔한 실수는 표를 <div>들에 CSS로 격자처럼 보이게만 만드는 것(CSS grid/flex). 시각적으로는 표처럼 보여도 스크린 리더에겐 그냥 텍스트 덩어리라, 행·열·머리글 관계가 통째로 사라지죠. 비시각 사용자는 ‘어느 값이 어느 항목·속성인지’ 전혀 모릅니다. 데이터 표는 반드시 <table> 시맨틱으로 만들어야 하죠. (반대로 레이아웃 목적으로 <table>을 쓰는 것도 잘못입니다. <table>은 데이터 표에만.)

‘데이터 구조를 적절하게’. 규칙의 ’적절하게’는 — 표의 실제 구조에 맞게 마크업하라는 뜻입니다:

단순 표 → <th scope> + <td>.

행 머리글이 있는 표 → 행 머리글도 <th scope="row">.

복잡한 표(다단계 머리글·병합) → headers/id로 정확히 연결.

표 제목 → <caption>.

구조를 단순화하거나(복잡한 표는 가능하면 나누기), 정확히 마크업해 관계가 왜곡 없이 전달되게 하죠.

이 규칙은 표 접근성의 토대입니다 — 시각 격자(CP-239 셀·행, CP-240 정렬)를 코드 구조로 반영해, 모바일 배열 변경(CP-243)·가로 스크롤(CP-244)에서도 관계가 유지되게 하죠. 정렬 기능(aria-sort CP-241), 빈 셀(CP-242) 도 이 시맨틱 위에서 작동합니다. 사이드 메뉴 CP-099, 아코디언 CP-199에서 본 ’시각 구조를 시맨틱으로’의 표 버전이죠.

정리하면 — 표의 데이터 관계가 스크린 리더에 전달되려면 <table>/<th scope>/<td>/<caption> 등 시맨틱 태그로 데이터 구조를 정확히 마크업해, 비시각 사용자도 ’어느 값이 어느 항목·속성인지’를 알게 해야 합니다.

3. 점검 / 개선

무엇을 점검하나

시맨틱 표 — 데이터 표가 <table>/<tr>/<th>/<td>로 마크업됐는가(가짜 div 표 아님).

머리글 scope — <th>에 scope="col"/"row"가 명시됐는가(복잡하면 headers/id).

caption — 표 제목이 <caption>으로 제공되는가.

개선 방향

데이터 표를 <table> 시맨틱으로. 머리글 <th scope>, 제목 <caption>.

복잡한 표는 headers/id 연결 또는 구조 단순화. 가짜 div 표 제거.

4. 누가 담당하나 / 우리 사이트에 해당될까?

역할책임
퍼블리셔/개발<table>/<th scope>/<caption> 시맨틱 마크업
접근성 담당스크린 리더 표 관계 인지 검증
기관 유형CP-245 적용
중앙행정기관(대표·운영) / 공공기관 / 지자체✅ 필수 (표 사용 시)

웹접근성 의무 대상인 모든 공공 사이트가 해당됩니다.

5. 30초 자가진단 + FAQ

✅ 30초 자가진단

□ 데이터 표가 <table>/<th>/<td> 로 마크업됐나요(가짜 div 표 아님)?

□ <th>에 scope="col"/"row"가 명시됐나요?

□ 표 제목이 <caption>으로 제공되나요?

❓ FAQ

Q1. CSS로 표처럼 보이게 하면 안 되나요? 시각적으론 표여도 스크린 리더는 관계를 못 읽습니다. <table> 시맨틱이 필요하죠. Q2. scope가 왜 중요한가요? <th scope>로 머리글을 명시하면 스크린 리더가 각 셀을 읽을 때 관련 머리글을 함께 안내합니다(“홍길동 행, 전화 열, …”). Q3. 복잡한 표는요? 다단계 머리글·병합은 headers/id로 정확히 연결하거나, 가능하면 구조를 단순화합니다.

6. 마무리

CP-245의 메시지:

표는 표답게 마크업하라 — 데이터 구조를 <table>/<th scope> 시맨틱으로 반영하라.

표의 데이터 관계가 스크린 리더에 전달되려면 시맨틱 마크업이 필수입니다. CSS로 격자처럼 보이게만 만들면 관계가 사라지죠. <table>/<th scope>/<caption>으로 구조를 정확히 반영해 비시각 사용자도 관계를 인지하게 합니다. 다음 편은 표 그룹의 마지막 — 가로 스크롤 위치 조정입니다.

다음 편 예고 ▶ 「366. (CP-246) 가로 스크롤이 필요한 경우 단순한 동작으로 스크롤 위치를 조정할 수 있도록 하고 있다.」

ViewCheck는 표가 데이터 구조를 반영한 시맨틱 마크업인지를 진단합니다.

📚 참고 출처

KRDS 컴포넌트 — 표(Table) 가이드 — https://www.krds.go.kr/html/site/component/component_22.html

WCAG 2.1 SC 1.3.1 Info and Relationships — https://www.w3.org/WAI/WCAG21/Understanding/info-and-relationships.html

KRDS #ViewCheck #공공웹사이트 #전자정부 #디지털정부 #웹접근성 #디자인시스템 #UIUX #UI컴포넌트 #웹표준

KRDS,ViewCheck,공공웹사이트,전자정부,디지털정부,웹접근성,디자인시스템,UIUX,UI컴포넌트,웹표준

#KRDS#공공웹#컴포넌트##테이블#시맨틱마크업#데이터구조#table태그

관련 글