CSS clamp 반응형 폰트 크기를 직접 계산하는 방법

예제를 찾으면 clamp(16px, 4vw, 24px) 같은 코드만 나와요. "이 4vw는 어디서 나온 건지" 설명은 없고요. 직접 계산하지 않으면 구간이 어긋나는 이유, 그 메커니즘부터 짚고 갈게요.
단순 vw가 구간을 어긋나게 만드는 이유
clamp(최솟값, 선호값, 최댓값) — 반응형 동작을 만드는 건 중간의 선호값이에요. 문제는 여기에 4vw처럼 단순한 뷰포트 단위만 넣으면 계획한 구간이 밀린다는 거예요.
폰트를 16px~20px 사이에서 움직이게 하고 싶다고 해볼게요. 화면이 320px일 때 4vw는 12.8px이라 이미 최솟값 아래로 떨어져버려요. 그러면 clamp가 320px에서 400px 구간을 16px에 고정해버리고, 실제 스케일링은 400px에서야 시작돼요. 원하는 구간에서 움직이게 하려면 선호값에 기울기 × vw + 절편 형태의 식을 수학적으로 유도해서 넣어야 해요.
네 칸짜리 계산 시트
지금부터 워크시트처럼 따라오세요. 여기서 쓰는 숫자를 나중에 본인 프로젝트 값으로 바꾸면 그대로 씁니다.
입력값 확정 — 여기만 채우면 돼요
min_px = 16 ← 모바일에서 원하는 폰트 크기
max_px = 20 ← 데스크톱에서 원하는 폰트 크기
min_vw = 320 ← 스케일링 시작 뷰포트
max_vw = 1200 ← 스케일링 끝 뷰포트
1단계 — 기울기(slope) 계산
두 점을 잇는 직선의 기울기예요.
slope = (max_px − min_px) ÷ (max_vw − min_vw)
= (20 − 16) ÷ (1200 − 320)
= 4 ÷ 880
≈ 0.004545
CSS 단위로 바꾸면 0.004545 × 100 ≈ 0.4545vw가 됩니다.
2단계 — 절편(intercept) 계산
직선이 y축과 만나는 값이에요. "뷰포트 0px일 때의 가상 폰트 크기"라고 이해하면 됩니다.
intercept = min_px − slope × min_vw
= 16 − 0.004545 × 320
= 16 − 1.45
≈ 14.55px
3단계 — 조합 및 검증
font-size: clamp(16px, 0.4545vw + 14.55px, 20px);
제대로 계산했는지 양 끝에서 확인해요.
뷰포트 320px → 0.004545 × 320 + 14.55 ≈ 16px ✓
뷰포트 1200px → 0.004545 × 1200 + 14.55 ≈ 20px ✓
양 끝에서 정확히 원하는 값이 나오면 구간이 잘 맞게 잡힌 거예요.
타입 시스템 전체를 한 번에 계산하기
본문 하나만 잡고 끝내면 실은 절반만 한 거예요. H2 소제목이나 캡션에 각자 임의의 vw 계수를 넣으면 특정 화면 폭에서 제목이 본문보다 작아지는 위계 역전이 생길 수 있어요.
해결책은 단순해요. min_vw와 max_vw를 프로젝트 전체에서 고정하고, 레이어마다 min_px·max_px만 바꿔서 같은 공식을 반복 적용하는 거예요.
위에서 쓴 320→1200 범위로 H2(22px→28px)와 캡션(12px→14px)을 이어서 계산해볼게요.
[H2]
slope = (28 - 22) / (1200 - 320) = 6 / 880 ≈ 0.00682
intercept = 22 - 0.00682 × 320 ≈ 19.82px
→ font-size: clamp(22px, 0.6818vw + 19.82px, 28px);
[캡션]
slope = (14 - 12) / 880 ≈ 0.00227
intercept = 12 - 0.00227 × 320 ≈ 11.27px
→ font-size: clamp(12px, 0.2273vw + 11.27px, 14px);
세 줄 모두 min_vw=320, max_vw=1200으로 통일되니 어떤 화면 폭에서도 본문·제목·캡션이 동시에 같은 비율로 스케일링돼요.
사용할 서체를 고를 때는 웹 사용 범위와 라이선스를 먼저 확인하는 게 좋아요. 폰트비에서 웹 사용 가능 여부와 @font-face 코드를 한 번에 확인할 수 있으니 참고해보세요.
계산은 맞는데 작동하지 않을 때
아무리 정확하게 계산해도 브라우저에서 고정값으로만 표시되는 경우가 있어요. 순서대로 체크해보세요.
절편에 px 단위를 붙였는지 — 이게 가장 흔한 원인이에요. 0.4545vw + 14.55처럼 단위를 빠뜨리면 브라우저가 선호값 전체를 무효로 처리하고 min 또는 max 고정값으로 떨어져버려요. 반드시 0.4545vw + 14.55px로 써야 해요.
rem으로 바꾸고 싶다면 — 절편 값을 16으로 나누면 돼요. 14.55px → 14.55 ÷ 16 ≈ 0.91rem. 접근성 측면에서 rem이 유리하긴 한데, px로 먼저 계산하고 변환하는 편이 오류가 덜 납니다.
검증은 브라우저 개발자 도구에서 — 화면 너비를 320px로 맞추고 font-size 계산값이 16px인지, 1200px에서 20px인지 직접 확인하는 게 가장 빠르거든요 ✦
이 글이 도움이 됐나요?
여러분의 반응이 다음 글의 방향이 돼요

