table 태그에 thead가 없을 때 tbody에 row, col 처리 방법

웹 접근성을 고려해 HTML 테이블을 만들다 보면 <thead> 없이 <tbody>만 사용하는 경우가 있다.
이때 단순히 <td>만 사용하면 스크린 리더가 표 구조를 제대로 이해하지 못할 수 있다.
특히 공공기관 프로젝트나 웹 접근성 인증 대응을 진행할 때 <th scope="row">, <th scope="col"> 처리가 중요한 체크 항목으로 자주 등장한다.

이번 글에서는 <table> 태그에 <thead>가 없을 때 scope="row"scope="col"을 어떻게 사용해야 하는지 실제 예제와 함께 정리해본다.

왜 thead 없이 작성하는 경우가 있을까

실무에서는 항상 <thead>를 사용하는 것이 이상적이지만, 실제 운영 중인 사이트를 수정하다 보면 다음과 같은 구조를 자주 만나게 된다.

  • 게시판 상세 정보 테이블
  • 회원 정보 출력 테이블
  • 관리자 설정 화면
  • 간단한 2열 데이터 테이블
  • 오래된 레거시 소스

예를 들어 아래처럼 작성된 테이블이 많다.

<table>
	<tbody>
		<tr>
			<th>이름</th>
			<td>홍길동</td>
		</tr>
		<tr>
			<th>전화번호</th>
			<td>010-1234-5678</td>
		</tr>
	</tbody>
</table>

브라우저에서는 정상적으로 보이지만, 스크린 리더는 <th>가 어떤 방향의 제목인지 명확히 이해하지 못할 수 있다.

왜 문제가 되는가

웹 접근성에서는 “데이터의 의미 전달”이 매우 중요하다.
시각적으로는 표 구조가 명확해 보여도, 보조기기는 HTML 구조를 기준으로 데이터를 해석한다.

특히 <thead>가 없는 경우에는:

  • 어떤 셀이 제목인지
  • 행 제목인지
  • 열 제목인지

를 명시적으로 알려줘야 한다.

이 역할을 하는 것이 바로 scope 속성이다.

scope=”row”와 scope=”col” 차이

scope=”row”

현재 <th>가 해당 행(Row)의 제목이라는 의미다.
즉, 가로 방향 데이터 설명에 사용한다.

예시:

<table>
	<tbody>
		<tr>
			<th scope="row">이름</th>
			<td>홍길동</td>
		</tr>
		<tr>
			<th scope="row">전화번호</th>
			<td>010-1234-5678</td>
		</tr>
	</tbody>
</table>

이 구조에서는:

  • 이름 → 홍길동
  • 전화번호 → 010-1234-5678

처럼 왼쪽 제목이 오른쪽 데이터를 설명한다.

보통:

  • 회원 정보
  • 주문 정보
  • 상품 상세
  • 설정 화면

같은 “세로형 정보 테이블”에서 많이 사용한다.

scope=”col”

현재 <th>가 해당 열(Column)의 제목이라는 의미다.
즉, 세로 방향 데이터 설명에 사용한다.

예시:

<table>
	<tbody>
		<tr>
			<th scope="col">이름</th>
			<th scope="col">나이</th>
			<th scope="col">지역</th>
		</tr>
		<tr>
			<td>홍길동</td>
			<td>30</td>
			<td>부산</td>
		</tr>
	</tbody>
</table>

이 경우 첫 번째 행이 전체 열의 제목 역할을 한다.

주로:

  • 리스트 테이블
  • 게시판 목록
  • 성적표
  • 통계 데이터

같은 구조에서 사용한다.

실제 사례

예전에 공공기관 유지보수 프로젝트를 진행하면서 웹 접근성 검사 도구에서 아래 항목이 반복적으로 검출된 적이 있었다.

“데이터 셀과 제목 셀의 관계가 명확하지 않습니다.”

원인을 확인해보니 <thead> 없이 <tbody>만 사용하고 있었고, <th>에는 scope 속성이 전혀 없었다.

기존 코드:

<tr>
	<th>제목</th>
	<td>공지사항입니다.</td>
</tr>

수정 후:

<tr>
	<th scope="row">제목</th>
	<td>공지사항입니다.</td>
</tr>

이렇게 변경한 뒤 접근성 검사 오류가 해결되었다.
실제로 오래된 PHP 게시판이나 관리자 페이지에서는 이런 문제가 매우 자주 발생한다.

해결 방법

행 제목이면 scope=”row”

좌측 제목 + 우측 데이터 구조라면 대부분 row다.

<th scope="row">이메일</th>

열 제목이면 scope=”col”

상단 제목 행이라면 col 사용.

<th scope="col">작성일</th>

가능하면 thead 사용 권장

접근성과 유지보수를 고려하면 가장 좋은 방법은 <thead>를 사용하는 것이다.

<table>
	<thead>
		<tr>
			<th scope="col">이름</th>
			<th scope="col">나이</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>홍길동</td>
			<td>30</td>
		</tr>
	</tbody>
</table>

이 구조가 가장 명확하다.

정리

scope="row"scope="col"은 단순한 속성이 아니라,
스크린 리더가 테이블 구조를 올바르게 이해하도록 도와주는 중요한 웹 접근성 요소다.

특히 <thead> 없이 작성된 테이블에서는 거의 필수라고 봐도 된다.

정리하면:

  • 좌측 제목 → scope="row"
  • 상단 제목 → scope="col"
  • 가능하면 <thead> 사용
  • 웹 접근성 검사 시 자주 확인되는 항목

레거시 PHP 프로젝트를 유지보수하다 보면 이런 구조를 자주 만나는데, 작은 수정만으로 접근성 품질을 크게 개선할 수 있다.