04-typography — 타이포그래피
“텍스트가 화면에 그려지는 일은 단순히 폰트를 고르는 일이 아니다” — 폰트 파일을 어디서 받아, 어떻게 로드하고, 메트릭을 어떻게 맞추고, 어떤 가변 축으로 변주하고, 어떤 텍스트 속성으로 흘리는가의 7단 파이프라인이다.
한 문장 답 (Pyramid Top)
웹 타이포그래피는
폰트 자원 → 로딩 → 메트릭 → 가변성 → 텍스트 흐름 → 유체 스케일 → OpenType 기능의 7층 스택이다. 각 층마다 layout shift, FOUT/FOIT, CLS, 접근성 줌 같은 함정이 있고, 2024년 이후의 모던 CSS(size-adjust,text-wrap: balance,clamp() + cqi, variable fonts)가 이를 거의 다 해결할 수 있게 됐다.
챕터 지도 (Mermaid)
Why — 왜 별도 챕터인가
타이포그래피는 CSS의 모든 레이어가 교차하는 지점이다.
- Cascade:
font-family는 상속된다 — root에서 한 번만 정해도 모든 자식이 받는다. - Layout: 폰트 메트릭은 라인 박스 높이를 결정한다 — 같은
font-size도 폰트마다 베이스라인이 다르다. - Visual: 폰트는 화면의 70% 이상의 픽셀을 차지한다 — 본문의 가독성이 디자인의 절반이다.
- Motion: variable font 축을 트랜지션하면 글자가 부드럽게 굵어진다 —
font-variation-settings가 애니메이션 가능 속성이다. - Architecture: 폰트 토큰(
--font-display,--font-body)은 디자인 시스템의 핵심 토큰이다.
그리고 한국어 웹 타이포는 영문보다 훨씬 어렵다 — 한 폰트 파일이 3MB를 넘기 때문에 서브셋팅·동적 로딩·CDN 전략이 필수다.
How — 어떻게 읽나
다음 7개 문서를 순서대로 읽으면 약 90분 걸린다. 01-03이 로딩과 메트릭의 기초, 04-05가 글자 자체와 흐름, 06-07이 반응형과 미세 조판이다.
| # | 파일 | 읽는 데 | 핵심 키워드 |
|---|---|---|---|
| 01 | 01-font-stack | 12분 | system stack, fallback, font matching, local() |
| 02 | 02-web-fonts | 15분 | @font-face, font-display, swap/optional, subset |
| 03 | 03-font-metrics | 13분 | line-height, ascent/descent, leading-trim, size-adjust |
| 04 | 04-variable-fonts | 15분 | wght/wdth/slnt/opsz, font-variation-settings |
| 05 | 05-text-properties | 12분 | text-wrap balance/pretty, hyphens, word-break |
| 06 | 06-fluid-typography | 10분 | clamp(), cqi, modular scale, accessible scaling |
| 07 | 07-opentype-features | 10분 | font-feature-settings, tnum, ss01, ligatures |
의존성: 02는 01의 fallback 위에 web font를 얹는다. 03은 02 로드 후의 metric 충돌을 다룬다. 04는 03의 metric을 가변화한다. 05·06·07은 글자가 정해진 다음 단계다.
What — 한 페이지 요약
| 문서 | 한 줄 결론 |
|---|---|
| 01 | font-family는 선언이 아닌 순서다. system stack(-apple-system, Segoe UI)으로 fallback을 깐 뒤 web font를 얹는다. |
| 02 | @font-face { font-display: swap }은 가시성을, optional은 안정성을 택한다 — 둘은 완전히 반대 트레이드오프다. |
| 03 | line-height: 1.5는 단위 없는 숫자여야 한다. em은 상속이 누적되어 깨진다. size-adjust로 fallback metric을 맞춰 CLS를 0으로. |
| 04 | Variable font 한 파일 = 정적 폰트 9개를 압축한 것. 축(wght 100..900)이 연속이라 200 같은 비표준 값도 가능하다. |
| 05 | text-wrap: balance는 제목, pretty는 본문. 영문은 hyphens: auto로 분절, 한글은 word-break: keep-all로 단어 보호. |
| 06 | clamp(min, ideal, max)는 유체 타이포의 기본 공식. 뷰포트(vw) 대신 컨테이너(cqi)를 기준 삼으면 진짜 컴포넌트 단위 반응형이 된다. |
| 07 | font-feature-settings: "tnum" 한 줄로 표의 숫자가 가지런해진다. ss01은 폰트가 제공하는 스타일 세트를 선택한다. |
What-if — 이 챕터의 한계
- 이 챕터는 CSS 측면만 다룬다. 폰트 파일의 라이선스·웹폰트 서비스 선택(Google Fonts·Adobe Fonts·자체 호스팅)은 인프라 영역.
- 접근성 측면의 텍스트 대비·읽기 순서·스크린리더는
05-color-visual(대비)과 별도 a11y 도메인. - CJK 폰트 렌더링의 동적 서브셋팅 서버 구현은 다루지 않는다 — Google Fonts CSS API가 자동 처리.
- 디자인 토큰으로 폰트 시스템을 어떻게 모델링하는가는
08-architecture영역.
Insight — 한 단락 이야기
“FOIT은 IE의 죄, FOUT은 모두의 합의, swap은 결정의 외주”
2008년
@font-face가 IE로 부활했을 때 IE는 폰트 로드 동안 텍스트를 숨겼다 — FOIT (Flash of Invisible Text). 사용자는 흰 화면을 봤고, 폰트가 느린 회사는 매출 손실을 봤다. 2014년 Chrome이 3초 후 fallback 표시를 도입했고, 곧 모든 브라우저가 같은 정책을 택했다 — 짧은 시간의 FOUT (Flash of Unstyled Text) 이 FOIT보다 낫다는 합의. 2017년font-display속성이 표준화되며 이 결정이 개발자의 손으로 넘어왔다 —swap(가시성 우선),optional(레이아웃 안정 우선),block(짧은 FOIT). 2022년size-adjust가 추가되며 fallback 폰트의 metric까지 맞출 수 있게 됐고, CLS는 이론상 0이 됐다. CSS 타이포의 역사는 “보이게 할까, 흔들리지 않게 할까” 의 25년 진자 운동이다.
한 단락 요약
웹 타이포는 폰트 자원(
01) · 로딩(02) · 메트릭(03) · 가변성(04) · 텍스트 흐름(05) · 유체 스케일(06) · OpenType 기능(07)의 7층이다. 이 챕터를 끝내면 “왜 제목이 한 줄에서 두 줄로 점프했나”, “왜 한글 폰트만 늦게 뜨나”, “왜 표의 숫자가 가지런하지 않나” 가 모두 같은 스택의 다른 층 문제임을 보게 된다. 다음 챕터(05-color-visual)는 이 글자 위에 색과 시각 효과가 어떻게 얹히는지를 다룬다.