1. HTML 문서의 전체 골격
모든 HTML 문서는 아래의 기본 뼈대를 갖는다. 이 구조가 빠지거나 어긋나면 브라우저가 문서를 올바르게 해석하지 못할 수 있다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="HTML 문서 구조를 공부한 스터디 노트">
<title>HTML 문서의 기본 구조 | HTML 기초</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="favicon.ico">
</head>
<body>
<h1>안녕하세요</h1>
<p>HTML 문서 구조를 공부하고 있습니다.</p>
<script src="main.js"></script>
</body>
</html>
크게 세 부분으로 나뉜다. DOCTYPE 선언, 문서 메타데이터를 담는 <head>, 그리고 사용자에게 보이는 콘텐츠를 담는 <body> 다. 하나씩 해부한다.
2. <!DOCTYPE html>: 문서 형식 선언
2.1 DOCTYPE이란
<!DOCTYPE html>
- 이것은 HTML 태그가 아니다. 브라우저에게 "이 문서를 HTML5 규격으로 파싱하라"고 알리는 선언(Declaration) 이다.
- 반드시 문서의 맨 첫 줄에 와야 하며, 그 어떤 태그나 공백보다 앞서야 한다.
- 대소문자를 가리지 않는다.
<!DOCTYPE HTML>,<!doctype html>모두 유효하다. 다만 WHATWG 명세와 대부분의 자료에서<!DOCTYPE html>— DOCTYPE은 대문자, html은 소문자 — 형태를 표준 예시로 사용한다.
2.2 선언하지 않으면 어떻게 되나: 쿼크 모드(Quirks Mode)
DOCTYPE 선언이 없거나 잘못되면 브라우저가 쿼크 모드(Quirks Mode) 로 전환된다.
- 쿼크 모드는 1990년대 브라우저의 비표준 렌더링 방식을 흉내 내는 호환 모드다. 당시 작성된 구식 웹사이트를 깨지지 않게 보여주기 위해 존재한다.
- 쿼크 모드에서는 박스 모델, 폰트 크기 계산, 테이블 레이아웃 등이 현대 표준과 다르게 동작해 레이아웃이 틀어지거나 CSS가 예상과 다르게 적용될 수 있다.
- DOCTYPE이 올바르면 브라우저는 표준 모드(Standards Mode) 로 동작한다. 현대 웹은 반드시 표준 모드에서 동작해야 한다.
2.3 DOCTYPE의 역사: 왜 이렇게 간단해졌나
HTML5 이전의 DOCTYPE은 훨씬 복잡했다. DTD(Document Type Definition) 라는 외부 규격 문서의 URL을 포함해야 했기 때문이다.
<!-- HTML 4.01 Strict의 DOCTYPE — 길고 복잡하다 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<!-- XHTML 1.0 Strict의 DOCTYPE -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
HTML5는 브라우저가 실제로 DTD를 사용하지 않는다는 현실을 반영해, DOCTYPE을 단순히 표준 모드 트리거로만 쓰기로 했다. 그 결과 <!DOCTYPE html> 이라는 최소한의 형태가 됐다.
3. <html> · <head> · <body>: 문서의 세 기둥
3.1 <html>: 문서의 루트 요소
<html lang="ko">
- HTML 문서 전체를 감싸는 루트(Root) 요소다. DOCTYPE을 제외한 모든 HTML 요소는 이 안에 위치한다.
lang속성이 중요하다. 이 속성은 문서의 주 언어를 선언한다.- 스크린 리더가 올바른 언어로 텍스트를 읽는다. (한국어와 영어는 발음·억양이 다르다.)
- 검색 엔진이 문서의 언어를 파악해 해당 언어 사용자에게 적절히 노출한다.
- 브라우저의 자동 번역 기능이 원본 언어를 정확히 감지한다.
- 값은 BCP 47 언어 태그를 사용한다. 한국어는
ko, 미국 영어는en-US, 영국 영어는en-GB.
| 속성 | 값 예시 | 역할 |
|---|---|---|
lang | ko, en, en-US, ja | 문서의 주 언어 선언 |
dir | ltr(좌→우), rtl(우→좌) | 텍스트 방향 (아랍어·히브리어 등) |
3.2 <head>: 문서의 두뇌 — 메타데이터 영역
<head>
...
</head>
<head>안의 내용은 화면에 직접 표시되지 않는다. 대신 문서에 관한 정보(메타데이터)를 담아 브라우저·검색 엔진·소셜 미디어 등에 전달한다.- 반드시
<title>요소를 하나 포함해야 한다. 이것이<head>의 유일한 필수 요소다. <head>에 올 수 있는 요소는 다음과 같다.
| 요소 | 역할 |
|---|---|
<title> | 문서 제목 (탭·검색 결과 표시) |
<meta> | 문자 인코딩, 뷰포트, 설명, Open Graph 등 메타데이터 |
<link> | 외부 CSS·아이콘·정규 URL 등 연결 |
<style> | 내부 CSS 스타일 선언 |
<script> | JavaScript (head에서 defer/async로 불러오는 경우) |
<base> | 문서 내 모든 상대 URL의 기준 주소 설정 |
3.3 <body>: 문서의 몸통 — 콘텐츠 영역
<body>
...
<script src="main.js"></script>
</body>
- 사용자가 실제로 화면에서 보고 상호작용하는 모든 콘텐츠가 위치하는 공간이다. 텍스트, 이미지, 링크, 폼, 버튼 등 모든 시각적 요소가 여기에 들어간다.
<script>는</body>직전에 배치한다. 브라우저는 HTML을 위에서 아래로 파싱하다<script>를 만나면 파싱을 중단하고 스크립트를 먼저 실행한다(렌더 블로킹).</body>직전에 두면 HTML이 모두 파싱되어 DOM이 완성된 뒤 스크립트가 실행되므로 안전하다.
head vs body: 쉽게 구분하는 기준
"화면에 보이는가?" — 보인다면
<body>, 보이지 않는 정보(문서 설명, 스타일 연결, 인코딩 등)라면<head>다.
4. <meta>: 문서를 설명하는 다목적 태그
<meta> 는 닫는 태그가 없는 빈 요소(void element)이며, 속성 조합에 따라 매우 다양한 역할을 수행한다.
4.1 문자 인코딩 선언
<meta charset="UTF-8">
- 이 선언은
<head>의 가장 첫 번째 요소로 와야 한다. HTML 명세는 인코딩 선언이 문서의 첫 1,024바이트 안에 있어야 한다고 규정한다. - UTF-8 은 전 세계 모든 문자(한글, 일본어, 아랍어, 이모지 등)를 표현할 수 있는 가장 범용적인 인코딩이다. HTML5 문서에서 UTF-8이 사실상 표준이다.
- 이 선언 없이 한글을 포함하면 브라우저가 다른 인코딩으로 해석해 글자가 깨지는(mojibake) 현상이 발생할 수 있다.
4.2 뷰포트 설정
<meta name="viewport" content="width=device-width, initial-scale=1.0">
- 모바일 기기에서 페이지가 올바르게 보이도록 뷰포트(화면 표시 영역)를 설정한다.
- 이 태그가 없으면 모바일 브라우저가 페이지 전체를 데스크탑 너비(보통 980px)로 렌더링한 뒤 축소해서 보여주므로, 텍스트가 작게 보이고 터치가 불편해진다.
content 값 | 의미 |
|---|---|
width=device-width | 뷰포트 너비를 기기의 실제 화면 너비로 설정 |
initial-scale=1.0 | 초기 확대·축소 배율을 1배(원본 크기)로 설정 |
minimum-scale=1.0 | 최소 축소 배율 제한 |
maximum-scale=1.0 | 최대 확대 배율 제한 (접근성상 권장하지 않음) |
user-scalable=no | 사용자 확대·축소 비활성화 (접근성상 사용 금지) |
주의:
user-scalable=no와maximum-scale=1.0이 두 값은 시각 장애가 있는 사용자의 확대 기능을 막아 접근성을 해친다. WCAG(웹 콘텐츠 접근성 지침) 1.4.4 항목은 사용자가 콘텐츠를 200%까지 확대할 수 있어야 한다고 명시한다. 사용하지 않는 것이 원칙이다.
4.3 페이지 설명 (description)
<meta name="description" content="HTML 문서의 기본 구조를 공부한 스터디 노트입니다.">
- 페이지의 내용을 요약하는 설명문이다. 검색 엔진 결과 페이지(SERP)에서 제목 아래에 표시되는 스니펫(snippet) 의 후보로 사용된다.
- 권장 길이: 50~160자. 너무 길면 검색 결과에서 잘린다.
- 검색 엔진이 이 값을 반드시 그대로 사용하는 것은 아니다. 페이지 본문에서 더 적절한 내용을 찾으면 자체적으로 스니펫을 생성하기도 한다.
- 각 페이지마다 고유한 설명을 작성하는 것이 SEO에 유리하다.
4.4 robots 제어
<meta name="robots" content="noindex, nofollow">
- 검색 엔진 크롤러(봇)의 동작을 제어한다.
content 값 | 의미 |
|---|---|
index (기본값) | 이 페이지를 검색 인덱스에 포함 |
noindex | 이 페이지를 검색 인덱스에서 제외 |
follow (기본값) | 이 페이지의 링크를 따라가 수집 |
nofollow | 이 페이지의 링크를 따라가지 않음 |
noarchive | 캐시 저장 금지 |
4.5 Open Graph (소셜 미디어 공유)
<meta property="og:title" content="HTML 문서의 기본 구조">
<meta property="og:description" content="DOCTYPE부터 meta 태그까지 HTML 골격을 해부한다.">
<meta property="og:image" content="https://example.com/thumbnail.png">
<meta property="og:url" content="https://example.com/html-structure">
<meta property="og:type" content="article">
- Facebook이 개발하고 현재 대부분의 소셜 미디어가 지원하는 Open Graph 프로토콜을 따르는 메타 태그다.
- 카카오톡·트위터·슬랙 등에 URL을 공유할 때 나타나는 미리 보기 카드(링크 프리뷰) 의 제목·설명·이미지를 이 태그로 제어한다.
- 블로그 글을 공유했을 때 썸네일이 제대로 나오려면
og:image가 필수다.
5. <title>: 페이지의 이름표
<title>HTML 문서의 기본 구조 | HTML 기초</title>
- 브라우저 탭에 표시되는 문서 제목이다.
- 검색 엔진 결과 페이지에서 클릭 가능한 제목(blue link) 으로 표시된다. SEO에 직접적인 영향을 미치는 가장 중요한 요소 중 하나다.
<head>안에 반드시 하나 존재해야 하며, 유일한 필수 메타데이터 요소다.
5.1 좋은 title 작성 원칙
| 원칙 | 설명 |
|---|---|
| 권장 길이 50~60자 | 너무 길면 검색 결과에서 잘린다 (… 처리) |
| 페이지마다 고유하게 | 모든 페이지가 같은 title이면 SEO에 불리 |
| 핵심 키워드를 앞에 | 검색자가 먼저 보는 앞부분에 중요 단어를 배치 |
| 사이트명 뒤에 구분자로 | 페이지 제목 | 사이트명 또는 페이지 제목 - 사이트명 형식 |
6. <link>: 외부 자원과의 연결
<link> 는 현재 HTML 문서와 외부 자원의 관계를 선언하는 빈 요소다. rel 속성이 관계의 성격을 정의하며, 이에 따라 역할이 완전히 달라진다.
6.1 CSS 스타일시트 연결
<link rel="stylesheet" href="style.css">
- 가장 흔히 쓰이는
<link>사용 패턴이다. - 브라우저는 이 태그를 만나면 즉시 CSS 파일을 다운로드하기 시작한다. CSS는 렌더링을 차단하므로(
<script>와 달리 HTML 파싱은 계속되지만, 렌더 트리 생성이 지연됨)<head>안에 두어 가능한 일찍 로드하는 것이 좋다.
6.2 파비콘(Favicon) 설정
<link rel="icon" href="favicon.ico">
<link rel="icon" href="favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="apple-touch-icon.png">
- 브라우저 탭, 즐겨찾기, 모바일 홈 화면에 표시되는 작은 아이콘(파비콘) 을 지정한다.
favicon.ico는 전통적인 형식. SVG 파비콘은 어떤 해상도에서도 선명하게 보인다.rel="apple-touch-icon"은 iOS에서 홈 화면에 추가할 때 사용하는 아이콘이다.
6.3 정규 URL (Canonical)
<link rel="canonical" href="https://example.com/html-structure">
- 동일하거나 유사한 콘텐츠가 여러 URL에 존재할 때, 대표 URL을 검색 엔진에 알리는 태그다.
- 예를 들어
https://example.com/post?id=1과https://example.com/post/html-structure가 같은 내용을 가리킬 때, 어느 URL을 색인할지 지정한다. 이 설정이 없으면 검색 엔진이 중복 콘텐츠로 판단해 SEO에 불이익이 생길 수 있다.
6.4 리소스 힌트 (Resource Hints)
브라우저에게 "이 자원이 곧 필요할 것"임을 미리 알려 로딩 성능을 개선한다.
<!-- 폰트 파일을 미리 로드 -->
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
<!-- 다음 페이지에서 쓸 자원을 미리 가져옴 -->
<link rel="prefetch" href="next-page.js">
<!-- 외부 도메인과 미리 연결 (DNS + TCP + TLS) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
rel 값 | 의미 |
|---|---|
preload | 현재 페이지에 곧 필요한 자원을 우선 로드 |
prefetch | 다음 페이지에 필요할 가능성이 높은 자원을 유휴 시간에 미리 가져옴 |
preconnect | 자원을 가져오기 전, 외부 서버와의 연결(DNS+TCP+TLS)을 미리 수립 |
dns-prefetch | DNS 조회만 미리 수행 (preconnect보다 가벼움) |