한 줄 요약 — 타이포그래피는 결국 무슨 글꼴로, 얼마나 여유 있게 글자를 앉히느냐입니다. 글꼴은 font-family에 원하는 서체부터 기본 서체까지 여러 개를 순서대로 적어 두고(앞이 없으면 뒤로 넘어감, 맨 끝엔 항상 sans-serif 같은 generic family), 줄 간격 line-height는 글자 크기가 바뀌어도 함께 따라오도록 **단위 없는 숫자(본문은 보통 1.5~1.7)**로 줍니다. 한글 웹폰트는 글자 수가 많아 용량이 크니, 필요한 굵기만 부르고 font-display: swap으로 글꼴이 늦게 와도 글이 먼저 보이게 둡니다.

학습 목표

  • font-family에 글꼴을 여러 개 줄 세워 적는 이유(폰트 스택과 fallback)를 설명할 수 있다.
  • line-height에 단위 없는 숫자를 쓰는 이유를 알고, 본문에 무난한 권장값을 고를 수 있다.
  • Google Fonts의 <link>@font-face로 웹폰트를 불러와 적용할 수 있다.
  • 한글 웹폰트가 왜 무겁고, font-display로 로딩 중 화면을 어떻게 다루는지 안다.

오늘의 비유 — 같은 글도 신문체·교과서체·손글씨체에서 인상이 다르다

같은 문장이라도 어떤 글씨체로 적혀 있느냐에 따라 느낌이 완전히 달라집니다. "이번 주 모임 안내"라는 한 줄을 신문 1면처럼 또박또박한 명조체로 인쇄하면 진지하고 공식적으로 읽히고, 교과서처럼 둥글고 큼직한 글씨로 적으면 차분하고 친절하게 다가오며, 손으로 쓴 편지 글씨로 적으면 사적이고 따뜻하게 느껴집니다. 글자가 전하는 내용은 똑같은데, 서체가 인상의 절반을 정합니다.

타이포그래피는 이 "서체가 만드는 인상"을 화면에서 다루는 일입니다. 그런데 인상은 글꼴 모양 하나로만 정해지지 않습니다. 줄과 줄 사이를 얼마나 띄우느냐(줄 간격)에 따라, 같은 글도 빽빽해 답답하거나 여유로워 읽기 편해집니다. 종이 인쇄소라면 "이 서체로, 이만한 크기로, 줄은 이만큼 띄워 찍어 주세요"라고 주문서를 쓰겠죠. CSS에서 그 주문서가 바로 font-family·font-size·line-height입니다.

핵심 개념

글꼴을 고르는 font-family — 하나가 아니라 줄 세워 적는다

font-family는 값을 하나만 적는 속성이 아닙니다. 원하는 글꼴부터 기본 글꼴까지 여러 개를 쉼표로 줄 세워 적습니다.

body {
  font-family: "Pretendard", "Apple SD Gothic Neo", sans-serif;
}

브라우저는 앞에서부터 시도합니다. Pretendard가 깔려 있거나 웹폰트로 받아졌으면 그걸 쓰고, 없으면 다음인 Apple SD Gothic Neo로, 그것도 없으면 마지막 sans-serif로 넘어갑니다. 이렇게 줄 세운 목록을 **폰트 스택(font stack)**이라 부릅니다.

맨 끝의 sans-serif는 특정 글꼴 이름이 아니라 generic family입니다. "삐침 없는 고딕 계열 아무거나"라는 뜻이라, 어떤 운영체제에서도 글꼴 하나는 보장됩니다. 서체는 크게 획 끝에 삐침이 있는 **명조(serif)**와 삐침이 없는 **고딕(sans-serif)**으로 나뉘는데, 화면 본문에는 보통 고딕 계열이 무난합니다.

읽는 리듬을 정하는 line-height — 단위 없는 숫자로

line-height는 한 줄이 차지하는 세로 높이, 즉 줄 간격입니다. 값은 단위 없는 숫자로 주는 것이 기본입니다.

body {
  font-size: 1rem;
  line-height: 1.6; /* 글자 크기의 1.6배가 한 줄 높이 */
}

1.6은 "자기 요소의 글자 크기 × 1.6"이라는 비율입니다. 본문이 16px이면 줄 높이는 25.6px, 제목이 32px이면 51.2px — 각 요소가 자기 글자 크기에 맞춰 따로 계산합니다. 그래서 글자 크기를 바꿔도 줄 간격이 자연스럽게 따라옵니다. 만약 24px이나 1.6em처럼 고정 길이로 주면 그 계산된 값이 그대로 자식에게 물려져, 큰 글자에 좁은 줄 간격이 박혀 줄이 겹칠 수 있습니다(흔한 실수에서 자세히 봅니다).

