본문 바로가기

업무이야기

table 태그 웹 접근성 - caption, scope 중심으로

 

Table 웹 접근성 - caption, scope을 중심으로

table 태그의 접근성에 대해서 정확히 한 번 짚고 정리해두는 것이 좋을 것 같아 포스팅을 작성합니다. 

table은 데이터 테이블과 디자인을 위한 레이아웃 테이블로 나뉠 수 있습니다. 레이아웃을 위해 사용하더라도 접근성에 맞는 기준이 무엇인지는 잘 알고 있어야 접근성에 맞춰 사용해야 할 상황에서 잘 사용할 수 있을 것 같습니다. 

 

table 태그의 웹 접근성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<table>
    <caption>테이블 태그 접근성에 대한 예제</caption>
    <colgroup>
        <col style="width: 25%;" />
        <col />
        <col />
    <colgroup />
    <thead>
        <tr>
            <th scope="col">구분</th>
            <th scope="col">제목1</th>
            <th scope="col">제목2</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">구분1</th>
            <td>내용</td>
            <td>내용</td>
        </tr>
        <tr>
            <th scope="row">구분2</th>
            <td>내용</td>
            <td>내용</td>
        </tr>
    </tbody>
</table>
cs

 

 

데이터 테이블과 레이아웃 테이블의 구분

데이터 테이블

  • th가 존재한다.
  • th가 scope속성을 가지고 있다. 
  • caption을 가지고 있다.
  • thead 영역에는 td 태그가 올 수 없다.
  • tbody만 사용하거나 thead와 tbody만 있는 경우, thead, tbody, tfoot 어느것이든 생략 가능하며 한 테이블에 여러번 사용해도 상관없다.

레이아웃 테이블

  • th, caption, scope을 사용하지 않는다.

스크린 리더기는 caption과 th 유무 등으로 데이터 테이블과 레이아웃 테이블을 구분해서 레이아웃 테이블로 판단할 경우 소스코드를 순서대로 읽습니다. 하지만 이러한 디자인을 위한 레이아웃 테이블은 css를 사용할 것을 권하며 웹 접근성을 위해 지양하는 형태입니다. 

 

caption과 summary 

caption은 말 그대로 '제목'이며 summary는 표 내부에 대한 설명을 적어주는 것입니다. 예를 들어서 테이블의 캡션이 '테이블 태그 접근성 예제'라면 summary는 '구분 제목 1 제목 2 부제목 1 부제목 2'가 됩니다. 그러나 html5에서는 summary가 사라졌습니다. 아마도 summary를 적는 대신 테이블에 대한 설명을 <p></p> 태그에 빼라는 의미일 수도 있겠습니다.

 

caption

접근성을 위해서 테이블의 캡션은 필요한 요소입니다. 테이블 요소 바로 다음에 위치하며 보통 캡션을 사용하고 css로 숨기는 스타일을 입혀줍니다. 이때, 'display:none' 처리하지 않고 아래와 같은 스타일을 적용합니다. display:none처리 시 스크린 리더리가 caption을 빼고 읽게 됩니다.

1
2
3
4
5
6
7
8
9
10
11
.sr-only {
    position: absolute;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}
cs

 

 

scope

th가 thead에 있든 tbody에 있든 th태그라면 웹 접근성을 위해 scope 속성을 넣어주어야 합니다. scope은 스크린 리더기에서 읽히는 순서에 관여하게 됩니다. thead에 있는 th의 scope="col" 속성부터 읽게 될 것입니다. 가장 위의 예시 코드를 스크린 리더기로 읽을 시 구분→구분 1→제목 1→내용→제목 2→내용 순으로 읽히게 될 것입니다. 

제가 헷갈렸던 부분은 rowgroup과 colgroup에 관한 것이었습니다. 

 

상품 상품1
상품2
상품3
상품4
 
상품 상품1 a
b
상품2 c
d

단순하게 생각하면 rowspan과 colspan이 사용된 cell에 colgroup과 rowgroup을 주면 되는 것 같았지만 혼돈의 시작은 위와 같은 예시에서 시작되었습니다. 우측 표의 '상품'은 당연히 'rowgroup'을 주는 것이 맞아 보이지만 좌측 표의 '상품'에 대해서는 'rowgroup'을 주어야 할지 'row'를 주어야할지 헷갈렸습니다. 결과적으로 위의 표처럼 단순하다면 좌측과 우측의 '상품' 모두 scope 속성에 'rowgroup'이 맞을 것입니다. '상품'이란 카테고리 안에 '상품 1~4', 'a~d'까지 모두 포함되어 있기 때문입니다.

그러나 조금 더 복잡한 표의 경우라면 rowspan을 사용했다고 단순히 rowgroup을 사용하면 안 될 것 같았습니다. 웹 접근성 연구소에 질문 게시판에 있는 질문글의 답변을 보니 부제목 1의 경우 scope을 'rowgroup'으로 제공 시 '내용 2~내용 7'까지 모두 적용된다는 것이었습니다. 따라서 아래와 같은 표를 작성할 시 rowgroup을 사용하려면 tbody를 두 번 사용해서 부제목 1과 부제목 2 영역을 만들어 주어야 할 것으로 생각됩니다.

제목1 제목2 제목3 제목4
부제목1 부부제목1 내용2 내용3
부부제목2 내용4 내용5
부제목2 부부제목3 내용6 내용7

 

scope 속성 'colgroup' 또한 마찬가지인 것으로 보입니다. 따라서, 'colgroup'과 'rowgroup'사용 시 colspan과 rowspan이 사용되었다고 단순히 scope 속성을 줄 것이 아니라 'colgroup' 혹은 'rowgroup'이 모든 내용을 포함할 수 있는가는 생각하셔야 할 듯합니다.  

아래 코드 펜 링크로 들어가셔서 scope 'rowgroup'과 'colgroup'의 적용 범위를 확인해보시면 좋을 것 같습니다.

https://codepen.io/mctenshi/pen/aKkCH

반응형