font-display swap 차이, 표로 읽기

font-display 값 5가지는 텍스트를 얼마나 오래 숨기는지(block period)와, 대체 글꼴을 보여준 뒤 맞춤 글꼴로 언제까지 교체할 수 있는지(swap period)가 서로 다르게 정의돼 있습니다.
swap 값이 특히 헷갈리는 이유는 표에서 swap period가 "무한(∞)"으로 표시되기 때문인데, 이는 텍스트가 안 보인다는 뜻이 아니라 정반대로 처음부터 대체 글꼴이 곧바로 보이고 있다는 뜻입니다.
이 글은 다섯 값의 block period·swap period가 각각 무엇을 의미하는지, FOUT·FOIT가 타임라인의 어느 구간에서 발생하는지를 CSS 명세와 도구의 표시 기준으로 정리합니다.
어떤 값을 선택해야 하는지에 대한 판단은 사이트 상황마다 달라지므로 이 글에서 다루지 않습니다.
요약 ① block period는 텍스트가 안 보이는 구간(FOIT)이고, swap period는 대체 글꼴이 보이다가 교체될 수 있는 구간(FOUT)입니다. ② swap 값의 swap period가 "무한(∞)"인 것은 글꼴이 영원히 안 보인다는 뜻이 아니라, 로드가 아무리 늦어져도 그 순간 바로 교체된다는 뜻입니다. ③ 폰트 이름·URL 입력은 하단 생성 코드에만 반영되고, block/swap 기간 수치와 타임라인 비율은 선택한 font-display 값에 대한 고정 참고 데이터입니다.
font-display 값이 왜 헷갈리는가
프런트엔드 작업 중 Lighthouse의 "Ensure text remains visible during webfont load" 경고를 보고 font-display: swap을 CSS에 추가하는 경우가 흔합니다.
이후 페이지를 새로고침해보면 텍스트가 대체 글꼴로 잠깐 보이다가 맞춤 글꼴로 바뀌는 현상을 목격하게 됩니다.
이때 MDN이나 CSS 명세의 표를 열어보면 "Block Period"·"Swap Period"라는 용어와 3s, 100ms, ∞(무한) 같은 숫자가 나열돼 있어, 어떤 값이 텍스트를 더 오래 숨기는지 설명 없이는 헷갈리기 쉽습니다.
특히 "무한"이라는 단어는 직관과 반대로 읽히기 쉽습니다. block period가 짧을수록 텍스트가 빨리 보이는 좋은 쪽에 가까운데, "swap period 무한"이라는 문구만 보면 "무한히 안 보인다"로 거꾸로 오해하기 쉽습니다.
도구 없이 명세로 직접 확인하는 방법
font-display의 동작은 W3C CSS Fonts Module Level 4 명세가 정의한 폰트 표시 타임라인을 따릅니다. 이 타임라인은 폰트를 요청한 시점부터 세 구간으로 나뉩니다.
- 폰트 block 구간(font block period): 이 구간 동안 폰트가 아직 로드되지 않았다면 텍스트는 보이지 않는 상태로 남습니다. 이 구간 안에 로드가 끝나면 그 즉시 맞춤 글꼴로 렌더링됩니다.
- 폰트 swap 구간(font swap period): block 구간이 끝나면 시작되는 구간입니다. 폰트가 아직 없어도 이 구간부터는 대체 글꼴로 텍스트가 보이며, 이 구간 안에 로드가 끝나면 맞춤 글꼴로 교체됩니다.
- 폰트 실패 구간(font failure period): swap 구간이 끝나도록 로드가 안 되면 로드 실패로 처리되고, 이후로는 대체 글꼴이 이번 페이지 보기에서 계속 사용됩니다.
명세는 각 값이 block·swap 두 구간을 얼마나 길게 잡을지 권장값으로 정의합니다.
| font-display 값 | block 구간(명세 권장) | swap 구간(명세 권장) |
|---|---|---|
| auto | 브라우저 자체 정책(대체로 block과 유사) | 브라우저 자체 정책 |
| block | 짧음(약 3초) | 무한 |
| swap | 극히 짧음(약 100ms 이하, 사실상 즉시) | 무한 |
| fallback | 극히 짧음(약 100ms 이하) | 짧음(약 3초) |
| optional | 극히 짧음(약 100ms 이하) | 없음(0초) |
이 표만으로도 다섯 값의 차이를 손으로 따져볼 수 있습니다.
block과 swap은 둘 다 swap 구간이 무한이라 언젠가 로드만 되면 반드시 교체되지만, block은 그 전에 최대 3초간 텍스트를 숨기고 swap은 거의 숨기지 않고 바로 대체 글꼴을 보여준다는 차이가 있습니다.
참고로 아래 도구는 swap 값의 block 구간을 "0s"로, block 값의 block 구간을 "3s"로 표시합니다. 명세가 권장하는 "100ms 이하"를 사실상 0에 가깝다고 보아 반올림해 보여주는 것입니다.
저희 도구로 확인하기.
폰트 이름과 URL만 입력하면 font-display 값별 block/swap 기간·타임라인과 @font-face 코드를 무료로 바로 확인합니다.

