
반응형, data-label, 접근성. 내 눈엔 멀쩡했는데 핸드폰에서 깨진 그 날.
블로그에 비교표를 올렸을 때 내 눈엔 깔끔하게 보였다. 데스크탑 화면에서 컬럼이 딱딱 맞아 떨어지고, 텍스트도 잘 들어가 있었다. 뿌듯한 마음으로 저장하고 나서 핸드폰으로 확인했는데, 표가 화면 밖으로 반쪽 이상 튀어나와 있었다. 마치 옷장에 양복을 넣으려는데 소매가 문 밖으로 빠져나온 것 같은 기분이었다. 억지로 접어 넣어도 다음날 보면 또 삐져나와 있는 그 느낌.
그때 처음 든 생각은 '내가 뭘 잘못한 건가'였다. HTML 태그도 맞게 썼고, 내용도 제대로 들어가 있었다. 문제는 내가 아니라 HTML 표 자체가 모바일 우선 시대 이전에 설계된 요소라는 데 있었다. 기본 동작이 "내 열 너비만큼 공간이 있어야 한다"는 것이라서, 화면이 좁으면 그냥 삐져나와 버린다. 내가 잘못 만든 게 아니라 애초에 그렇게 만들어진 것인데, 그걸 나중에야 알았다. 그 황당함이 계기가 되어 반응형 표 처리 방식을 제대로 파고들게 됐다.
요즘 블로그 방문 트래픽의 60~70%가 모바일인 걸 생각하면 표 하나 망가진 게 보기 싫은 수준이 아니라 이탈률 문제다. 그 이후로 표를 만들 때마다 모바일 뷰를 먼저 확인하는 버릇이 생겼다. 데스크탑에서 예쁜 표가 모바일에서 깨지면 방문자 절반은 그냥 나가버린다.
반응형 표 구조: 일반적인 믿음과 실제 차이
HTML 표를 제대로 짰으면 어느 화면에서나 잘 보일 거라고 생각하는 분들도 있다. 나도 그렇게 믿었다. 스마트폰 요금제 비교표를 처음 만들었을 때였다. thead, tbody, th, td를 정석대로 나눠 쓰고, 배경색도 교대로 넣어서 꽤 만족스러운 결과물이었다. 그런데 핸드폰으로 열어보니 오른쪽 두 열이 화면 밖으로 완전히 잘려 있었고, 가로 스크롤조차 되지 않았다.
여기서 thead란 표의 헤더 행을 감싸는 시맨틱 태그로, 쉽게 말해 표 위쪽에 들어가는 열 제목 묶음이다. 시맨틱 태그란 HTML 요소에 의미를 부여하는 태그를 의미하며, 브라우저와 스크린 리더가 콘텐츠를 올바르게 해석하는 데 쓰인다. 이 구조를 제대로 잡지 않으면 보조 기술이 표를 인식하지 못하는 접근성 문제로 이어진다. 처음에는 이게 SEO나 접근성과 무슨 관계가 있나 싶었는데, 구조가 명확하지 않으면 정보를 전달받아야 할 사람 중 일부가 아예 배제된다는 걸 알고 나서 생각이 달라졌다.
내가 처음 시도한 해결책은 표를 감싸는 래퍼 div에 overflow-x: auto 속성을 추가하는 방법이었다. overflow-x: auto란 콘텐츠가 컨테이너 너비를 초과할 때 가로 방향으로 스크롤 가능한 영역을 자동으로 생성하는 CSS 속성이다. 이 한 줄만 추가했는데 가로 스크롤이 생기면서 잘리던 열이 보이기 시작했다. 그런데 문제가 하나 남았다. 사용자가 옆으로 스크롤할 수 있다는 걸 모를 수 있다는 점이었다. 그래서 표 위에 "좌우로 스크롤하세요"라는 안내 문구를 별도로 추가했다. 작은 디테일이지만, 이걸 빠뜨리면 독자가 정보의 절반을 그냥 놓치고 떠난다.
이게 불편한 해결책이라는 걸 나는 안다. 가로 스크롤 자체가 모바일에서 자연스러운 동작이 아니기 때문이다. 그럼에도 쓰는 이유는, 열이 많거나 데이터 갱신이 잦은 표에서 다른 방법보다 유지 관리가 훨씬 단순하기 때문이다. 완벽한 방법이 없을 때 현실적인 선택을 하는 것도 블로그 운영의 일부라고 생각한다.
반응형 표를 만들 때 체크해야 할 핵심 포인트를 정리하면 이렇다. 표를 래퍼 div로 감싸고 overflow-x: auto를 적용해 가로 스크롤을 허용해야 한다. thead, tbody, th, td 시맨틱 구조를 반드시 갖춰야 하고, caption 태그와 scope 속성으로 접근성을 챙겨야 한다. 모바일 분기점에서 미디어 쿼리로 세로 쌓기 레이아웃을 적용하는 것도 고려해야 한다.
data-label 세로 쌓기 방식: 효과적이지만 유지 보수 비용이 있다
data-label 방식은 각 td 셀에 data-label이라는 HTML 속성을 직접 넣고, CSS에서 그 값을 화면에 출력하는 방식이다. 덕분에 모바일 환경에서 헤더 셀이 화면에서 사라져도 각 td가 자기 라벨을 직접 표시할 수 있다. 완성하고 핸드폰으로 열어보는 순간, 각 행이 카드처럼 세로로 쌓여서 훨씬 읽기 편한 화면이 나왔다. 그때부터 표를 만들면 모바일 뷰를 먼저 확인하는 게 습관이 됐다.
그런데 이 방식이 항상 옳다고 말하기는 어렵다. data-label 세로 쌓기 방식은 비교 목적의 표, 즉 각 행이 독립적인 데이터를 담을 때 강점을 발휘한다. 하지만 행과 열의 교차점을 봐야 하는 행렬형 표에서는 세로 쌓기가 오히려 정보 파악을 더 어렵게 만든다. 행렬형 표란 행과 열 양쪽에 모두 헤더가 있고, 그 교차 지점에서 의미가 완성되는 구조의 표다. 이런 표를 세로로 쌓으면 맥락이 끊긴다.
유지 보수 측면에서도 현실적인 단점이 있다. 열 제목이 바뀔 때마다 HTML의 모든 td에 붙은 data-label 속성을 일일이 수정해야 한다. 열이 많고 데이터 갱신이 잦은 표라면 오히려 관리 비용이 늘어난다. 한 번은 요금제 비교표의 열 이름을 바꿨다가 data-label을 열두 군데 수정해야 했던 적이 있다. 그때 이 방법이 편한 게 아니라 처음에만 편한 방법이라는 걸 깨달았다.
반응형 웹 디자인의 원칙은 콘텐츠를 어떤 화면에서도 접근 가능하게 만드는 것이지, 특정 기법을 무조건 적용하는 게 아니다. 내 경험상, 표의 성격을 먼저 파악하고 방식을 선택하는 게 맞다. 단순 비교표라면 data-label 세로 쌓기, 데이터 갱신이 잦거나 열이 많은 표라면 래퍼 div 가로 스크롤 방식이 더 현실적이다.
표는 만드는 사람 기준이 아니라 읽는 사람 기준으로 만들어야 한다. 내 화면에서 예쁘면 완성이 아니라, 독자의 화면에서 안 깨지면 완성이다. 당연한 말 같지만, 직접 반쪽짜리 표를 마주하기 전에는 잘 와닿지 않았다. 표를 만들고 나면 반드시 모바일 화면으로 한 번 더 확인하는 것, 그게 지금 내가 지키는 가장 기본적인 규칙이다. 크롬 개발자 도구에서 모바일 에뮬레이터를 열어보는 데 10초도 안 걸린다. 그 10초가 독자 이탈을 막아준다.
참고
- MDN Web Docs
- CSS-Tricks – Responsive Data Tables
- W3Schools – CSS Tables
- web.dev – Responsive web design basics