2026.04.12기술
디자인 시스템에서 fluid typography 도입하기
이 글은 clamp() 기반 폰트 스케일을 토큰화하여 모바일/데스크톱 분기를 줄이고 일관성을 유지한 경험을 정리한 것이다.
왜 fluid typography 인가
전통적인 반응형 타이포는 breakpoint마다 font-size를 재정의했다. 단점이 명확하다.
- 분기 사이에서 글자 크기가 점프
- 새 breakpoint가 생기면 모든 토큰을 재배치
- CSS LOC가 빠르게 늘어남
"Fluid typography는 단순히 글자 크기가 부드럽게 변하는 것 이상이다. 디자이너와 엔지니어가 공유 가능한 단일 척도다."
clamp 토큰 설계
아래 슬라이더로 viewport 폭을 조정해 보면 clamp() 가 어떤 곡선을 그리는지 직관적으로 잡힌다.
Fluid Typography
clamp(1rem, 0.8vw + 0.7rem, 1.6rem)
viewport800px
= 17.6pxAa 한글 abc 123
다음과 같은 스케일을 도입했다.
const fontSize = {
100: "clamp(0.7rem, 0.24vw + 0.6rem, 0.8rem)",
200: "clamp(0.8rem, 0.64vw + 0.68rem, 1.2rem)",
300: "clamp(1rem, 0.8vw + 0.8rem, 1.4rem)",
400: "clamp(1.375rem, 1vw + 1.125rem, 1.625rem)",
500: "clamp(1.2rem, 1.2vw + 1rem, 2rem)",
600: "clamp(1.6rem, 2vw + 1.2rem, 2.8rem)",
} as const;스케일 단계 의미
| step | range | role |
|---|---|---|
| 100 | 11~13px | caption |
| 200 | 13~19px | body |
| 300 | 16~22px | lead |
| 400 | 22~26px | subtitle |
| 500 | 19~32px | heading |
| 600 | 26~45px | display |
의사 결정 흐름
flowchart TD
A[breakpoint별 font-size 재정의] --> B{유지보수 부담}
B -- 크다 --> C[fluid clamp 도입]
B -- 작다 --> A
C --> D[step 기반 토큰화]
D --> E[component에서 role 참조]
사용 예
import { primitives } from "notepad-ds/tokens/primitives";
const heading = style({
fontSize: primitives.font.role.heading,
});마무리
fluid는 만능이 아니다. 매우 작은 화면(320px 이하)이나 매우 큰 화면(2560px 이상)에선 clamp의 min/max가 직접 한계를 만들어 추가 조정이 필요할 수 있다. 하지만 일반적인 viewport 범위에서는 breakpoint를 거의 제거할 수 있어 코드 자체가 단순해진다.