# HTML이 기대한 대로 동작하게 만드는 필수 태그들

> Clean Markdown view of GeekNews topic #23963. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=23963](https://news.hada.io/topic?id=23963)
- GeekNews Markdown: [https://news.hada.io/topic/23963.md](https://news.hada.io/topic/23963.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-10-28T10:03:59+09:00
- Updated: 2025-10-28T10:03:59+09:00
- Original source: [blog.jim-nielsen.com](https://blog.jim-nielsen.com/2025/dont-forget-these-html-tags/)
- Points: 30
- Comments: 3

## Summary

웹페이지가 브라우저에서 **예상한 대로 렌더링**되려면 몇 가지 태그가 필수입니다. `<!doctype html>`은 **표준 모드**를 강제해 오래된 레이아웃 버그를 막고, `&lt;html lang&gt;`은 **접근성과 검색 정확도**를 높이며, `&lt;meta charset&gt;`과 `&lt;meta viewport&gt;`는 각각 **문자 인코딩**과 **모바일 표시 비율**을 제어합니다. 단순한 형식 요소처럼 보이지만, 이 네 가지는 HTML이 ‘제대로’ 작동하도록 만드는 최소한의 주문과도 같습니다. 기본기를 다시 점검하고 싶은 프런트엔드 개발자라면 한 번쯤 되새겨볼 만한 내용입니다.

## Topic Body

- 웹페이지를 브라우저에서 예상한 대로 표시하려면 몇 가지 **기본 HTML 태그**를 반드시 포함해야 함  
- `<!doctype html>`은 **표준 모드 렌더링**을 보장해 레이아웃 계산 오류를 방지함  
- `&lt;html lang="en"&gt;`은 **언어 정보 제공**으로 접근성, 검색, 번역 품질을 향상시킴  
- `&lt;meta charset="utf-8"&gt;`과 `&lt;meta name="viewport" ...&gt;`은 각각 **문자 인코딩**과 **모바일 표시 비율**을 제어함  
- 이런 태그들은 단순한 형식 요소가 아니라, **웹 표준과 사용자 경험의 일관성**을 유지하는 핵심 구성요소임  

---

### HTML 기본 구조와 필수 태그 개요
- 글은 Alex Petros의 발표 “Incantations that make HTML work correctly”에서 영감을 받아 작성된 내용임  
  - 저자는 브라우저에서 HTML 파일을 직접 열 때 항상 포함해야 하는 **기본 스니펫**을 정리함  
  - 예시로 제시된 기본 구조는 다음과 같음  
    ```
    <!doctype html>
    &lt;html lang="en"&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;meta name="viewport" content="width=device-width,initial-scale=1.0"&gt;
    ```
- 각 태그는 브라우저가 HTML을 **표준적으로 해석하고 표시**하도록 돕는 역할을 함  
  - 누락 시 브라우저가 **비표준 모드(quirks mode)** 로 전환되거나, 문자 깨짐, 모바일 화면 축소 등 문제가 발생함  

### `<!doctype html>` — 표준 모드 선언
- `<!doctype html>`은 브라우저가 **표준 모드(standards mode)** 로 렌더링하도록 지시하는 선언임  
  - 이 선언이 없으면 브라우저는 **quirks mode**로 전환되어, 과거 비표준 HTML 동작을 에뮬레이션함  
  - 그 결과 **레이아웃, 크기, 정렬 계산**이 달라져 예기치 않은 표시 오류가 발생함  
- `<!doctype html>`은 대소문자 구분이 없으며, `<!DOCTYPE HTML>`이나 `<!doCTypE HTml>` 등 어떤 형태로도 인식됨  
  - 저자는 “1998년식 마크업을 쓰고 싶다면 대문자로 써도 된다”고 농담을 덧붙임  

### `&lt;html lang="en"&gt;` — 문서 언어 지정
- `&lt;html lang="en"&gt;`은 문서의 **기본 언어를 명시**하는 태그임  
  - 이 정보는 브라우저, 검색엔진, 스크린리더 등 다양한 도구가 활용함  
- 주요 활용 예시  
  - 스크린리더가 **올바른 발음과 음성 톤**을 선택  
  - 검색엔진이 **색인 및 번역 정확도**를 향상  
  - 맞춤법 검사 등 **로케일 기반 기능**을 적용  
- 언어 속성을 생략해도 화면상 문제는 없어 보이지만, 주변 도구들이 잘못된 처리를 할 수 있음  
  - 따라서 HTML 내부에 명시적으로 포함하는 것이 바람직함  
- 서버 응답 헤더로도 언어 정보를 전달할 수 있으나, **로컬 파일을 직접 열 때는 HTML 내 지정이 더 안전**함  
  - 예시 코드  
    ```
    return new Response(
        "<!doctype html>&lt;h1&gt;Hello world&lt;/h1&gt;",
        {
            status: 200,
            headers: { "Content-Type": "text/html; charset=utf-8" },
        }
    );
    ```

### `&lt;meta charset="utf-8"&gt;` — 문자 인코딩 지정
- `&lt;meta charset="utf-8"&gt;`은 브라우저가 문서의 **문자 인코딩 방식을 인식**하도록 함  
  - 이를 통해 é, ü, ñ, ©, ™, ®, …, 👍 등 **비ASCII 문자**가 올바르게 표시됨  
- 이 태그가 없으면 문서 내 특수문자나 스마트 인용부호가 깨져 보일 수 있음  
  - 저자는 자신의 블로그에서 “스마트 인용부호(smart quotes)”가 깨지는 사례를 예로 듦  
- 예시 비교  
  - `&lt;meta charset="utf-8"&gt;`이 없는 경우: 특수문자와 이모지가 깨짐  
  - 포함한 경우: 모든 문자가 정상 표시  
- 블로그에는 두 경우를 비교한 **스크린샷 이미지**가 첨부되어 있음  

### `&lt;meta name="viewport" content="width=device-width,initial-scale=1.0"&gt;` — 모바일 뷰포트 설정
- 이 태그는 모바일 브라우저에서 **화면 비율과 확대 비율**을 제어함  
  - 누락 시 모바일 기기에서 페이지가 **축소되어 작게 표시**됨  
- 저자는 “데스크톱에서는 잘 보이는데, 모바일에서 열면 모든 게 작게 보인다”며 **meta viewport 태그를 잊은 사례**를 소개함  
  - 왼쪽(태그 없음)과 오른쪽(태그 있음) 비교 스크린샷을 통해 차이를 시각적으로 설명함  
- 따라서 간단한 프로토타입이라도 이 태그를 포함해야 **기대한 레이아웃 비율**을 유지할 수 있음  

### 마무리 — HTML의 진짜 기본
- 저자는 마지막에 “가장 중요한 스니펫을 잊었다”며 농담을 던짐  
  - 예시로 다음 코드를 제시  
    ```
    &lt;div id="root"&gt;&lt;/div&gt;
    &lt;script src="bundle.js"&gt;&lt;/script&gt;
    ```
- 이는 현대 웹 개발에서 자주 사용하는 **JavaScript 기반 앱 구조**를 풍자적으로 언급한 것임  
- 전체적으로 글은 HTML의 **기초 태그들이 웹 표준 동작을 보장하는 핵심 요소**임을 강조함

## Comments



### Comment 45534

- Author: neo
- Created: 2025-10-28T10:03:59+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=45719140) 
- 재미있는 사실로, **HN과 paulgraham.com** 모두 DOCTYPE 선언이 없어서 **Quirks Mode**로 렌더링됨  
  개발자 도구에서 `document.compatMode`로 확인할 수 있음  
  나는 마우스오버된 요소의 텍스트를 쉽게 복사하기 위한 userscript를 쓰는데, Quirks Mode에서는 불안정하게 동작함  
  `document.write("<!DOCTYPE html>" + document.documentElement.innerHTML)`로 강제로 바꿀 수는 있지만 문서 전체가 초기화되어 문제를 일으킴  
  사용자 입장에서 더 **깨끗한 방법**으로 Standards Mode로 강제할 수 있는지 궁금함
  - `dang`이 HN의 **사용성 개선**을 좀 해줬으면 함  
    기본 폰트 크기가 12px 수준이라 대부분의 현대 기기에서는 너무 작게 보임  
    CSS도 약 13년 전 공개된 [기존 코드](https://github.com/wting/hackernews/blob/5a3296417d23d1ecc901447af63dfc27af217f40/news.arc#L473)를 그대로 쓰는 듯함
  - **uBlock 필터**로 해결 가능함  
    예: `||news.ycombinator.com/*$replace=/<html/<!DOCTYPE html><html/`
  - 일반적으로는 불가능하지만, WHATWG가 `document.compatMode`를 **쓰기 가능한 속성**으로 정의하면 가능할 것임  
    그나마 나은 방법은 기존 노드를 참조(`var old = document.documentElement`)해두고, `document.write`로 비어 있는 html을 쓴 뒤 다시 삽입하는 방식임  
    html 속성을 유지하려면 `outerHTML`을 활용하거나 속성을 하나씩 복원해야 함
  - 개인적으로는 브라우저가 항상 **Standards Mode**로 렌더링하거나, 사용자가 설정할 수 있으면 좋겠음  
    오래된 브라우저 호환성을 기본값으로 둘 필요는 없음  
    MDN의 quirks 문서를 읽고 나니, 앞으로는 DOCTYPE 대신 `Content-Type: application/xhtml+xml`을 써볼까 함  
    DOCTYPE은 내 HTML 출력 엔진에서 유일하게 **예외 처리**가 필요한 태그라서 마음에 들지 않음

- `<!doctype html>`이 자동으로 **UTF-8 인코딩**을 의미한다고 생각했는데, HTML5 이후로 바뀐 건지 궁금함

- `&lt;div id="root"&gt;&lt;/div&gt;`와 `&lt;script src="bundle.js"&gt;&lt;/script&gt;` 예시가 농담인 건 알지만, `&lt;main&gt;...&lt;/main&gt;` 태그가 빠진 듯함  
  이 태그를 쓰면 스크린리더가 페이지의 **크롬 영역**을 건너뛰어 접근성이 좋아짐  
  추가로 `&lt;nav&gt;`나 `role="navigation"`을 함께 쓰면 더 좋음
  - 나는 시각장애인은 아니지만, **스크린리더 친화적** 웹사이트를 만들 때 탐구해봤음  
    내 결론은 내비게이션 HTML을 **마지막에 배치**하고 CSS로 시각적으로만 위로 올리는 게 최적이었음
  - “농담”이라는 부분을 이해 못했음, 누가 설명해줄 수 있는지 궁금함

- TFA의 HTML이 잘못된 DOCTYPE을 가지고 있음 — `"DOCTYPE"`과 `"html"` 사이의 공백이 빠져 있고, 속성 간 공백도 없음  
  [HTML 스펙](https://html.spec.whatwg.org/multipage/syntax.html#attributes-2)에 따르면 속성 사이에는 ASCII 공백이 필요함  
  아마 **HTML minifier**가 자동으로 제거한 듯함  
  `minify-html` Rust 크레이트의 `enable_possibly_noncompliant` 옵션을 쓰면 이런 결과가 나옴  
  파서 스펙상 허용되지만 작성 스펙상은 유효하지 않은 HTML을 **의도적으로 이용**한 사례임
  - 참고로, TFA의 **웹사이트 자체**가 이런 오류를 포함한다는 뜻이지, 기사 내용이 잘못됐다는 건 아님
  - 왜 작성 스펙에서는 `"doctypehtml"` 같은 걸 허용하지 않는지 궁금함  
    어차피 파서가 처리할 수 있다면 굳이 비표준으로 남겨둘 이유가 없어 보임

- 웹 개발자가 아닌데, 왜 요즘 사이트들은 **화면의 20%만** 콘텐츠를 쓰는지 궁금함  
  내 해상도는 2560x1487인데 80%가 공백임  
  글을 읽으려면 170% 확대해야 함  
  예전 블로그들은 이런 문제가 없었는데, 의도된 디자인인지 **CSS 문제**인지 알고 싶음
  - 신문처럼 **가독성**을 위해 텍스트 폭을 제한하는 경우가 많음  
    눈의 이동 거리가 길면 피로도가 높아지고, 시각적으로도 너무 넓은 폭은 “빈약해 보이는” 인상을 줌  
    다만 이 사이트는 폭이 지나치게 좁은 편임  
    만약 확대해야 읽기 편하다면 CSS 설계가 잘못된 것일 수도 있음
  - [UX StackExchange의 논의](https://ux.stackexchange.com/questions/108801/what-is-the-best-number-of-paragraph-width-for-readability)에서도 비슷한 이유로 폭을 제한한다고 함
  - 너무 넓은 단락을 피하려는 이유임  
    나도 HN을 항상 **150% 줌**으로 봄  
    모바일에서는 괜찮지만 데스크톱 기본 폰트는 너무 작음
  - 이 사이트는 오래전에 만들어져 거의 **UI 변화가 없는** 드문 사례임  
    불편하더라도 줌으로 해결 가능함
  - 예전에 UX 일을 할 때도 **고정 폭 중앙 정렬**을 기본으로 디자인했음  
    HN도 같은 접근을 쓰는 듯함

- 나는 종종 [HTML5 Boilerplate](https://github.com/h5bp/html5-boilerplate/blob/main/dist/index.html)를 참고함  
  기본 구조를 빠르게 세팅할 때 유용함
  - 예전 Facebook의 **og: 메타데이터**가 들어 있는 게 아이러니함  
    지금은 회사 이름이 Meta라서 더 **독점적**으로 보임  
    어쩌면 이름의 의미가 메타버스가 아니라 메타데이터였을지도 모름
  - 이런 템플릿을 필요할 때 **어떻게 찾는지** 궁금함

- **Web Components**를 번들링 없이 쓰는 걸 선호함  
  나는 Lit Elements를 **순수 자바스크립트**로 사용 중임  
  TypeScript를 안 쓰는 건 요즘엔 마치 펀치카드를 쓴다고 말하는 것과 비슷한 반응을 얻음
  - 37signals는 자체 프레임워크 [Stimulus](https://stimulus.hotwired.dev/)를 사용함  
    CEO는 **no-build 접근법**을 지지하는데, 복잡성을 줄이고 코드 학습을 쉽게 하기 때문임  
    참고: [Basecamp](https://basecamp.com/)
  - 나도 Web Components를 쓸 때는 번들링을 피함  
    HTTP/2 환경에서는 파일을 나눠도 괜찮고, **immutable 캐시 헤더**를 설정하면 변경된 파일만 다시 받아 효율적임
  - 요즘은 **ESM 로딩**이 충분히 좋아져서 번들 없이도 쾌적함  
    importmap을 활용하면 의존성 관리도 쉬움  
    TypeScript는 유지하지만, 최신 `"target"` 설정으로 **타입 제거만 수행**하게 하면 빠르고 단순함
  - autocomplete를 끈 이유가 궁금함  
    나는 그 기능 없이는 코딩하기 힘듦

- `&lt;meta name="color-scheme" content="light dark"&gt;`를 추가하면 자동으로 **다크 모드 지원**이 가능함  
  - 좋은 팁임, 앞으로 기본 설정으로 넣는 걸 고려해야겠음

- 요즘은 선택 사항이지만, 나는 항상 **meta 정보를 `&lt;head&gt;` 안에** 넣는 걸 고집함  
  명확성과 일관성을 위해서임

- `&lt;html lang="en"&gt;` 대신 `&lt;html lang="en-US"&gt;`를 쓰는 게 더 낫다고 생각함
  - “en-INTL” 같은 **국제 영어 코드**가 있으면 좋겠음  
    미국식 표현을 줄이고 ISO 단위를 기본으로 쓰는 식으로  
    [논리적 문장부호](https://slate.com/human-interest/2011/05/logical-punctuation-should-we-start-placing-commas-outside-quotation-marks.html)처럼 언어적 차이를 줄이는 방향이 필요함  
    또한 어떤 키보드로든 모든 언어를 쓸 수 있어야 한다고 생각함
  - 하지만 “en”과 “en-US”는 **RFC 5646**에 따라 명확히 다른 의미임  
    [RFC 5646 문서](https://datatracker.ietf.org/doc/html/rfc5646)를 참고하면, “en”은 일반 영어, “en-US”는 미국식 영어를 뜻함
  - 이 설정은 **스크린리더의 발음**이나 **브라우저 맞춤법 검사기**에 영향을 줄 수 있음  
    예를 들어 US 영어와 영국 영어를 구분할 수 있게 됨

### Comment 45565

- Author: ahwjdekf
- Created: 2025-10-28T23:57:07+09:00
- Points: 2

필수라면 왜 기본으로 동작하지 않을까? 하여튼 웹은 참 이상하죠. 사고방식이 남다르네요

### Comment 45712

- Author: dongho42
- Created: 2025-10-31T21:58:57+09:00
- Points: 1
- Parent comment: 45565
- Depth: 1

하위호환 때문 아닐까요? 기본 동작방식을 그냥 바꿔버리면 이전에 잘 돌고 있던게 깨질 수 있으니까요
