반응형 디자인을 구현할 때 "화면이 커지면 요소도 커져야 한다"는 명제는 참입니다. 하지만 "무한히 커지거나 무한히 작아져야 한다"는 것은 거짓입니다. 여기서 VW와 clamp()의 근본적인 차이가 발생합니다.
1. VW: 화면에 정비례하는 단위
VW 단위는 뷰포트 너비에 정비례합니다(1vw = 뷰포트 너비의 1%). font-size: 5vw라고 설정하면 화면이 2000px일 때는 100px, 360px일 때는 18px이 됩니다.
2. clamp(): 한계가 있는 자유
clamp() 함수는 세 가지 값을 받습니다: 최솟값, 권장값, 최댓값. 브라우저는 권장값을 계산한 뒤, 그 값이 최솟값보다 작으면 최솟값을, 최댓값보다 크면 최댓값을 씁니다.
/* 문법: clamp(최솟값, 권장값, 최댓값) */
h1 { font-size: clamp(18px, 5vw, 32px); }
위 코드는 다음과 같이 작동합니다.
- 화면이 아무리 좁아져도 폰트는 18px보다 작아지지 않습니다.
- 화면이 아무리 넓어져도 폰트는 32px보다 커지지 않습니다.
- 그 사이(360~640px)에서는 화면 너비의 5%로 유연하게 변합니다.
문법을 이해하기에는 좋은 예제지만, 실제로 크기가 변하는 구간이 360~640px뿐이라 태블릿부터는 이미 최댓값에 고정됩니다. 또 px와 vw만 써서 사용자의 글꼴 크기 설정을 따르지 않습니다. 실무에서는 원하는 화면 구간에 맞춰 권장값을 계산하고 rem을 섞어 씁니다.
3. 권장값 계산법
"화면 A에서 크기 a, 화면 B에서 크기 b"가 되게 하려면 권장값을 "절편(rem) + 기울기(vw)"로 만듭니다.
기울기 = (b - a) / (B - A)
절편 = a - 기울기 * A
권장값 = 절편(px / 16 = rem) + 기울기 * 100(vw)
/* 예: 360px에서 18px → 1280px에서 32px */
기울기 = (32 - 18) / (1280 - 360) = 0.015217 → 1.5217vw
절편 = 18 - 0.015217 * 360 = 12.52px → 0.7826rem
h1 { font-size: clamp(1.125rem, 0.7826rem + 1.5217vw, 2rem); }
이 값은 360px에서 18px, 768px에서 약 24.2px, 1280px 이상에서 32px이 됩니다. 직접 계산하지 않아도 이 사이트의 Clamp 생성기에 최소·최대 화면과 크기를 넣으면 rem 또는 px 단위의 clamp() 값이 바로 나오고(rem 권장), 슬라이더로 화면 너비별 실제 크기를 미리 볼 수 있습니다. 제목·본문 크기를 한 번에 만드는 타입 스케일 기능도 있습니다.
4. rem을 섞어야 하는 이유
clamp()를 쓴다고 접근성이 저절로 좋아지지는 않습니다. 500px 너비의 브라우저 창에서 세 가지 방식을 비교하면 다음과 같습니다(화면에 보이는 크기 기준).
| 지정 방식 | 기본 | 200% 확대 | 글꼴 설정 32px |
|---|---|---|---|
5vw |
25px | 25px (1배) | 25px (1배) |
clamp(18px, 5vw, 32px) |
25px | 36px (1.44배) | 25px (1배) |
clamp(1.125rem, 0.7826rem + 1.5217vw, 2rem) |
약 20.1px | 36px (약 1.79배) | 36px (약 1.79배) |
브라우저를 200% 확대하면 창의 CSS 너비가 절반(250px)으로 줄어 vw 값도 절반이 됩니다. 그래서 VW만 쓴 글자는 확대해도 그대로이고, px로 만든 clamp는 확대에는 일부 반응하지만 글꼴 설정은 무시합니다. 최솟값·최댓값을 rem으로 두고 권장값에 rem을 섞으면 두 경우 모두 글자가 커집니다. 자세한 기준(WCAG 1.4.4)은 VW 단위와 웹 접근성을 참고하세요.
5. 주요 차이점 비교
| 특징 | VW 단위 | clamp() 함수 |
|---|---|---|
| 범위 제한 | 없음 (무한 비례) | 있음 (최소/최대 설정) |
| 미디어 쿼리 의존도 | 높음 (구간별 보정 필요) | 낮음 (함수 하나로 해결) |
| 코드 복잡도 | 단순함 | 다소 복잡하지만 명확함 |
| 글자 가독성/접근성 | 취약함 (확대·글꼴 설정 무시) | 최소·최대값에 rem을 쓰고 권장값에 rem + vw를 섞으면 우수 |
| 브라우저 지원 | 모든 브라우저 | 2020년부터 모든 주요 브라우저 |
6. min()·max()와 cqi 단위
상한이나 하한 중 하나만 필요하면 min()·max()로 충분합니다. 예를 들어 width: min(90vw, 1200px)는 "화면의 90%, 단 1200px까지"라는 뜻입니다.
화면이 아니라 부모 요소 너비에 맞춰 크기를 바꾸고 싶다면 컨테이너 쿼리 단위 cqi를 쓸 수 있습니다(1cqi = 컨테이너 너비의 1%). 2023년부터 주요 브라우저에서 지원되며, 카드처럼 놓이는 위치에 따라 너비가 달라지는 컴포넌트에 유용합니다.
/* 카드 너비 200px에서 16px → 600px 이상에서 24px */
.card { container-type: inline-size; }
.card h3 { font-size: clamp(1rem, 0.75rem + 2cqi, 1.5rem); }
7. 실무에서는 어떻게 쓰나요?
최근 실무에서는 화면 너비에 따라 글자 크기가 자연스럽게 변하는 유동 타이포그래피(Fluid Typography)를 구현할 때 clamp()를 가장 많이 씁니다. 화면 구간을 정하고, rem을 섞은 권장값을 계산해 제목·본문 크기를 CSS 변수로 관리하는 방식이 일반적입니다.
결론
VW는 엔진이고, clamp()는 그 엔진의 속도를 조절하는 리미터(Limiter)와 같습니다. 원하는 화면 구간에 맞춰 권장값을 계산하고 rem을 섞어 두면, 화면 크기와 사용자 설정에 모두 반응하는 글자 크기를 만들 수 있습니다. 시안의 px 값을 옮길 때는 PX↔VW 변환기나 PX to REM 변환기를 활용하세요.