지난 편에서 HTML은 문서의 뼈대이며 태그는 의미를 지닌다고 이야기했습니다. 이번에는 그 이야기를 실전으로 끌고 내려와, 왜 모든 것을 상자 태그 하나로 처리하면 안 되는지를 파고들려 합니다. 제가 초보 시절 가장 많이 쓴 태그는 아무 의미 없는 범용 상자 태그였습니다. 무엇이든 담을 수 있으니 편했지만, 바로 그 편함이 함정이었습니다.


범용 상자 태그는 아무 의미가 없기에 어디에나 쓸 수 있지만, 뒤집어 말하면 어디에 써도 브라우저에게 아무것도 알려주지 않습니다. 이번 편에서는 이 무의미한 상자 대신 의미를 지닌 시맨틱 태그를 골라 쓸 때 접근성과 검색과 유지보수가 어떻게 달라지는지를 구체적인 사례로 짚어보겠습니다.


1. 범용 상자 태그가 나쁜 것은 아니다

먼저 오해를 풀어야 합니다. 범용 상자 태그 자체가 잘못된 것은 아닙니다. 이 태그는 순수하게 묶음을 만들거나 스타일을 입히기 위한 그릇으로 존재합니다. 딱히 어울리는 의미 태그가 없고 그저 여러 요소를 하나로 감싸 배치만 하고 싶을 때는 이 상자 태그가 정답입니다. 문제는 이것을 모든 상황의 기본값으로 삼는 습관입니다.


제가 처음 배울 때는 머리글도 상자, 본문도 상자, 목록도 상자, 버튼처럼 보이는 것도 상자로 만들었습니다. 화면상으로는 완벽했지만, 그 문서를 기계가 읽으면 그냥 정체불명의 상자가 수십 개 쌓인 더미일 뿐이었습니다. 사람 눈에만 의미가 있고 기계에게는 백지나 다름없었던 것이죠.


이 차이는 눈에 잘 보이지 않아서 더 위험합니다. 화면이 멀쩡하니 문제를 느끼지 못하고 넘어가기 쉽습니다. 하지만 화면 낭독 프로그램 사용자나 검색엔진 로봇에게는 그 백지 상태가 그대로 전달됩니다. 보이지 않는 사용자에게 보이지 않는 손해가 쌓이는 것입니다.


그래서 저는 상자 태그를 쓰기 전에 한 번 멈춰서 묻는 습관을 들였습니다. 이 자리에 더 어울리는 의미 태그가 정말 없는가. 머리글이라면 머리글 태그, 본문이라면 본문 태그, 곁가지라면 곁가지 태그가 이미 준비되어 있습니다. 상자 태그는 그 어느 것에도 해당하지 않을 때 마지막으로 꺼내는 도구여야 합니다.


이 순서를 뒤집는 것만으로도 문서의 질이 확 달라집니다. 의미 태그를 먼저 떠올리고 없을 때만 상자를 쓰면, 자연스럽게 문서 전체가 의미로 채워집니다. 반대로 상자를 먼저 떠올리면 문서는 끝까지 백지로 남습니다. 결국 습관의 순서 하나가 결과를 가릅니다.


2. 뼈대를 이루는 대표 시맨틱 태그들

HTML에는 문서의 큰 구획을 표시하는 시맨틱 태그가 여럿 마련되어 있습니다. 페이지 위쪽의 로고와 소개를 담는 머리글 태그, 주요 이동 메뉴를 담는 내비게이션 태그, 페이지의 고유한 핵심 내용을 담는 본문 태그, 마무리 정보를 담는 바닥글 태그가 대표적입니다. 이름만 봐도 각자 맡은 자리가 분명합니다.


여기에 더해 그 자체로 독립적인 한 덩어리를 뜻하는 글 태그가 있습니다. 블로그 글 하나, 댓글 하나, 상품 카드 하나처럼 떼어 내도 말이 되는 단위에 씁니다. 그리고 제목을 가진 주제별 묶음을 뜻하는 구획 태그가 있어서, 하나의 글 안을 여러 주제로 나눌 때 유용합니다.


