며칠 전 친구 몇 명과 잡담을 나누다가 나온 이야기가 있다. 그중 한 명이 HTML에서 <article>
태그와 <section>
태그가 어떻게 다른지를 물어왔다. 이는 웹 개발 역사와 함께 이어져온 유구한 질문 중 하나다. 비슷한 질문으로는 아마도 “도대체 왜 white-space: no-wrap이라고 하지 않고 꼭 white-space: nowrap이라고 쓰는 걸까?” 혹은 “왜 HTML 색상 정의에서 회색gray은 어두운 회색dark gray보다 더 어두운 걸까?” 등이 있을 것이다.
난 그냥 늘 하던 대로 답했다. <article>
을 단지 신문이나 블로그 기사article로 여기지 말고 옷 한 벌an article of clothing이라고 생각하면 된다고. 옷은 상황에 맞춰 여러 번 다시 입을 수 있다. 바지 한 벌로 다른 옷들과 함께 다양하게 입을 수 있고, 셔츠도 서로 다른 바지와 함께 여러 방식으로 입을 수 있다. 무릎까지 오는 가죽 부츠도 일종의 의상이다. 부츠만 신고 외출할 수는 없는 일 아닌가!
<article> 태그에 대한 공식적인 사양은 다음과 같다.
Article 요소는 문서, 페이지, 애플리케이션에 포함되며, 그 자체로도 독자적으로 완성된 내용을 담고 있다. 원칙적으로 Article 요소에 담긴 내용은 기사 통합 서비스 등을 통해서 따로 배포되거나 재사용할 수 있다. Article 요소의 내용은 게시판 글이 될 수도 있고, 잡지나 뉴스의 기사, 블로그에 올린 글, 사용자가 올린 댓글, 상호작용할 수 있는 기능 모듈을 비롯해서 다른 어떤 종류의 독립적인 콘텐츠도 될 수 있다.
다시 말해서, 홈페이지에 블로그 글을 나열했다면 그것은 <main>
태그 안에 각 블로그 글을 하나씩 <article>
태그에 넣어 나열한 형식일 것이다. 블로그가 아니라 유튜브 홈페이지 같은 경우라면 동영상을 <article>
태그에 나열할 수 있을 것이고, 아마존 같은 사이트라면 상품 정보를 하나씩 <article>
에 넣어 나열하는 식이 될 것이다. 이 모든 <article>
은 말하자면 다른 형식으로 추출해서 제공할 수 있는 콘텐츠다. 스스로 독자적인 페이지가 되기도 하지만 다른 페이지에 광고로 등장할 수도 있고, 뉴스레터 기사 중 하나로 나타날 수도 있다.
애플 watchOS의 읽기 모드는 <article>
태그를 통해서 페이지의 본문을 파악한다. 애플의 설명을 들어보자.
새로 소개된 watchOS5의 읽기 모드는 글이 많은 웹 페이지를 열 때 자동으로 시작합니다. 읽기 모드가 웹 페이지 내용에서 중요한 부분을 제대로 선별하려면 그 문서에 포함된 각 요소의 의미와 목적을 부각하도록 의미를 담은 코딩semantic markup을 해야 합니다. 예를 하나 들어봅시다. 먼저, 페이지의 어느 부분이 가장 중요한 부분인지를 표시하기 위해 그 부분을 <article> 태그 안에 넣습니다.
<article> 태그를 HTML5의 마이크로 데이터와 함께 사용하면 작은 시계 화면에서도 최적의 화면을 구성할 수 있도록 할 수 있다.
특히 <header> 요소를 <article> 안에 포함하면 읽기 모드에서 함께 표시됩니다. 읽기 모드는 각각의 <header> 요소를 itemprop 설정에 따라 다르게 보여줍니다. Itemprop를 이용하면 글의 저자, 출간일, 제목, 부제목 등을 눈에 잘 띄게 표시할 수 있습니다.
그럼 <section> 태그는 어디에 쓰는가?
나는 이 질문에 언제나 <section>
에 대해서는 신경 쓸 필요도 없고, 그것이 <article>
태그와 어떻게 다른지 고민할 필요도 없다고 말한다. <section> 태그는 애당초 웹 브라우저가 HTML5 문서의 목차를 정할 수 있도록, 각각의 제목과 그에 따른 내용을 담기 위한 보편적인 용도의 컨테이너로 만들어졌다.
목차가 무슨 상관이냐고? 문서에서 목차를 인식하는 알고리듬은 제목 태그를 하나만 써도 (다시 말해서 <h1>
만 써도) 그 제목이 <article>
, <section>
같은 HTML5의 구획 요소에 의해 얼마나 깊이 둘러싸여 있는지에 따라 스스로 올바른 깊이의 제목이 되도록 (다시 말해서 <h2>
나 <h3>
으로 변하도록) 조정한다.
예를 들어서, CMS(Content Management System, 웹사이트의 기사 내용을 표준화된 양식으로 모아서 관리하는 시스템 – 옮긴이)에 다음과 같은 내용이 들어 있다고 하자.
See the Pen <a href=’https://codepen.io/wabooks/pen/KKpqeWJ’>KKpqeWJ</a> by wa (<a href=’https://codepen.io/wabooks’>@wabooks</a>) on <a href=’https://codepen.io’>CodePen</a>.
이 글을 독자적으로 보여주는 데는 아무 문제가 없다. 하지만 홈페이지에 최근 글 목록의 형식으로 이 글을 표시하고 싶다면 어떨까?
See the Pen <a href=’https://codepen.io/wabooks/pen/BaNZxoz’>BaNZxoz</a> by wa (<a href=’https://codepen.io/wabooks’>@wabooks</a>) on <a href=’https://codepen.io’>CodePen</a>
HTML에 정의된 바에 따르면 <section>
과 마찬가지로 <article>
은 구획을 짓기 위한 요소이므로, 앞의 사례에서 <article>
안에 들어 있는 <h1>
은 논리적으로 따지면 <h2>
가 되어야 한다.
참고: 이런 방식이 새로운 개념은 아니다. 인터넷의 창시자로 불리는 팀 버너스 리Tim Berners-Lee는 1991년에 다음과 같은 이메일을 보내기도 했다.
미국 출판 협회American Publishers’ Association의 문서 표준Document Type Definition에서 따온
<h1>
이나<h2>
같은 것으로 제목을 특정하기보다, 내 생각에는<section>
요소에 각 구획을 포함하고 구획의 제목을 모두 똑같이<h>
태그로 표시해서 그 구획이 얼마나 깊이 들어가 있는지에 따라 제목의 깊이를 정하도록 하는 편이 더 좋겠습니다.
불행히도 HTML5의 이 목차 인식 기능을 구현해놓은 웹 브라우저는 전혀 없다. 굳이 <section>
태그를 써야 할 이유가 없는 것이다. JAWS 스크린리더가 목차 인식 기능을 자체적으로 (인터넷 익스플로러에서만) 구현하려고 한 적이 있었지만 버그가 너무 많았다. 웹 브라우저 개발자들은 이 기능을 구현하는 데 영 관심이 없는 것 같다. (구체적인 사정을 알고 싶다면 이 글 마지막에 ‘추천 문헌 목록’을 참조하자.)
그런 이야기를 한창 하고 있을 때, 옆에 있던 다른 친구가 끼어들었다. “그런데 말이야, 요즘 브라우저에서는 <section>
에 얼마나 여러 번 둘러싸여 있는지에 따라서 <h1>
글자 크기가 달라지잖아.” 그 친구는 바로 사례를 보여줬고, 나는 놀라지 않을 수 없었다.
여기 간단한 데모를 만들어두었다. 왼쪽 줄은 <h1>
네 개를 하나씩 점점 더 깊이 <section> 태그로 둘러싼 것이며, 오른쪽 줄은 <h1>
, <h2>
, <h3>
, <h4>
를 다른 요소에 둘러싸지 않고 나열한 것이다. 파이어폭스 브라우저에서 <section>에 둘러싸인 <h1>
요소들의 크기는 기존 방식으로 정의한 <h1>
…<h4>
요소 크기와 같다.
이 결과는 크롬, 크로미움 기반 브라우저(이를테면 Mac OS에서 구동하는 엣지Edge 베타), Mac OS에서 실행한 사파리 브라우저에서 모두 동일하게 나타난다. 자, 그렇다면 우리는 내용의 구획에 따라 <section>
을 나누고, 그 안에 들어가는 모든 헤딩을 <h1>
태그로 표시하면 되는 걸까?
그렇지는 않다. 이 방식은 <h1>
의 겉모습만 바꿀 뿐이다. <section>
에 한 번 포함된 <h1>
의 헤딩 ‘level 2’가 겉보기엔 <h2>와 똑같아 보일 수 있다. 하지만 파이어폭스 개발자 도구에 있는 접근성 검사 기능을 열어보면, 접근성 트리에는 여전히 헤딩의 깊이가 ‘1’로 등록되어 있음을 알 수 있다.
이제 앞의 사례 오른쪽에 있는 진짜 <h2> 헤딩과 비교해보자.
<h2> 태그를 쓴 헤딩은 접근성 트리에서 제대로 인식되는 것을 알 수 있다. 모질라Mozilla는 이 차이점에 대해 다음과 같이 설명했다.
그 부분에 대해서는 저희도 실험을 좀 해봤습니다. 사내 접근성 팀에서 검토한 결과 (의도하지 않게
<h1>
의 깊이 수준이 낮아지는 등) 오히려 나쁜 점들이 많다고 해서 기능을 제외하게 되었습니다.
보조 기술을 사용하는 사람들에게는 페이지의 목차가 순차적으로 정리되어 있는 것이 무엇보다도 중요하다. 제8회 웹에임WebAIM 스크린리더 사용자 연구 조사 결과는 이 사실을 잘 보여준다.
제대로 된 목차 구조의 유용성에 대한 문항에서, 응답자의 86.1퍼센트가 목차의 구조를 아는 것이 매우 혹은 어느 정도 유용하다고 대답했습니다.
결국 우리는 계속해서 <section>
태그는 무시하고 <h1>
부터 <h6>
까지의 태그를 사용해서 제목을 표시해야 한다는 것이다.
절대로 안 된다는 법은 없다
“하지만······ 이 페이지에서도 <section>
요소를 썼잖아요!” 이 글을 읽는 분들 중에 이렇게 말할 사람이 있을지도 모르겠다. 그 말이 맞다. ‘간단 요약’ 항목은 보다 나은 접근성을 제공하기 위해서 <section>
요소에 담겨 있다. 스크린리더 사용자 레오니 왓슨Léoni Watson은 “스크린리더 사용자가 웹에 접근하는 방법”이라는 온라인 강의 중에 스매싱 매거진 웹사이트를 읽을 때의 경험을 개선하기 위해 마크업을 조금 수정하면 좋겠다는 제안을 했다.
아래 스크린샷에서 볼 수 있듯이, 스매싱 매거진 기사는 맨 앞에 ‘간단 요약’ 항목이 나오고, 그 뒤에 가로선으로 기사의 본문과 요약문을 나눈다.
하지만 그 가로선은 단지 장식이어서, 어디서 요약이 끝나고 기사가 시작되는지를 알 수 없었다. 레오니 왓슨은 요약문을 <section>
요소 안에 넣으면 이 문제를 해결할 수 있을 것이라는 제안을 했다.
See the Pen <a href=’https://codepen.io/wabooks/pen/oNXwyWB’>oNXwyWB</a> by wa (<a href=’https://codepen.io/wabooks’>@wabooks</a>) on <a href=’https://codepen.io’>CodePen</a>.
대부분의 스크린리더는 따로 ‘접근 가능 이름accessible name’이 부여되지 않은 이상 <section>
요소를 언급하지 않는다. 이 경우에는 aria-label을 이용해서 접근 가능한 이름을 부여했다. 이렇게 되면 스크린리더는 사용자가 ‘간단 요약 영역’에 들어간다는 사실을 안내해주고, 다 읽으면 ‘간단 요약 영역 끝’이라고 알려준다. 이 간단한 마크업은 스크린리더 사용자가 원한다면 요약 부분을 건너뛸 수 있게 해준다.
<section> 대신 가장 기초적인 <div>
태그를 사용할 수도 있지만, 그런 접근 방식에 대해서는 마르코 제에Marco Zehe가 다음과 같은 말을 한 적이 있다.
어떤 영역에 aria-label이나 aria-labelledby를 써서 이름을 붙이는 경우, 그 영역의 role(용도)은 제대로 된 위젯widget이나 문서 구성landmark으로 설정하는 것이 가장 기본적인 원칙이다.
<div role=“region” aria-label=“간단 요약”>
이라고 하기보다 <section>
태그를 이용해서 HTML에 내재된 용도 정보를 활용하는 편이 낫다. “ARIA에 대한 절대 원칙: 언제나 기본 정보를 쓰는 것이 부가 정보를 더하는 것보다 훨씬 낫다”라고 내가 한 말에도 부합한다.
맺음말
이 글을 통해서 독자 여러분이 다음 몇 가지를 이해했으면 좋겠다.
<h1>
을 여기저기 잔뜩 쓰지 말 것. 페이지의 주 제목으로<h1>
을 쓰고, 다음으로는<h2>
,<h3>
,<h4>
… 이런 식으로 순차적으로 제목의 깊이를 정한다.- 글의 특정 영역이 시작하고 끝나는 지점을 스크린리더 사용자가 알아챌 수 있게 하려면
<section>
과 aria-label을 사용하라. 그런 목적이 아니라면 그냥 다른 태그를 쓰도록 하자. 이를테면<aside aria-label=“간단 요약”>
이라고 한다거나, 굳이 <div> 태그를 써야 할 이유가 있다면<div role=“region” aria-label=“간단 요약”>
이라고 쓸 수도 있겠다. <main>
,<header>
,<footer>
,<nav>
등은 스크린리더 사용자에게 매우 유용한 태그이며, 보조 기술을 사용하지 않는 사람들에게는 아무 영향을 주지 않는다. 적극적으로 활용하자.<article>
은 블로그 글만을 위해서 만들어지지 않았으며, 독자적으로 완성된 콘텐츠는 무엇이든 담을 수 있다. 특히 watchOS에 콘텐츠가 제대로 표시될 수 있게 하는 데 큰 도움이 된다.
이 글을 작성하면서 레오니 왓슨에게 많은 도움을 받았다. 글에 오류가 있다면 그것은 모두 레오니 잘못이다.
추천 문헌 목록
- “헤딩과 섹션” – HTML 5.2 W3C 제안서(2017년 12월 14일)
다음 문구에 주목할 것: “현재 목차 인식 알고리듬이 구현된 사례는 알려져 있지 않으며, 따라서 사용자에게 문서의 구조를 전달하기 위해 목차 인식에 의존할 수는 없다. 웹 페이지를 만들 때에는 <h1>부터 <h6>까지의 헤딩을 사용해야 한다.” - “목차 인식 알고리듬은 구현되지 않았다” – 에이드리언 로젤리Adrian Roselli
<section> 태그로 각 구획을 나누는 알고리듬의 변천사를 소상하게 밝혀놓은 글. - “HTML에 적용된 ARIA” – W3C 편집자 초안(2019년 12월 19일)
HTML 코딩을 하다가 자꾸만 ARIA에 정의된 role과 속성attribute을 적용하게 된다면, 한번 읽어보고 마음에 새길 만한 글. - “의미가 담긴 HTML의 실용적 가치” – 브루스 로슨Bruce Lawson
watchOS가 HTML5와 마이크로 데이터를 어떻게 활용하는지에 대해서 분석한 글.
헤이던 피커링의 《인클루시브 디자인 패턴》
누구라도 접근 가능한 인터페이스를 만드는 데 실제로 적용할 수 있는 인클루시브한 디자인 패턴을 알려드립니다. HTML과 CSS·자바스크립트 라이브러리, WAI-ARIA 역할 및 콘텐츠 접근성 지침의 올바른 사용법, 반응형 디자인에서 일반적인 접근성 문제를 해결하는 방법, 건너뛰기 링크를 다루는 방법, 내비게이션 영역 및 랜드마크의 효율적인 활용법, 버튼이나 폼을 유지하는 방법 등을 구체적으로 설명합니다.
books@webactually.com
잘 읽었습니다! 제 블로그에 퍼가도 될까요!
재밌는글 잘읽었습니다~
흥미롭게 잘 읽었습니다. 많은 도움이 될 것 같습니다!
재밌게 잘 읽었습니다 감사합니다.
잘 읽었습니다. 유용한 정보 감사합니다.