타임라인을 읽을 때 흔히 헷갈리는 지점
표와 타임라인을 읽을 때는 특히 아래 네 가지를 헷갈리기 쉽습니다.
- "swap 구간 무한"은 "안 보임"이 아닙니다: swap 값은 block 구간이 사실상 없어서(0s) 텍스트가 처음부터 대체 글꼴로 바로 보입니다. swap 구간이 무한이라는 것은 맞춤 글꼴이 아무리 늦게 로드되더라도 로드되는 순간 교체할 기회가 계속 열려 있다는 뜻이지, 텍스트가 안 보이는 시간이 무한이라는 뜻이 아닙니다.
- FOIT와 FOUT는 발생 구간이 다릅니다: FOIT(Flash of Invisible Text)는 block 구간에서 텍스트 자체가 렌더링되지 않아 발생하는 현상이고, FOUT(Flash of Unstyled Text)는 swap 구간에서 대체 글꼴로 보이던 텍스트가 맞춤 글꼴로 바뀌면서 발생하는 현상입니다.
- optional의 "0s"는 "즉시 교체"가 아닙니다: "0초 만에 즉시 교체된다"가 아니라 "이번 페이지를 보는 동안에는 교체가 아예 일어나지 않는다"는 뜻입니다. block 구간(약 100ms)이 지나면 대체 글꼴로 고정되고, 그 이후 다운로드가 끝난 맞춤 글꼴은 다음 방문 때 적용됩니다.
- 도구 입력값과 참고 수치는 서로 무관합니다: 폰트 이름이나 URL을 바꾸면 화면 하단의 @font-face 코드 텍스트만 바뀝니다. 위쪽의 Block Period·Swap Period 수치와 타임라인 막대 비율은 선택한 font-display 값에 대한 고정 참고 데이터라 입력값과 무관하게 동일하게 표시됩니다.
| font-display 값 | 이 값에서 텍스트가 보이는 방식 | 헷갈리기 쉬운 포인트 |
|---|---|---|
| swap | 처음부터 대체 글꼴로 즉시 표시(FOUT 가능) | swap 구간 "무한"을 "안 보임"으로 착각하기 쉬움 |
| block | 최대 3초간 안 보이다가(FOIT) 대체 글꼴로 전환 | block 구간이 끝나야 대체 글꼴이라도 보임 |
| fallback | 아주 잠깐 안 보이다가 대체 글꼴, 3초 지나면 이번 로드에선 고정 | "고정"을 "로드 실패"로 착각하기 쉬움 |
| optional | 아주 잠깐 확인 후 대체 글꼴로 고정, 교체 없음 | swap 구간 "0s"를 "즉시 교체"로 착각하기 쉬움 |
정리
- block period는 텍스트가 안 보이는 구간(FOIT), swap period는 대체 글꼴이 보이다가 교체될 수 있는 구간(FOUT)입니다.
- swap 값은 block 구간이 사실상 0이라 텍스트가 즉시 대체 글꼴로 보이고, swap 구간이 무한이라 로드되는 순간 언제든 교체됩니다.
- block 값은 최대 3초간 텍스트를 숨긴 뒤에야 대체 글꼴이 나타나고, 이후는 swap처럼 무한히 교체될 수 있습니다.
- fallback과 optional은 swap 구간에 상한이 있어(각각 약 3초, 0초), 그 시간을 넘기면 이번 페이지 보기에서는 더 이상 교체되지 않습니다.
- 폰트 이름·URL 입력은 생성 코드 텍스트에만 반영되고, block/swap 기간과 타임라인 비율은 선택한 값에 대한 고정 참고 데이터입니다.
폰트 이름과 URL만 입력하면 font-display 값별 block/swap 기간·타임라인과 @font-face 코드를 무료로 바로 확인합니다.
자주 묻는 질문
swap 기간이 "무한(∞)"이면 글꼴이 영원히 안 보이나요?
아닙니다. swap 구간이 무한이라는 것은 텍스트가 안 보이는 시간이 무한이라는 뜻이 아니라, 맞춤 글꼴이 아무리 늦게 로드되더라도 로드되는 순간 대체 글꼴에서 맞춤 글꼴로 교체될 수 있다는 뜻입니다.
swap 값은 오히려 block 구간이 사실상 없어 텍스트가 처음부터 즉시 보입니다.
FOUT와 FOIT는 정확히 어떤 차이인가요?
FOIT(Flash of Invisible Text)는 block 구간에서 텍스트 자체가 렌더링되지 않아 안 보이는 현상입니다.
FOUT(Flash of Unstyled Text)는 swap 구간에서 대체 글꼴로 보이던 텍스트가 맞춤 글꼴로 바뀌면서 발생하는 현상입니다. block 값은 FOIT가, swap 값은 FOUT가 상대적으로 두드러집니다.
auto 값은 어떤 값과 동작이 같나요?
auto는 명세상 브라우저 자체 정책을 따르도록 정의돼 있어 값 하나로 고정되지 않습니다. 다만 Chrome, Safari, Firefox 등 대부분의 주요 브라우저는 auto를 block과 비슷하게 처리하는 것으로 알려져 있습니다.
생성된 @font-face 코드의 font-weight나 font-style도 입력한 값이 반영되나요?
아니요. 생성되는 코드에서 font-family와 src(URL)는 입력한 값이 그대로 반영되지만, font-weight는 400, font-style은 normal로 고정돼 있습니다.
다른 굵기나 스타일을 쓰는 폰트라면 복사한 코드에서 해당 값을 직접 수정해야 합니다.