본문과 직접 관련은 없지만 곁들여 두는 내용에는 곁가지 태그를 씁니다. 사이드바, 관련 링크 모음, 광고처럼 본문의 흐름에서 살짝 비켜난 것들이 여기 들어갑니다. 저는 이 태그를 알기 전에는 사이드바도 그냥 상자로 만들었는데, 곁가지 태그로 바꾸자 화면 낭독 프로그램이 본문과 곁가지를 구분해 안내해 주기 시작했습니다.


이 태그들의 좋은 점은 서로 겹쳐 쓸 수 있다는 것입니다. 예를 들어 머리글 태그와 바닥글 태그는 페이지 전체에서도 쓰지만, 하나의 글 태그 안에서도 그 글만의 머리글과 바닥글로 다시 쓸 수 있습니다. 글 안에 작성일과 글쓴이를 머리글로 묶고, 마지막에 출처를 바닥글로 묶는 식입니다.


여기서 특히 강조하고 싶은 규칙이 하나 있습니다. 페이지의 고유한 핵심 내용을 담는 본문 태그는 한 문서에 딱 하나만 두는 것이 원칙입니다. 여러 페이지에 공통으로 반복되는 머리글이나 메뉴, 바닥글은 이 본문 태그 바깥에 둡니다. 이렇게 하면 이 페이지에서 진짜 새로운 내용이 어디부터인지가 명확해집니다.


제가 이 구획 태그들을 제대로 배치하고 나서 얻은 가장 큰 선물은 이동의 편리함이었습니다. 화면 낭독 프로그램 사용자는 이 구획들을 랜드마크 삼아 페이지를 껑충껑충 건너뛰며 이동할 수 있습니다. 상자로만 짠 페이지에는 그런 이정표가 하나도 없어서 처음부터 끝까지 순서대로 들어야 합니다.


3. 같은 화면, 다른 코드

말로만 하면 와닿지 않으니 짧은 비교를 보겠습니다. 아래는 상자만으로 짠 머리글과 시맨틱 태그로 짠 머리글입니다. 화면에 나타나는 모습은 스타일만 같으면 완전히 동일합니다. 하지만 기계가 읽는 의미는 하늘과 땅 차이입니다.


<div class="top">
  <div class="menu">메뉴</div>
</div>


<header>
  <nav aria-label="주요 메뉴">메뉴</nav>
</header>


위쪽 코드는 브라우저에게 아무 정보도 주지 않습니다. 상단이라는 이름과 메뉴라는 이름은 오직 사람이 붙인 이름표일 뿐, 기계는 그 뜻을 읽지 못합니다. 반면 아래쪽 코드는 여기가 머리글이고 그 안이 이동 메뉴라는 사실을 태그 이름 자체로 선언합니다. 스타일 클래스가 아니라 태그의 종류가 의미를 나릅니다.


이 작은 차이가 쌓이면 페이지 전체의 성격이 달라집니다. 시맨틱 태그로 짠 페이지는 그 자체로 구조가 읽히는 반면, 상자로만 짠 페이지는 클래스 이름을 하나하나 해석해야 겨우 뜻이 통합니다. 그런데 클래스 이름은 사람마다 다르게 붙이니 표준이 없습니다. 태그는 표준이 있으니 누가 봐도 같은 뜻입니다.


제가 다른 사람과 협업할 때 이 표준의 힘을 절감했습니다. 서로 클래스 이름 규칙은 달랐지만, 시맨틱 태그의 뜻은 같았기에 상대의 코드를 처음 봐도 뼈대가 곧바로 읽혔습니다. 의미 태그는 팀 전체가 공유하는 공통 언어인 셈입니다.


4. 인라인과 블록, 그리고 중첩 규칙