권장값은 글의 성격마다 다릅니다. 읽는 양이 많은 본문은 1.5~1.7이 무난하고, 한 줄짜리 제목은 1.1~1.3처럼 좁혀야 단단해 보입니다.

웹폰트를 불러오는 두 가지 길 — Google Fonts와 @font-face

원하는 글꼴이 사용자 기기에 깔려 있다는 보장은 없습니다. 그래서 글꼴 파일을 직접 받아 오는 것이 웹폰트입니다. 부르는 길은 크게 둘입니다.

첫째, Google Fonts 같은 서비스가 주는 <link><head>에 붙입니다. 가장 간단합니다.

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
  href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700&display=swap"
  rel="stylesheet">

둘째, 글꼴 파일을 내 서버에 두고 @font-face로 직접 등록합니다. 한글에서 많이 쓰는 Pretendard를 자체 호스팅할 때의 모습입니다.

@font-face {
  font-family: "Pretendard";
  src: url("/fonts/Pretendard-Regular.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

둘 다 끝나면 평소처럼 font-family에 이름을 적어 쓰면 됩니다. 여기서 font-display: swap이 중요합니다. 웹폰트는 네트워크로 받아 오느라 시간이 걸리는데, 그동안 글자를 어떻게 보여줄지 정하는 값입니다. 기본값은 글꼴이 올 때까지 글자를 잠깐 숨기는 **FOIT(Flash of Invisible Text, 글자가 잠깐 안 보이는 현상)**가 나기 쉽고, swap은 일단 기본 글꼴로 먼저 보여 준 뒤 웹폰트가 오면 바꾸는 **FOUT(Flash of Unstyled Text, 기본 글꼴로 보였다가 교체되는 현상)**가 됩니다. 글이 먼저 보이는 swap이 대개 안전합니다.

함께 따라하기 — 한글 웹폰트를 적용하고 로딩 중 화면 보기

day-18 폴더에 index.htmlstyle.css를 만듭니다. Google Fonts에서 한글 글꼴 하나(여기선 고운돋움, Gowun Dodum)를 display=swap으로 불러와 본문에 입혀 봅니다.

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8">
    <title>폰트와 타이포그래피</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link
      href="https://fonts.googleapis.com/css2?family=Gowun+Dodum&display=swap"
      rel="stylesheet">
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <article class="post">
      <h1>오늘 읽은 문장</h1>
      <p>같은 글도 글꼴과 줄 간격에 따라 인상이 달라집니다. 직접 바꿔 보면 그 차이가 한눈에 들어옵니다.</p>
    </article>
  </body>
</html>
body {
  font-family: "Gowun Dodum", "Apple SD Gothic Neo", sans-serif;
  line-height: 1.7;
  margin: 2rem;
}

.post h1 {
  font-size: 1.75rem;
  line-height: 1.2;   /* 제목은 본문보다 좁게 */
}

.post p {
  font-size: 1.0625rem;
  max-width: 36rem;   /* 한 줄이 너무 길지 않게 */
}

저장하고 열어 보면 한글이 둥글둥글한 고운돋움으로 바뀌어 보입니다. 제목은 줄 간격이 좁아 단단하게, 본문은 1.7로 여유 있게 읽힙니다. 로딩 중 화면을 보려면 개발자 도구 Network 탭에서 속도를 "Slow"로 낮추고 새로고침해 보세요. 웹폰트가 도착하기 전 잠깐 기본 글꼴로 글이 보이다가, 글꼴이 오면 슥 바뀝니다 — 이게 swap이 만드는 FOUT입니다. &display=swap을 빼고 새로고침하면 이번엔 글자가 잠깐 안 보였다 나타나는 FOIT가 보입니다.

흔한 실수 3가지

1. line-height에 px을 박아 글자 크기가 바뀌어도 줄간격이 안 변한다

body {
  font-size: 16px;
  line-height: 24px; /* 고정 길이 */
}
h1 { font-size: 40px; }

(이 코드는 의도와 다르게 동작합니다.) line-height24px로 주면 그 값이 그대로 자식에게 물려집니다. 그래서 글자가 40px인 제목도 줄 높이는 24px에 머물러, 윗줄과 아랫줄이 서로 겹쳐 버립니다. 1.6em으로 줘도 결과는 비슷합니다 — em은 선언한 그 자리에서 길이로 계산돼 굳어지기 때문입니다.

body { line-height: 1.6; } /* 각 요소가 자기 글자 크기 × 1.6 */
h1   { font-size: 40px;  } /* 줄 높이도 40 × 1.6 = 64px로 따라옴 */

단위 없는 숫자는 길이가 아니라 비율을 물려줍니다. 그래서 큰 글자는 큰 줄 간격을, 작은 글자는 작은 줄 간격을 각자 계산해 겹칠 일이 없습니다.

2. 웹폰트 굵기를 전부 불러와 첫 화면이 늦어진다

<link
  href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;300;400;500;700;900&display=swap"
  rel="stylesheet">

(첫 화면이 느려집니다.) 한글은 화면에 그려야 할 글자(글리프)가 2,000자가 넘어, 한 굵기 파일만으로도 영문 폰트보다 훨씬 무겁습니다. 위처럼 굵기 6종을 한꺼번에 부르면 그만큼 용량이 배로 불어나 첫 화면이 그릴 것을 기다리게 됩니다.

<link
  href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700&display=swap"
  rel="stylesheet">

실제로 쓰는 굵기 — 보통 본문 400, 강조 700 — 두세 개만 부르면 충분합니다. 가능하면 woff2 포맷과, 필요한 글자만 추려 담은 subset(서브셋) 파일을 쓰면 더 가벼워집니다.

3. font-family에 fallback을 안 두어 폰트 실패 시 깨진다

body { font-family: "Pretendard"; } /* 글꼴 하나뿐 */

(웹폰트가 안 받아지면 글꼴이 의도와 다르게 떨어집니다.) Pretendard 하나만 적어 두면, 글꼴 파일이 늦거나 실패했을 때 브라우저는 자기 기본 글꼴로 떨어집니다. 그 기본값은 운영체제마다 달라서, 윈도우와 맥에서 글자 인상이 제각각이 됩니다.

body {
  font-family: "Pretendard", "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
}

원하는 웹폰트를 맨 앞에, 그다음 OS별 기본 한글 고딕(맥의 Apple SD Gothic Neo, 윈도우의 맑은 고딕)을, 맨 끝에 generic family인 sans-serif를 둡니다. 앞에서부터 없으면 차례로 넘어가고, 마지막 sans-serif가 어떤 환경에서도 글꼴 하나는 보장합니다.

오늘 배운 것 체크리스트

  • font-family는 원하는 글꼴부터 generic family까지 줄 세워 적는다는 걸 안다.
  • line-height에 단위 없는 숫자를 쓰는 이유와 본문 권장값(1.5~1.7)을 안다.
  • Google Fonts <link>@font-face 두 방식으로 웹폰트를 불러올 수 있다.
  • 한글 웹폰트가 무거운 이유와, 굵기를 줄여 부르는 이유를 설명할 수 있다.
  • font-display: swap이 FOIT 대신 FOUT를 만든다는 차이를 안다.

자주 묻는 질문

Q. Pretendard를 적용하려면 꼭 폰트 파일을 다운로드해야 하나요?

A. 아닙니다. 파일을 직접 받아 서버에 두고 @font-face로 등록하는 방법이 가장 확실하지만, jsDelivr 같은 CDN이 제공하는 CSS를 <link>로 붙이면 다운로드 없이도 바로 쓸 수 있습니다. 처음엔 CDN으로 시작하고, 로딩 속도를 더 챙겨야 할 때 자체 호스팅과 서브셋으로 넘어가면 됩니다.

Q. line-height는 px로 주면 안 되나요? 숫자랑 뭐가 다른가요?

A. px(또는 em)으로 주면 그 줄 높이가 자식 요소에 그대로 굳어 물려져, 글자 크기가 다른 곳에서 줄이 겹치거나 너무 벌어집니다. 단위 없는 숫자는 "글자 크기의 몇 배"라는 비율을 물려주기 때문에 각 요소가 알아서 계산합니다. 본문 1.51.7, 제목 1.11.3을 기준으로 잡으면 무난합니다.

Q. 한글 웹폰트는 용량이 너무 큰데 꼭 써야 하나요?

A. 꼭은 아닙니다. 맥의 Apple SD Gothic Neo, 윈도우의 맑은 고딕 같은 시스템 폰트만으로 스택을 짜도 무난한 화면이 나옵니다. 브랜드 글꼴이 꼭 필요할 때만 웹폰트를 쓰되, 굵기를 줄이고 woff2·서브셋·font-display: swap으로 무게를 덜어 주세요.

다음 시간 예고

내일은 배경 — color, image, gradient를 자유자재로를 다룹니다. 단색 배경부터 이미지 배경, 그리고 두 색을 섞는 그라데이션까지 — background-size: covercontain이 어떻게 다른지, 히어로 섹션 하나를 세 가지 배경으로 만들어 비교합니다.

더 알아보기