HTML 구조와 문법
DOCTYPE부터 head와 body까지 문서 골격을 만들고 요소·태그·속성·주석·블록과 인라인 문법을 구분합니다.
1장에서는 웹이 동작하는 방식과 HTML, CSS, 자바스크립트가 맡는 일을 살펴보고, 자기소개 페이지를 만들며 HTML이 페이지의 뼈대를 만든다는 것을 경험했습니다. 2장에서는 HTML(HyperText Markup Language)을 더 자세히 다룹니다. 이 글에서는 모든 HTML 문서가 따르는 기본 구조와, 요소, 태그, 속성, 주석 같은 문법 규칙, 그리고 블록 요소와 인라인 요소의 차이를 정리합니다.
HTML DOCUMENT
HTML 소스를 읽어 DOM의 부모·자식 관계를 만듭니다
Document 아래에 DOCTYPE 노드와 html 요소가 있고, head와 body는 html 안의 형제입니다.
- HTML 소스
태그, 속성, 텍스트를 작성합니다. DOCTYPE은 태그의 부모가 아닙니다.
- 파서가 DOM 구성
토큰화와 트리 구성 규칙으로 노드를 만듭니다. 생략 태그와 잘못된 중첩은 규칙에 따라 보정될 수 있습니다.
DOCTYPE의 또 다른 역할 · 문서 모드
현대 문서의 <!doctype html>은 표준 모드로 해석하도록 합니다. 이 모드 결정과 DOM의 부모·자식 관계는 구분합니다.
화살표는 DOM의 부모에서 자식으로 향합니다. 그림은 일반적인 HTML 골격을 단순화했습니다. 실제 DOM에는 텍스트·주석 등도 포함됩니다. 화면 배치가 DOM 순서를 자동으로 바꾸지는 않습니다.
위 그림은 브라우저가 HTML 소스를 읽어 DOM의 부모와 자식 관계를 만드는 과정을 보여 줍니다. 작성한 태그, 속성, 텍스트를 파서가 토큰으로 나누고 트리 구성 규칙에 따라 노드를 만들며, 생략한 태그나 잘못 겹친 태그는 이 규칙에 따라 보정되기도 합니다. 완성된 트리에서 Document 아래에는 DocumentType 노드와 html 요소가 형제로 있고, html 아래에 head와 body가 다시 형제로 놓입니다.
화살표는 실행 순서가 아니라 부모에서 자식으로 향하는 관계입니다. <!DOCTYPE html>은 html의 부모가 아니며, 그림 아래의 설명처럼 문서를 표준 모드로 해석하게 하는 역할을 따로 합니다. 실제 DOM에는 그림에서 생략한 텍스트와 주석 노드도 들어 있습니다.
HTML 문서의 기본 구조
모든 HTML 문서는 브라우저가 올바르게 해석할 수 있도록 정해진 기본 구조를 따릅니다. 1장에서 본 뼈대를 다시 살펴보겠습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>웹 페이지 제목</title>
</head>
<body>
<h1>환영합니다!</h1>
<p>이곳에 내용이 들어갑니다.</p>
</body>
</html>HTML 문법은 조건에 따라 html, head, body 같은 일부 태그를 생략하는 것도 허용합니다. 하지만 처음 연습할 때는 이 태그들을 모두 적어, 문서의 설정과 화면의 내용이 어디에 들어가는지 분명히 나눠 봅니다.
첫 줄의 <!DOCTYPE html>은 문서 유형 선언(document type declaration)입니다. 브라우저는 이 선언을 보고 현재 HTML 표준에 따라 문서를 해석하는 표준 모드를 고릅니다. 선언이 없으면 오래된 브라우저의 동작을 흉내 내는 호환 모드(quirks mode)로 해석해, CSS가 예상과 다르게 적용될 수 있습니다. 그래서 이 교재는 모든 파일의 첫 줄에 이 선언을 적습니다.
<html lang="ko">는 문서 전체를 감싸는 루트(root) 요소입니다. 모든 내용은 이 요소 안에 들어가며, lang="ko"는 문서의 주 언어가 한국어임을 밝힙니다. 검색 엔진과 스크린 리더는 이 값을 보고 내용을 알맞은 언어로 처리하므로, 영어 문서라면 en, 일본어 문서라면 ja처럼 바꿉니다.
<head>에는 문서 자체에 관한 정보, 즉 메타데이터(metadata)가 들어가며 화면에 직접 보이지 않습니다. 다음 요소들이 주로 들어갑니다.
<meta>: 문자 인코딩(charset), 뷰포트(viewport), 페이지 설명(description) 같은 정보를 정합니다.<title>: 브라우저의 탭이나 창 제목에 보이는 페이지 제목을 정합니다.<link>: 외부 CSS 파일이나 파비콘(favicon, 사이트 아이콘)을 연결합니다.<style>: 문서 안에 직접 CSS를 씁니다.<script>: 자바스크립트 코드를 넣거나 외부 자바스크립트 파일을 연결합니다.
<body>에는 화면에 보일 모든 내용이 들어갑니다. 글, 이미지, 버튼, 동영상처럼 사용자가 보는 것은 모두 <h1>, <p>, <img>, <a> 같은 요소로 이 안에 씁니다.
더 깊이: 호환 모드에서는 무엇이 달라질까
HTML 표준이 정한 문서 모드는 실제로 세 가지입니다. 현재 표준대로 해석하는 무호환 모드(no-quirks mode, 앞에서 말한 표준 모드), 오래된 브라우저를 흉내 내는 호환 모드(quirks mode), 그리고 몇 가지 동작만 옛 방식을 따르는 제한 호환 모드(limited-quirks mode)입니다. 브라우저는 문서 맨 앞의 DOCTYPE을 보고 모드를 고르는데, <!DOCTYPE html>은 지금의 모든 브라우저에서 무호환 모드가 됩니다. 다른 DOCTYPE을 쓰면 그 종류에 따라 제한 호환 모드나 호환 모드가 될 수 있으므로, 굳이 다른 선언을 쓸 이유가 없습니다.
호환 모드에서 달라지는 동작은 WHATWG의 Quirks Mode 표준에 목록으로 정리되어 있습니다. 예를 들어 CSS에서 color: ff0000처럼 # 없이 적은 색이나 width: 100처럼 단위 없이 적은 길이가 일부 속성에서 그대로 받아들여지고, 표 셀의 높이 계산과 body가 html을 채우는 방식도 달라집니다. 제한 호환 모드에서는 이 가운데 줄 높이 계산에 관한 두 가지만 옛 방식을 따릅니다.
지금 문서가 어떤 모드인지는 콘솔에서 document.compatMode로 확인합니다. 호환 모드이면 "BackCompat"이, 그렇지 않으면 "CSS1Compat"이 나옵니다. CSS가 다른 사이트와 다르게 적용되는데 원인을 찾지 못했다면, DOCTYPE이 빠졌거나 그 앞에 다른 내용이 들어가 있지 않은지 이 값으로 먼저 확인해 볼 수 있습니다.
태그와 요소
HTML 문서를 이루는 기본 단위는 요소(element)이고, 요소를 표시하는 표기가 태그(tag)입니다. <h1>, <p>, <img>처럼 <와 >로 둘러싼 키워드를 태그라고 부릅니다. 대부분의 태그는 시작 태그와 종료 태그가 한 쌍이며, 종료 태그는 </h1>처럼 < 뒤에 /가 붙습니다.
시작 태그와 종료 태그, 그 사이의 내용(content)을 모두 합친 것이 요소입니다. <h1>이것은 제목입니다.</h1>은 하나의 h1 요소이며, <h1>은 시작 태그, </h1>은 종료 태그, “이것은 제목입니다.”는 내용입니다.
<img>, <br>, <input>, <meta>, <link> 같은 빈 요소(void element)는 내용을 가질 수 없으므로 종료 태그도 쓰지 않습니다. HTML에서는 <img src="image.jpg">처럼 씁니다. <img src="image.jpg" />처럼 끝에 /를 붙여도 브라우저가 인식하지만, HTML에서 이 /는 아무 효과가 없습니다. XML에서 요소를 스스로 닫는 표기와 겉모양만 같을 뿐입니다.
속성: 요소에 정보 더하기
요소에는 내용 말고도 추가 정보를 줄 수 있으며, 이를 속성(attribute)이라고 합니다. 속성은 시작 태그 안에 속성명="값" 형태로 씁니다.
<a href="https://www.google.com" target="_blank" title="새 탭에서 구글 열기">구글로 이동</a>
<img src="images/logo.png" alt="회사 로고" width="100" height="50"><a> 요소는 링크를 만들며 href, target, title이 속성입니다. <img> 요소는 이미지를 넣으며 src, alt, width, height가 속성입니다. 각 속성의 뜻은 다음과 같습니다.
href: 링크가 가리키는 URL입니다.target: 링크를 열 위치입니다._blank는 새 탭이나 새 창에서 엽니다.title: 요소에 대한 보조 설명으로, 마우스를 올리면 툴팁으로 보일 수 있습니다.src: 이미지 파일의 경로(source)입니다.alt: 이미지를 불러오지 못했을 때 대신 보이고, 스크린 리더가 이미지를 설명할 때 읽는 대체 텍스트(alternative text)입니다. 접근성에서 특히 중요합니다.width,height: 이미지의 너비와 높이를 픽셀 단위로 정합니다. 크기는 보통 CSS로 조절하지만, 이 두 값을 적어 두면 브라우저가 이미지를 받기 전에 자리를 미리 잡아 화면이 덜컹거리지 않습니다.
속성을 쓸 때는 몇 가지 규칙이 있습니다. 값이 있는 속성은 이름과 값을 =로 잇고, required처럼 켜고 끄는 불리언 속성은 이름만 적어도 됩니다. HTML은 조건에 맞으면 따옴표 없는 값도 허용하지만, 공백이 있는 값에서 실수를 줄이기 위해 이 교재는 값을 항상 큰따옴표로 감쌉니다. 태그 이름과 속성, 속성과 속성 사이는 공백으로 구분합니다.
주석: 코드에 메모 남기기
코드에 설명이나 나중에 참고할 내용을 남기고 싶을 때는 주석(comment)을 씁니다. HTML 주석은 <!--로 시작해 -->로 끝납니다.
<!-- 아래 단락은 사용자 화면에 표시됩니다. -->
<p>이것은 주석 아래에 있는 단락입니다.</p>주석은 코드를 읽기 쉽게 하고, 다른 개발자나 나중의 내가 코드를 이해하는 데 도움을 줍니다. 잠시 쓰지 않을 코드를 주석으로 감싸 꺼 두는 데도 씁니다.
주석은 페이지 화면에는 보이지 않지만, 브라우저로 전달된 HTML 소스에는 그대로 남아 있습니다. 페이지 소스 보기나 개발자 도구를 열면 방문자도 읽을 수 있으므로, 비밀번호나 비밀 키 같은 정보는 절대 주석에 적지 않습니다.
블록 요소와 인라인 요소
브라우저의 기본 스타일에서 요소는 크게 블록(block)과 인라인(inline) 두 가지 방식으로 표시됩니다. 이 표시 방식은 요소의 의미와는 별개이며, 나중에 배울 CSS의 display 속성으로 바꿀 수 있습니다. 그래도 각 요소가 기본으로 어떻게 표시되는지 알아야 CSS로 배치를 조절할 수 있습니다.
블록 요소는 새 줄에서 시작하고, 너비를 따로 정하지 않으면 부모 요소의 사용할 수 있는 너비를 모두 채웁니다. 문단이나 제목처럼 한 덩어리로 놓이며, <div>, <h1>부터 <h6>, <p>, <ul>, <ol>, <li>, <form>, <header>, <footer>, <section>, <article>, <aside>가 대표적인 블록 요소입니다.
<h1>첫 번째 제목</h1>
<p>첫 번째 단락입니다.</p>
<p>두 번째 단락입니다.</p>
<div>이것은 div 블록입니다.</div>이 코드에서 제목, 두 문단, div는 각각 새 줄에서 시작해 차례로 아래로 쌓입니다. 너비는 화면 전체로 고정된 것이 아니라, 부모 요소의 사용할 수 있는 영역을 기준으로 정해집니다.
인라인 요소는 새 줄을 시작하지 않고, 내용에 필요한 만큼의 너비만 차지하며 글의 흐름 안에 놓입니다. 글의 일부를 강조하거나 링크를 넣을 때 주로 쓰며, <span>, <a>, <strong>, <em>, <img>, <input>, <label>, <button>이 대표적인 인라인 요소입니다.
안녕하세요, <strong>[여러분의 이름]</strong>입니다.
<a href="#">더 알아보기</a> 이곳에 <img src="icon.png" alt="아이콘"> 이미지가 있습니다.이 코드의 <strong>, 링크, 이미지는 글 사이에 이어져 놓입니다. 공간이 충분하면 같은 줄에 이어지고, 화면이 좁으면 글자처럼 다음 줄로 넘어갑니다. input이나 button 같은 입력 요소는 인라인으로 놓이지만 너비와 높이를 다루는 방식이 일반 글자와 다르므로, 여기서는 요소가 문서에서 무엇을 뜻하는지와 CSS로 어떻게 보이는지를 나눠 생각하는 데 집중합니다.
정리
- HTML 문서는
<!DOCTYPE html>, 루트인<html>, 문서 정보를 담는<head>, 화면 내용을 담는<body>로 이루어집니다. <!DOCTYPE html>은 문서를 표준 모드로 해석하게 하며, DOM에서는html요소의 부모가 아니라 형제입니다.- 요소는 시작 태그, 내용, 종료 태그를 합친 것이고, 빈 요소는 내용과 종료 태그가 없습니다.
- 속성은 시작 태그 안에
이름="값"으로 쓰며,alt는 접근성에,width와height는 자리를 미리 잡는 데 쓰입니다. - 주석은 화면에 보이지 않지만 소스에는 남으므로 비밀 정보를 적지 않습니다.
- 블록 요소는 새 줄에서 시작해 너비를 채우고, 인라인 요소는 글의 흐름 안에서 내용만큼 차지하며, 표시 방식은 CSS로 바꿀 수 있습니다.
연습 문제
1. title과 h1
기본 예제를 structure.html로 저장해 엽니다. <title>의 내용만 “구조 실험”으로 바꾸고 저장한 뒤 새로고침하면, 브라우저 탭과 페이지 안의 제목 중 어디가 바뀔까요? 이번에는 <h1>의 내용만 바꾸면 어떻게 될까요?
해설 보기
<title>을 바꾸면 브라우저 탭의 제목만 “구조 실험”으로 바뀌고, 페이지 안의 큰 제목은 그대로입니다. <title>은 head에 있는 문서 정보이기 때문입니다.
<h1>을 바꾸면 반대로 페이지 안의 제목만 바뀌고 탭 제목은 그대로입니다. <h1>은 body에 있는 화면의 내용입니다.
2. 큰 div와 작은 h1
CSS로 글자를 아주 크게 키운 div와, 글자를 작게 줄인 h1이 있습니다. 문서의 제목이라는 의미를 가진 것은 어느 쪽일까요?
해설 보기
h1입니다. 요소의 의미는 어떤 태그를 썼는지로 정해지고, 글자 크기는 CSS로 얼마든지 바꿀 수 있는 표현일 뿐입니다. 스크린 리더와 검색 엔진은 h1을 제목으로 인식하지만, 크게 보이는 div는 의미 없는 묶음으로 처리합니다.
그래서 제목이 필요하면 크기와 상관없이 h1부터 h6을 쓰고, 보이는 크기는 CSS로 맞춥니다.
3. 주석에 적은 비밀번호
관리자 비밀번호를 HTML 주석에 적어 두면 화면에 보이지 않으니 방문자에게 비밀이 지켜질까요?
해설 보기
지켜지지 않습니다. 주석은 화면에 그려지지 않을 뿐, 서버가 보낸 HTML 소스에 그대로 들어 있습니다. 방문자가 페이지 소스 보기나 개발자 도구의 Elements 패널을 열면 주석 내용을 읽을 수 있습니다.
브라우저로 보내는 HTML, CSS, 자바스크립트에는 비밀 정보를 넣지 않고, 비밀은 서버에서만 다룹니다.
다음 글 텍스트, 링크, 이미지 다루기에서는 제목과 문단, 강조 같은 텍스트 요소와 링크, 이미지를 넣는 방법을 자세히 다룹니다.