시맨틱 태그를 배치할 때 함께 알아야 할 개념이 요소의 성격 구분입니다. 요소는 크게 한 줄을 통째로 차지하며 위아래로 쌓이는 블록 성격과, 콘텐츠 폭만 차지하며 옆으로 흐르는 인라인 성격으로 나뉩니다. 문단이나 구획 같은 큰 덩어리는 블록이고, 강조나 링크 같은 문장 속 조각은 인라인입니다.


이 성격은 배치뿐 아니라 중첩 규칙에도 영향을 줍니다. 원칙적으로 인라인 성격의 요소 안에 블록 성격의 큰 덩어리를 넣지 않습니다. 문장 속 강조 안에 문단을 통째로 집어넣는 것은 어색하고, 브라우저도 이를 이상하게 해석할 수 있습니다. 큰 것은 큰 것끼리, 작은 것은 그 안에 담는 순서를 지키는 것이 안전합니다.


다만 링크 태그는 예외적으로 블록 덩어리를 통째로 감싸는 것이 허용됩니다. 카드 전체를 하나의 링크로 만들고 싶을 때 이 규칙이 유용합니다. 이런 예외를 제외하면, 큰 구획 안에 작은 조각을 담는 자연스러운 위계를 유지하는 편이 좋습니다.


중첩과 관련해 초보가 자주 저지르는 실수도 있습니다. 목록의 직계 자식으로는 목록 항목만 와야 하는데 엉뚱한 태그를 끼워 넣는다든가, 문단 안에 또 다른 큰 덩어리를 넣는다든가 하는 것들입니다. 이런 실수는 화면에서는 티가 안 나지만 문서 구조를 조용히 망가뜨립니다.


저는 이런 실수를 줄이려고 코드를 짤 때 위계를 들여쓰기로 눈에 보이게 만듭니다. 부모보다 자식을 한 칸 더 들여 쓰면, 어떤 태그가 어떤 태그 안에 들어 있는지 한눈에 보입니다. 들여쓰기가 어긋나면 대개 중첩도 어긋나 있어서, 시각적 단서만으로도 오류를 잡아낼 수 있습니다.


결국 인라인과 블록의 구분, 그리고 중첩 규칙은 시맨틱 태그를 올바른 자리에 놓기 위한 문법적 토대입니다. 아무리 좋은 의미 태그를 골라도 엉뚱한 자리에 끼워 넣으면 그 의미가 살지 않습니다. 태그의 뜻과 태그가 놓일 자리, 이 둘을 함께 챙겨야 완전한 구조가 됩니다.


5. 실천으로 옮기는 작은 습관

이론을 실천으로 바꾸는 첫 습관은 페이지를 짜기 전에 구획부터 그려 보는 것입니다. 저는 새 페이지를 시작할 때 항상 머리글, 본문, 곁가지, 바닥글의 큰 상자를 먼저 시맨틱 태그로 세웁니다. 그 골격이 서고 나서야 그 안을 세부 내용으로 채웁니다. 뼈대를 먼저 세우면 살은 저절로 제자리를 찾습니다.


두 번째 습관은 상자 태그에 손이 갈 때마다 잠깐 멈추는 것입니다. 이 자리에 정말 의미 태그가 없는지 한 번 되짚으면, 놀랄 만큼 자주 더 나은 선택지가 이미 존재합니다. 이 멈춤이 처음에는 번거롭지만 몇 번 반복하면 곧 무의식적으로 의미 태그를 먼저 떠올리게 됩니다.


세 번째 습관은 완성한 페이지를 개발자 도구로 열어 구조를 눈으로 확인하는 것입니다. 브라우저의 접근성 검사 기능을 켜면 내가 세운 랜드마크가 제대로 잡혔는지 목록으로 보여줍니다. 여기에 상자만 잔뜩 보이고 랜드마크가 비어 있다면, 아직 의미가 부족하다는 신호입니다.


