웹페이지들은 저마다 디자인이 꽤 다를 수 있고 실제로도 그렇습니다. 하지만 전체 화면 비디오나 게임을 보여주는 페이지, 일종의 예술 프로젝트, 혹은 구조가 엉망인 페이지가 아니라면 대체로 비슷한 표준 구성 요소들을 공유하는 경향이 있습니다.
"전형적인 웹사이트"는 대략 아래와 같은 구조를 가질 수 있습니다:

참고: 위 이미지는 HTML을 통해 정의할 수 있는 문서의 주요 섹션들을 보여줍니다. 하지만 레이아웃, 색상, 글꼴을 포함해 화면에 보이는 모습은 HTML에 CSS를 적용하여 만든 것입니다. HTML은 '뼈대', CSS는 '옷'이라고 생각하시면 이해하기 쉬워요!
위에서 본 예시가 엄청 예쁜 디자인은 아니지만, 전형적인 웹사이트 레이아웃 예시를 설명하기에는 아주 훌륭합니다. 어떤 웹사이트는 단이 더 많고, 어떤 곳은 훨씬 더 복잡하지만 대략적인 감은 잡으셨을 겁니다. CSS를 잘 다룬다면 사실 아무 태그(요소)나 사용해서 여러 섹션을 감싸고 원하는 대로 보이게 만들 수 있습니다. 하지만 앞서 이야기했듯이, 우리는 시맨틱(의미)을 존중해야 하며 알맞은 작업에 알맞은 요소(태그)를 사용해야 합니다.
그 이유는 '눈에 보이는 것'이 전부가 아니기 때문입니다. 시력이 정상인 사용자들의 주의를 주요 콘텐츠(예: 내비게이션 메뉴나 관련 링크)로 끌기 위해 우리는 색상이나 큰 글꼴을 사용합니다. 하지만 "분홍색"이나 "큰 폰트" 같은 개념이 전혀 도움 되지 않는 시각 장애인분들은 어떨까요?
참고: 남성의 약 8%, 여성의 0.5%가 색맹(색각이상)을 가지고 있습니다. 다시 말해, 남성은 약 12명 중 1명, 여성은 200명 중 1명꼴입니다. 전 세계 인구의 약 4~5%가 시각 장애인 또는 시력 저하를 겪고 있습니다 (2015년 기준 총인구가 약 75억 명일 때, 어느 정도의 시력 상실을 겪는 사람이 9억 4천만 명에 달했습니다).
HTML 코드를 작성할 때, 여러분은 콘텐츠의 섹션을 그 기능(functionality)에 따라 마크업할 수 있습니다. 즉, 앞서 설명한 콘텐츠 섹션들을 명확하게 나타내는 요소들을 사용하면, 스크린 리더 같은 보조 기술(assistive technologies)이 해당 요소들을 인식해서 "메인 내비게이션 찾기" 또는 "메인 콘텐츠 찾기" 같은 작업을 수월하게 도와줄 수 있습니다. 코스 초반에 언급했듯이, 알맞은 작업에 알맞은 요소 구조와 시맨틱을 사용하지 않으면 여러 가지 문제가 발생합니다.
이러한 시맨틱 마크업을 구현하기 위해 HTML은 각 섹션을 나타내는 전용 태그들을 제공합니다. 예를 들면 다음과 같습니다:
<header><nav><main>, 이 안의 다양한 하위 섹션들은 <article>, <section>, <div> 요소들로 표현됩니다.<aside>, 주로 <main> 안에 배치됩니다.<footer>💡 강사의 팁: 태그 이름만 봐도 이 영역이 어떤 역할을 하는지 직관적으로 알 수 있죠? 이것이 바로 시맨틱 마크업의 힘입니다! 동료 개발자와 코드를 리뷰할 때도 커다란
<div>덩어리들을 보는 것보다 훨씬 코드 읽기가 편해진답니다.
위에서 살펴본 예시 구조는 아래의 코드와 같이 작성할 수 있습니다 (우리의 GitHub 저장소에서 이 예제를 확인할 수도 있습니다). 아래 코드를 보면서, 시각적인 결과물의 각 섹션을 어떤 태그들이 구성하고 있는지 천천히 살펴보세요.
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>My page title</title>
<link
href="https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300|Sonsie+One"
rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<header>
<h1>Header</h1>
</header>
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Our team</a></li>
<li><a href="#">Projects</a></li>
<li><a href="#">Contact</a></li>
</ul>
<form>
<input type="search" name="q" placeholder="Search query" />
<input type="submit" value="Go!" />
</form>
</nav>
<main>
<article>
<h2>Article heading</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Donec a diam
lectus. Set sit amet ipsum mauris. Maecenas congue ligula as quam
viverra nec consectetur ant hendrerit. Donec et mollis dolor. Praesent
et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt
congue enim, ut porta lorem lacinia consectetur.
</p>
<section>
<h3>Subsection</h3>
<p>
Donec ut librero sed accu vehicula ultricies a non tortor. Lorem
ipsum dolor sit amet, consectetur adipisicing elit. Aenean ut
gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id
dolor.
</p>
<p>
Pelientesque auctor nisi id magna consequat sagittis. Curabitur
dapibus, enim sit amet elit pharetra tincidunt feugiat nist
imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed
odio eros.
</p>
</section>
<section>
<h3>Another subsection</h3>
<p>
Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum
soclis natoque penatibus et manis dis parturient montes, nascetur
ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at
sem facilisis semper ac in est.
</p>
<p>
Vivamus fermentum semper porta. Nunc diam velit, adipscing ut
tristique vitae sagittis vel odio. Maecenas convallis ullamcorper
ultricied. Curabitur ornare, ligula semper consectetur sagittis,
nisi diam iaculis velit, is fringille sem nunc vet mi.
</p>
</section>
</article>
<aside>
<h2>Related</h2>
<ul>
<li><a href="#">Oh I do like to be beside the seaside</a></li>
<li><a href="#">Oh I do like to be beside the sea</a></li>
<li><a href="#">Although in the North of England</a></li>
<li><a href="#">It never stops raining</a></li>
<li><a href="#">Oh well…</a></li>
</ul>
</aside>
</main>
<footer>
<p>©Copyright 2050 by nobody. All rights reversed.</p>
</footer>
</body>
</html>
시간을 조금 내서 코드를 찬찬히 훑어보며 이해해 보세요. 코드 안에 있는 주석(comments)들이 이해를 도와줄 겁니다. 이 문서에서는 당장 코드로 많은 것을 하라고 요구하진 않아요. 왜냐하면 문서 레이아웃을 이해하는 핵심은 튼튼한 HTML 구조를 작성하는 것이고, 배치는 CSS로 하는 것이니까요. 배치는 나중에 CSS 주제에서 CSS 레이아웃을 배울 때까지 잠시 미뤄두겠습니다.
HTML의 모든 구획화(sectioning) 요소들의 전반적인 의미를 자세히 이해하는 것은 매우 중요합니다. 웹 개발 경험이 쌓일수록 점차 익숙해지실 내용들이죠. HTML 요소 레퍼런스(HTML element reference)를 읽어보시면 훨씬 더 자세한 내용을 확인하실 수 있습니다. 일단 지금은 다음의 주요 정의들을 이해하려고 노력해 보세요:
<main>: 이 페이지만의 고유한 콘텐츠를 나타냅니다. <main>은 페이지당 오직 한 번만 사용해야 하며, <body> 바로 안에 직접 넣어야 합니다. 이상적으로는 다른 요소들 내부에 중첩되어서는 안 됩니다.<article>: 페이지의 다른 부분과 독립적으로 떨어져 있어도 그 자체로 의미가 통하는 관련 콘텐츠의 블록을 감쌉니다 (예를 들면 블로그 포스트 하나, 뉴스 기사 하나 등).<section>: <article>과 비슷하지만, 하나의 독립된 기능(예: 미니맵이나 기사 헤드라인 및 요약본의 모음)이나 테마를 구성하는 페이지의 특정 부분을 하나로 묶을 때 더 적합합니다. 각 섹션을 제목(heading)으로 시작하는 것이 모범 사례(best practice)로 여겨집니다. 문맥에 따라 <article>을 여러 개의 <section>으로 나눌 수도 있고, 반대로 <section>을 여러 개의 <article>로 나눌 수도 있다는 점도 기억해 두세요.<aside>: 메인 콘텐츠와 직접적인 관련은 없지만, 간접적으로 관련된 부가 정보(용어집, 작성자 약력, 관련 링크 등)를 제공할 수 있는 콘텐츠를 담습니다.<header>: 도입부 콘텐츠 그룹을 나타냅니다. 만약 <body>의 자식 요소로 쓰인다면 웹페이지 전체의 글로벌 헤더를 정의하지만, <article>이나 <section>의 자식으로 쓰인다면 해당 특정 구역만의 헤더를 정의합니다 (이것을 <title>이나 <h1>~<h6> 같은 제목류와 헷갈리지 마세요).<nav>: 페이지의 메인 내비게이션 기능(메뉴 등)을 담습니다. 부차적인 자잘한 링크들은 내비게이션에 넣지 않는 것이 좋습니다.<footer>: 페이지의 맺음말(끝) 부분 콘텐츠 그룹을 나타냅니다.💡 강사의 팁:
<article>과<section>의 차이를 헷갈려하시는 분들이 정말 많아요! 이렇게 생각해보세요. 해당 영역만 쏙 잘라내서 다른 사이트나 RSS 피드에 붙여넣었을 때 "그 자체로 내용이 완결되는가?" 완결된다면<article>, 그렇지 않고 그저 연관된 내용들을 시각적으로 묶어둔 카테고리 같은 개념이라면<section>을 쓰시면 됩니다.
위에서 언급된 각 요소들의 이름을 클릭하면 "HTML 요소 레퍼런스" 섹션의 해당 문서를 읽어볼 수 있으며, 더 자세한 내용을 확인할 수 있습니다.
간혹 항목들을 하나로 묶거나 어떤 콘텐츠를 감싸야 하는데, 도무지 딱 맞는 시맨틱 요소를 찾을 수 없는 상황에 부닥칠 수 있습니다. 때로는 CSS나 JavaScript를 적용해 여러 요소들을 하나의 덩어리로 제어하기 위해 묶고 싶을 때도 있죠. 이런 경우를 위해 HTML은 <div>와 <span> 요소를 제공합니다. 이 요소들은 쉽게 타겟팅(선택)할 수 있도록 적절한 class 속성(attribute)을 부여해 이름표를 달아주는 것이 좋습니다.
<span>은 인라인(inline) 논-시맨틱(의미 없는) 요소입니다. 콘텐츠를 감쌀 더 좋은 텍스트 전용 시맨틱 요소를 찾을 수 없거나, 특정한 의미를 추가하고 싶지 않을 때만 사용해야 합니다. 예를 들면 다음과 같습니다:
<p>
The King walked drunkenly back to his room at 01:00, the beer doing nothing to
aid him as he staggered through the door.
<span class="editor-note">
[Editor's note: At this point in the play, the lights should be down low].
</span>
</p>
이 경우, 편집자의 메모(editor's note)는 단지 연극 연출가에게 추가적인 지시를 내리기 위한 것일 뿐, 마크업 상에서 특별한 의미(semantic meaning)를 가지도록 의도된 것이 아닙니다. 시력이 정상인 사용자들을 위해 CSS를 사용해서 메인 텍스트와 이 메모 사이에 약간의 거리를 두거나 디자인을 다르게 할 수 있겠죠.
<div>는 블록 레벨(block level) 논-시맨틱 요소입니다. 이 역시 더 적합한 블록 시맨틱 요소를 찾을 수 없거나 특정 의미를 부여하고 싶지 않을 때만 사용해야 합니다. 예를 들어, 전자상거래(쇼핑몰) 사이트를 탐색하는 중 언제든지 끌어올려서 볼 수 있는 장바구니 위젯이 있다고 상상해 보세요:
<div class="shopping-cart">
<h2>Shopping cart</h2>
<ul>
<li>
<p>
<a href=""><strong>Silver earrings</strong></a>: $99.95.
</p>
<img src="../products/3333-0985/thumb.png" alt="Silver earrings" />
</li>
<li>…</li>
</ul>
<p>Total cost: $237.89</p>
</div>
이것은 굳이 <aside>라고 볼 수 없습니다. 반드시 페이지의 메인 콘텐츠와 관련된 것도 아니니까요(페이지 어디에서든 볼 수 있길 원하죠). 그렇다고 메인 콘텐츠의 일부분도 아니므로 <section>을 쓰기도 적절치 않습니다. 따라서 이런 경우에는 <div>를 쓰는 것이 완벽히 괜찮습니다. 스크린 리더 사용자가 이것을 쉽게 찾을 수 있도록 이정표 역할을 하는 제목(heading)을 하나 포함해 두었습니다.
⚠️ 주의 (Warning):
<div>는 사용하기가 너무 편해서 남용하기가 아주 쉽습니다(이른바 'divitis' 또는 'div 병'이라고 부릅니다).div는 의미론적인 가치를 지니지 않기 때문에 그저 여러분의 HTML 코드를 복잡하고 어수선하게 만들 뿐입니다. 더 나은 시맨틱 대안이 없을 때만 조심스럽게 사용하고, 사용을 최소화하도록 노력하세요. 그렇지 않으면 나중에 문서를 수정하고 유지보수할 때 큰 어려움을 겪게 될 것입니다.
참고: Scrimba의 Semantic HTML 인터랙티브 튜토리얼을 보면 시맨틱 마크업이 무엇인지, 왜 써야 하는지 유용한 복습 자료를 제공하며, 시맨틱 요소로 HTML 코드베이스를 개선하는 능력을 테스트해 볼 수 있는 챌린지도 있습니다.
여러분이 가끔 사용하게 될, 알아두면 좋은 요소 두 가지가 있습니다. 바로 <br>과 <hr>입니다.
<br>: 줄바꿈 요소 (the line break element)<br>은 문단 내에서 강제로 줄바꿈을 만듭니다. 우편 주소나 시(poem)처럼 짧은 줄이 고정적으로 나열되는 상황에서 딱딱한 구조를 강제할 수 있는 유일한 방법입니다. 예를 들어:
<p>
There once was a man named O'Dell<br />
Who loved to write HTML<br />
But his structure was bad, his semantics were sad<br />
and his markup didn't read very well.
</p>
만약 <br> 요소가 없다면, 이 문단은 그저 긴 한 줄로 렌더링될 것입니다 (이전 과정에서 설명했듯, HTML은 코드 상의 공백과 줄바꿈을 대부분 무시합니다). 코드에 <br> 요소를 넣으면 다음과 같이 렌더링됩니다:
There once was a man named O'Dell
Who loved to write HTML
But his structure was bad, his semantics were sad
and his markup didn't read very well.
<hr>: 주제 분리 요소 (the thematic break element)<hr> 요소는 문서 내에서 텍스트의 주제가 바뀌었음을(예: 다른 주제로 넘어가거나 이야기의 장면이 바뀔 때) 나타내는 수평선(horizontal rule)을 만듭니다. 시각적으로는 그저 수평으로 그어진 하나의 선처럼 보입니다. 예시를 볼까요:
<p>
Ron was backed into a corner by the marauding netherbeasts. Scared, but
determined to protect his friends, he raised his wand and prepared to do
battle, hoping that his distress call had made it through.
</p>
<hr />
<p>
Meanwhile, Harry was sitting at home, staring at his royalty statement and
pondering when the next spin off series would come out, when an enchanted
distress letter flew through his window and landed in his lap. He read it
hazily and sighed; "better get back to work then", he mused.
</p>
위 코드는 웹 브라우저에서 아래와 같이 보일 겁니다:
Ron was backed into a corner by the marauding netherbeasts. Scared, but determined to protect his friends, he raised his wand and prepared to do battle, hoping that his distress call had made it through.
Meanwhile, Harry was sitting at home, staring at his royalty statement and pondering when the next spin off series would come out, when an enchanted distress letter flew through his window and landed in his lap. He read it hazily and sighed; "better get back to work then", he mused.
단일 웹페이지의 구조를 기획했다면, 그 다음 단계는 전체 여러 페이지로 구성된 웹사이트의 구조를 기획하는 것입니다. 어떻게 페이지들을 배치하고 서로 링크를 연결해야 최상의 사용자 경험(User Experience)을 제공할 수 있을지 고민하는 단계죠. 이것을 정보 구조도(Information architecture)라고 부릅니다.
크고 복잡한 웹사이트의 경우 이 과정에 엄청난 기획 작업이 필요하지만, 몇 개의 페이지만 있는 간단한 웹사이트라면 아주 빠르고 재미있는 연습이 될 수 있습니다.
작업 과정은 대략 이렇습니다:
여러분이 직접 만들 웹사이트를 상상하며 위 연습을 한 번 수행해 보세요. 어떤 주제의 사이트를 만들고 싶으신가요? 도전 과제 삼아, 지금까지 배운 HTML 지식을 활용해서 해당 사이트의 페이지 몇 개를 직접 코드로 작성해 보세요. 저희가 제공하는 기본 HTML 템플릿을 출발점으로 삼으시면 좋습니다.
💡 강사의 팁: 프론트엔드 개발자는 단순히 코드를 치는 사람이 아니라 사용자의 '경험'을 코드로 번역하는 사람입니다. 코딩에 들어가기 전 이렇게 손으로 끄적이며 구조를 잡는 과정이 습관화되면, 나중에 리액트(React)나 뷰(Vue) 같은 프레임워크를 다루실 때 '컴포넌트 분리'를 하는 데도 엄청난 도움이 됩니다!