HTML이 기대한 대로 동작하게 만드는 필수 태그들
(blog.jim-nielsen.com)- 웹페이지를 브라우저에서 예상한 대로 표시하려면 몇 가지 기본 HTML 태그를 반드시 포함해야 함
-
<!doctype html>은 표준 모드 렌더링을 보장해 레이아웃 계산 오류를 방지함 -
<html lang="en">은 언어 정보 제공으로 접근성, 검색, 번역 품질을 향상시킴 -
<meta charset="utf-8">과<meta name="viewport" ...>은 각각 문자 인코딩과 모바일 표시 비율을 제어함 - 이런 태그들은 단순한 형식 요소가 아니라, 웹 표준과 사용자 경험의 일관성을 유지하는 핵심 구성요소임
HTML 기본 구조와 필수 태그 개요
- 글은 Alex Petros의 발표중 “Incantations that make HTML work correctly” 슬라이드에서 영감을 받아 작성된 내용임
- 저자는 브라우저에서 HTML 파일을 직접 열 때 항상 포함해야 하는 기본 스니펫을 정리함
- 예시로 제시된 기본 구조는 다음과 같음
<!doctype html> <html lang="en"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
- 각 태그는 브라우저가 HTML을 표준적으로 해석하고 표시하도록 돕는 역할을 함
- 누락 시 브라우저가 비표준 모드(quirks mode) 로 전환되거나, 문자 깨짐, 모바일 화면 축소 등 문제가 발생함
<!doctype html> — 표준 모드 선언
-
<!doctype html>은 브라우저가 표준 모드(standards mode) 로 렌더링하도록 지시하는 선언임- 이 선언이 없으면 브라우저는 quirks mode로 전환되어, 과거 비표준 HTML 동작을 에뮬레이션함
- 그 결과 레이아웃, 크기, 정렬 계산이 달라져 예기치 않은 표시 오류가 발생함
-
<!doctype html>은 대소문자 구분이 없으며,<!DOCTYPE HTML>이나<!doCTypE HTml>등 어떤 형태로도 인식됨- 저자는 “1998년식 마크업을 쓰고 싶다면 대문자로 써도 된다”고 농담을 덧붙임
<html lang="en"> — 문서 언어 지정
-
<html lang="en">은 문서의 기본 언어를 명시하는 태그임- 이 정보는 브라우저, 검색엔진, 스크린리더 등 다양한 도구가 활용함
- 주요 활용 예시
- 스크린리더가 올바른 발음과 음성 톤을 선택
- 검색엔진이 색인 및 번역 정확도를 향상
- 맞춤법 검사 등 로케일 기반 기능을 적용
- 언어 속성을 생략해도 화면상 문제는 없어 보이지만, 주변 도구들이 잘못된 처리를 할 수 있음
- 따라서 HTML 내부에 명시적으로 포함하는 것이 바람직함
- 서버 응답 헤더로도 언어 정보를 전달할 수 있으나, 로컬 파일을 직접 열 때는 HTML 내 지정이 더 안전함
- 예시 코드
return new Response( "<!doctype html><h1>Hello world</h1>", { status: 200, headers: { "Content-Type": "text/html; charset=utf-8" }, } );
- 예시 코드
<meta charset="utf-8"> — 문자 인코딩 지정
-
<meta charset="utf-8">은 브라우저가 문서의 문자 인코딩 방식을 인식하도록 함- 이를 통해 é, ü, ñ, ©, ™, ®, …, 👍 등 비ASCII 문자가 올바르게 표시됨
- 이 태그가 없으면 문서 내 특수문자나 스마트 인용부호가 깨져 보일 수 있음
- 저자는 자신의 블로그에서 “스마트 인용부호(smart quotes)”가 깨지는 사례를 예로 듦
- 예시 비교
-
<meta charset="utf-8">이 없는 경우: 특수문자와 이모지가 깨짐 - 포함한 경우: 모든 문자가 정상 표시
-
- 블로그에는 두 경우를 비교한 스크린샷 이미지가 첨부되어 있음
<meta name="viewport" content="width=device-width,initial-scale=1.0"> — 모바일 뷰포트 설정
- 이 태그는 모바일 브라우저에서 화면 비율과 확대 비율을 제어함
- 누락 시 모바일 기기에서 페이지가 축소되어 작게 표시됨
- 저자는 “데스크톱에서는 잘 보이는데, 모바일에서 열면 모든 게 작게 보인다”며 meta viewport 태그를 잊은 사례를 소개함
- 왼쪽(태그 없음)과 오른쪽(태그 있음) 비교 스크린샷을 통해 차이를 시각적으로 설명함
- 따라서 간단한 프로토타입이라도 이 태그를 포함해야 기대한 레이아웃 비율을 유지할 수 있음
마무리 — HTML의 진짜 기본
- 저자는 마지막에 “가장 중요한 스니펫을 잊었다”며 농담을 던짐
- 예시로 다음 코드를 제시
<div id="root"></div> <script src="bundle.js"></script>
- 예시로 다음 코드를 제시
- 이는 현대 웹 개발에서 자주 사용하는 JavaScript 기반 앱 구조를 풍자적으로 언급한 것임
- 전체적으로 글은 HTML의 기초 태그들이 웹 표준 동작을 보장하는 핵심 요소임을 강조함
Hacker News 의견
-
재미있는 사실로, 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년 전 공개된 기존 코드를 그대로 쓰는 듯함 -
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 이후로 바뀐 건지 궁금함 -
<div id="root"></div>와<script src="bundle.js"></script>예시가 농담인 건 알지만,<main>...</main>태그가 빠진 듯함
이 태그를 쓰면 스크린리더가 페이지의 크롬 영역을 건너뛰어 접근성이 좋아짐
추가로<nav>나role="navigation"을 함께 쓰면 더 좋음- 나는 시각장애인은 아니지만, 스크린리더 친화적 웹사이트를 만들 때 탐구해봤음
내 결론은 내비게이션 HTML을 마지막에 배치하고 CSS로 시각적으로만 위로 올리는 게 최적이었음 - “농담”이라는 부분을 이해 못했음, 누가 설명해줄 수 있는지 궁금함
- 나는 시각장애인은 아니지만, 스크린리더 친화적 웹사이트를 만들 때 탐구해봤음
-
TFA의 HTML이 잘못된 DOCTYPE을 가지고 있음 —
"DOCTYPE"과"html"사이의 공백이 빠져 있고, 속성 간 공백도 없음
HTML 스펙에 따르면 속성 사이에는 ASCII 공백이 필요함
아마 HTML minifier가 자동으로 제거한 듯함
minify-htmlRust 크레이트의enable_possibly_noncompliant옵션을 쓰면 이런 결과가 나옴
파서 스펙상 허용되지만 작성 스펙상은 유효하지 않은 HTML을 의도적으로 이용한 사례임- 참고로, TFA의 웹사이트 자체가 이런 오류를 포함한다는 뜻이지, 기사 내용이 잘못됐다는 건 아님
- 왜 작성 스펙에서는
"doctypehtml"같은 걸 허용하지 않는지 궁금함
어차피 파서가 처리할 수 있다면 굳이 비표준으로 남겨둘 이유가 없어 보임
-
웹 개발자가 아닌데, 왜 요즘 사이트들은 화면의 20%만 콘텐츠를 쓰는지 궁금함
내 해상도는 2560x1487인데 80%가 공백임
글을 읽으려면 170% 확대해야 함
예전 블로그들은 이런 문제가 없었는데, 의도된 디자인인지 CSS 문제인지 알고 싶음- 신문처럼 가독성을 위해 텍스트 폭을 제한하는 경우가 많음
눈의 이동 거리가 길면 피로도가 높아지고, 시각적으로도 너무 넓은 폭은 “빈약해 보이는” 인상을 줌
다만 이 사이트는 폭이 지나치게 좁은 편임
만약 확대해야 읽기 편하다면 CSS 설계가 잘못된 것일 수도 있음 - UX StackExchange의 논의에서도 비슷한 이유로 폭을 제한한다고 함
- 너무 넓은 단락을 피하려는 이유임
나도 HN을 항상 150% 줌으로 봄
모바일에서는 괜찮지만 데스크톱 기본 폰트는 너무 작음 - 이 사이트는 오래전에 만들어져 거의 UI 변화가 없는 드문 사례임
불편하더라도 줌으로 해결 가능함 - 예전에 UX 일을 할 때도 고정 폭 중앙 정렬을 기본으로 디자인했음
HN도 같은 접근을 쓰는 듯함
- 신문처럼 가독성을 위해 텍스트 폭을 제한하는 경우가 많음
-
나는 종종 HTML5 Boilerplate를 참고함
기본 구조를 빠르게 세팅할 때 유용함- 예전 Facebook의 og: 메타데이터가 들어 있는 게 아이러니함
지금은 회사 이름이 Meta라서 더 독점적으로 보임
어쩌면 이름의 의미가 메타버스가 아니라 메타데이터였을지도 모름 - 이런 템플릿을 필요할 때 어떻게 찾는지 궁금함
- 예전 Facebook의 og: 메타데이터가 들어 있는 게 아이러니함
-
Web Components를 번들링 없이 쓰는 걸 선호함
나는 Lit Elements를 순수 자바스크립트로 사용 중임
TypeScript를 안 쓰는 건 요즘엔 마치 펀치카드를 쓴다고 말하는 것과 비슷한 반응을 얻음- 37signals는 자체 프레임워크 Stimulus를 사용함
CEO는 no-build 접근법을 지지하는데, 복잡성을 줄이고 코드 학습을 쉽게 하기 때문임
참고: Basecamp - 나도 Web Components를 쓸 때는 번들링을 피함
HTTP/2 환경에서는 파일을 나눠도 괜찮고, immutable 캐시 헤더를 설정하면 변경된 파일만 다시 받아 효율적임 - 요즘은 ESM 로딩이 충분히 좋아져서 번들 없이도 쾌적함
importmap을 활용하면 의존성 관리도 쉬움
TypeScript는 유지하지만, 최신"target"설정으로 타입 제거만 수행하게 하면 빠르고 단순함 - autocomplete를 끈 이유가 궁금함
나는 그 기능 없이는 코딩하기 힘듦
- 37signals는 자체 프레임워크 Stimulus를 사용함
-
<meta name="color-scheme" content="light dark">를 추가하면 자동으로 다크 모드 지원이 가능함- 좋은 팁임, 앞으로 기본 설정으로 넣는 걸 고려해야겠음
-
요즘은 선택 사항이지만, 나는 항상 meta 정보를
<head>안에 넣는 걸 고집함
명확성과 일관성을 위해서임 -
<html lang="en">대신<html lang="en-US">를 쓰는 게 더 낫다고 생각함- “en-INTL” 같은 국제 영어 코드가 있으면 좋겠음
미국식 표현을 줄이고 ISO 단위를 기본으로 쓰는 식으로
논리적 문장부호처럼 언어적 차이를 줄이는 방향이 필요함
또한 어떤 키보드로든 모든 언어를 쓸 수 있어야 한다고 생각함 - 하지만 “en”과 “en-US”는 RFC 5646에 따라 명확히 다른 의미임
RFC 5646 문서를 참고하면, “en”은 일반 영어, “en-US”는 미국식 영어를 뜻함 - 이 설정은 스크린리더의 발음이나 브라우저 맞춤법 검사기에 영향을 줄 수 있음
예를 들어 US 영어와 영국 영어를 구분할 수 있게 됨
- “en-INTL” 같은 국제 영어 코드가 있으면 좋겠음