저는 이 세 습관을 몸에 붙이고 나서 코드 리뷰에서 지적받는 일이 크게 줄었습니다. 처음부터 의미대로 짜니 나중에 고칠 것이 적었기 때문입니다. 급하게 상자로 때우고 나중에 시맨틱으로 바꾸는 것보다, 처음부터 제대로 짜는 편이 결국 훨씬 빠릅니다.


물론 완벽할 필요는 없습니다. 어떤 자리에 어떤 태그가 가장 어울리는지 애매한 경우도 많습니다. 그럴 때는 너무 오래 고민하기보다 가장 근접한 의미 태그를 고르고 넘어갑니다. 상자로 도망치지만 않으면 대체로 옳은 방향입니다. 완벽보다 방향이 중요합니다.


여기서 제가 겪은 구체적인 사례 하나를 나누고 싶습니다. 예전에 상자로만 짠 목록 화면이 있었습니다. 눈으로 보면 분명히 항목이 여러 개 늘어선 목록인데, 화면 낭독 프로그램으로 들어보니 그냥 문장이 줄줄이 읽힐 뿐 몇 개짜리 목록인지 알려주지 않았습니다. 사용자는 지금 목록을 듣고 있는지조차 알 수 없었던 것이죠. 그 부분을 진짜 목록 태그로 바꾸자, 프로그램이 항목이 다섯 개인 목록이라고 먼저 안내한 뒤 하나씩 읽어 주었습니다.


이 경험이 저에게 준 교훈은 분명했습니다. 겉모습이 같다고 같은 것이 아니라는 사실입니다. 사람 눈에는 똑같아 보여도 기계가 전달받는 정보의 양은 하늘과 땅 차이였습니다. 그 차이를 만드는 것이 바로 어떤 태그를 골랐느냐 하나였습니다. 상자와 목록 태그는 화면상 구분이 안 되지만, 그 안에 담긴 의미의 밀도는 전혀 달랐습니다.


또 하나 강조하고 싶은 것은 시맨틱 태그가 스타일을 방해하지 않는다는 점입니다. 간혹 의미 태그를 쓰면 원하는 디자인이 안 나오지 않을까 걱정하는 분이 있습니다. 전혀 그렇지 않습니다. 어떤 시맨틱 태그든 스타일로 얼마든지 원하는 모양을 낼 수 있습니다. 의미는 태그가 지니고, 모양은 스타일이 맡으니 둘은 서로 간섭하지 않습니다. 그러니 의미 태그를 쓴다고 디자인을 포기할 일은 없습니다.


반대로 상자 태그로 버튼이나 링크 흉내를 내는 것은 오히려 더 많은 수고를 부릅니다. 상자를 버튼처럼 보이게 만들려면 키보드로 눌리게 하고 화면 낭독 프로그램에 버튼이라고 알리는 처리를 일일이 손으로 해줘야 합니다. 처음부터 진짜 버튼 태그를 쓰면 그 모든 것이 공짜로 딸려 옵니다. 편하려고 상자를 골랐다가 결국 더 고생하는 셈입니다.


그래서 저는 요즘 상자 태그로 무언가를 흉내 내고 싶어지면, 그 흉내에 드는 수고를 먼저 떠올립니다. 대개는 이미 그 역할을 하는 진짜 태그가 마련되어 있고, 그것을 쓰는 편이 훨씬 적은 노력으로 더 나은 결과를 냅니다. 바퀴를 다시 발명하지 않는 것, 이것이 시맨틱 태그를 대하는 제 태도입니다.


이번 편에서는 상자 태그의 함정과 시맨틱 태그의 힘을 살펴봤습니다. 다음 편에서는 이 시맨틱 태그들을 실제 페이지 골격으로 조립하는 방법, 그러니까 머리글과 내비게이션과 본문과 바닥글을 어떤 순서와 관계로 배치해야 하는지를 더 구체적으로 다루겠습니다. 재료를 알았으니 이제 조립을 배울 차례입니다.