it-box

clamp로 글자 크기를 유동적으로 조절하는 법

CSS clamp()로 미디어 쿼리 없이 화면 너비에 따라 글자 크기가 변하게 만드는 방법, 기준값을 두 지점에서 계산하는 과정, rem을 써야 하는 이유를 정리합니다.

화면 너비별로 제목 크기를 나눠 쓰는 코드는 금방 길어집니다. 모바일, 태블릿, 데스크톱마다 @media 블록을 만들고, 브레이크포인트를 옮기면 그 블록을 전부 다시 맞춰야 합니다. 글자 크기는 화면 너비에 따라 부드럽게 변하는 편이 자연스러운데, 단계별 스위치로 구현하면 특정 너비에서 글자가 갑자기 커지거나 줄어드는 구간이 생깁니다.

clamp()는 이 문제를 한 줄로 풉니다. 값이 최소와 최대 사이에서 화면 너비에 비례해 변하도록 만들고, 양 끝은 고정할 수 있습니다. 이 글은 문법, 기준값을 계산하는 과정, 단위를 rem으로 잡아야 하는 이유, 실제로 자주 틀리는 부분을 다룹니다. 계산 결과를 직접 확인하고 싶다면 clamp 계산기에 같은 숫자를 넣어 보세요.

clamp 문법

font-size: clamp(최소값, 기준값, 최대값);

세 인자는 순서가 정해져 있습니다. 브라우저는 기준값을 계산한 뒤 최소값보다 작으면 최소값을, 최대값보다 크면 최대값을 씁니다. 기준값에는 보통 calc()처럼 고정 단위와 vw 단위를 더한 식을 넣습니다.

h1 {
  font-size: clamp(1rem, 0.8rem + 1vw, 1.5rem);
}

이 선언은 뷰포트 너비가 바뀔 때 다음 세 가지 상태를 가집니다. 너비가 좁을 때는 기준값이 1rem보다 작아지므로 1rem으로 고정됩니다. 너비가 넓을 때는 기준값이 1.5rem을 넘어서므로 1.5rem으로 고정됩니다. 그 사이에서는 0.8rem + 1vw가 적용되어 너비에 비례해 커집니다.

기준값을 두 지점에서 유도하기

기준값을 직접 짜는 일은 일차 함수를 찾는 일과 같습니다. 두 개의 조건을 정하면 됩니다. 뷰포트 너비가 w_min일 때 글자 크기가 f_min이고, 너비가 w_max일 때 글자 크기가 f_max가 되도록 만듭니다. 그러면 그 사이의 글자 크기는 직선으로 변합니다.

직선의 기울기는 다음과 같습니다.

기울기 s = (f_max - f_min) / (w_max - w_min)

이 값은 단위가 없는 비율입니다. px를 px로 나눈 값입니다. 기준값에서 vw를 쓰려면 뷰포트 너비의 1%가 1vw라는 점을 반영해 100을 곱해야 합니다. 즉 s * 100vw가 됩니다.

절편은 기울기 항을 빼서 얻습니다.

절편 a = f_min - s * w_min

최종 식은 a + (s * 100)vw입니다. 절편 a는 px 단위로 계산되므로, rem으로 바꿀 때는 기준 글꼴 크기인 16px로 나눕니다.

손계산 예제

최소 16px을 뷰포트 320px에서, 최대 24px을 뷰포트 1120px에서 얻고 싶다고 합시다.

s = (24 - 16) / (1120 - 320) = 8 / 800 = 0.01
기울기 vw = 0.01 * 100 = 1vw
절편 a = 16 - 0.01 * 320 = 16 - 3.2 = 12.8px = 12.8 / 16 rem = 0.8rem
양 끝 값 = 16 / 16 = 1rem, 24 / 16 = 1.5rem

결과는 clamp(1rem, 0.8rem + 1vw, 1.5rem)입니다. 검산은 두 점에 대입하면 됩니다. 뷰포트 320px에서 12.8px + 1vw는 12.8px + 3.2px = 16px입니다. 뷰포트 1120px에서는 12.8px + 11.2px = 24px입니다. 두 지점 모두 원하는 값과 맞습니다.

다른 예로 최소 16px을 뷰포트 320px에서, 최대 40px을 뷰포트 1280px에서 얻는 경우를 보겠습니다. 기울기는 24 / 960 = 0.025이므로 2.5vw입니다. 절편은 16 - 0.025 * 320 = 8px = 0.5rem입니다. 결과는 clamp(1rem, 0.5rem + 2.5vw, 2.5rem)입니다. 뷰포트 1280px에서 8px + 32px = 40px이므로 역시 맞습니다.

계산기는 이 절차를 그대로 수행합니다. 입력한 최소·최대 글꼴 크기와 두 너비에서 기울기와 절편을 구하고, rem 값으로 바꿔 한 줄의 clamp()를 만듭니다. 기준 루트 글꼴 크기는 입력란에서 바꿀 수 있습니다.

비율이 깔끔하게 떨어지지 않으면 계산기는 소수점이 긴 값을 그대로 보여 줍니다. 예를 들어 320px에서 1280px 사이를 16px에서 32px로 바꾸면 기울기는 1.6666...vw가 됩니다. 손으로 옮길 때 반올림하면 양 끝 지점의 값이 조금씩 어긋납니다. 가능하면 기울기가 깔끔한 너비 조합을 고르는 편이 검산하기 쉽습니다.

rem을 써야 하는 이유

최소값과 최대값, 그리고 절편을 rem으로 쓰는 이유는 사용자의 글꼴 설정을 존중하기 위해서입니다. 브라우저에서 기본 글꼴 크기를 올린 사용자는 rem 값이 함께 커집니다. 반면 px로 쓴 최소·최대값은 그대로 고정됩니다.

WCAG의 텍스트 크기 조절 기준은 보조 기술 없이도 글자를 200%까지 키울 수 있고, 그 과정에서 내용이나 기능이 사라지면 안 된다고 요구합니다. 고정 px 값은 이 요구를 쉽게 깨뜨립니다. 최소 글꼴 크기가 px로 고정되어 있으면, 기본 글꼴 크기를 키운 사용자도 제목의 하한은 그대로 봅니다.

계산기의 안내 문구에도 같은 내용이 있습니다. 지정한 루트 글꼴 크기에서 두 너비의 글꼴 크기를 맞추며, 실제 루트 글꼴 크기가 달라지면 rem 값의 크기도 달라진다는 뜻입니다. 여기서 중요한 점은 vw 항목은 루트 글꼴 크기와 무관하다는 것입니다. 따라서 절편과 양 끝 값이 rem이라도 기울기 부분은 사용자 설정을 따르지 않습니다. 이 때문에 기울기를 지나치게 크게 잡으면 기본 글꼴 크기를 바꾼 사용자에게 어색한 크기 변화가 나타날 수 있습니다.

일반적인 실무 기준은 다음과 같습니다. 제목이나 큰 숫자처럼 크기 차이가 눈에 띄는 요소에만 clamp()를 쓰고, 본문은 고정된 rem 값으로 두는 편이 안전합니다. 모든 글자에 유동 크기를 적용하면 줄 간격과 레이아웃이 함께 흔들리기 쉽습니다.

흔한 실수

첫째, 인자 순서를 바꾸는 실수입니다. 최소값이 첫 번째, 최대값이 마지막입니다. 최소값과 최대값을 뒤집으면 브라우저는 범위를 제대로 만들지 못합니다.

둘째, 기울기에 100을 곱하지 않는 실수입니다. s를 그대로 vw에 넣으면 0.01vw처럼 아주 작은 값이 되어 글자가 거의 변하지 않습니다. s * 100이어야 합니다.

셋째, 절편을 px와 rem 중 하나로 통일하지 않는 실수입니다. 절편은 px로 계산한 뒤 16으로 나눠 rem으로 옮기거나, 처음부터 rem 기준으로 계산해야 합니다. 두 단위를 섞으면 검산이 어려워지고, 기본 글꼴 크기가 16px이 아닌 환경에서 값이 틀어집니다.

넷째, 루트 글꼴 크기가 16px이라고 가정하는 실수입니다. 계산기는 루트를 입력받지만, 많은 사이트는 html의 글꼴 크기를 바꾸기도 합니다. 그러면 절편의 rem 값이 원래 계산과 달라집니다. 루트를 바꿨다면 계산도 같은 값으로 다시 해야 합니다.

다섯째, vw 항목만 쓰는 실수입니다. font-size: 2.5vw처럼 뷰포트 단위만 쓰면 사용자 글꼴 설정이 전혀 반영되지 않습니다. 최소와 최대를 rem으로 묶어 두는 이유가 여기에 있습니다.

여섯째, 최소 너비와 최대 너비를 같게 잡는 실수입니다. 계산기는 최대 너비가 최소 너비보다 커야 한다고 검사합니다. 같은 값을 넣으면 기울기를 나눌 수 없습니다.

일곱째, 최소 글꼴 크기가 기준보다 큰 경우입니다. 계산기는 최대 글꼴 크기가 최소 글꼴 크기보다 작지 않도록 요구합니다. 두 값을 바꿔 넣었는지 확인하세요.

점검 목록

  • clamp()의 세 인자가 최소, 기준, 최대 순서인지 확인합니다.
  • 최소와 최대 글꼴 크기가 rem으로 표시되는지 확인합니다.
  • 기준값의 기울기는 (f_max - f_min) / (w_max - w_min) * 100으로 계산했는지 확인합니다.
  • 절편에 / 16을 적용했는지, 또는 루트 글꼴 크기를 실제 값으로 넣었는지 확인합니다.
  • 두 뷰포트 지점, 즉 최소 너비와 최대 너비에서 대입한 값이 원하는 글꼴 크기와 맞는지 계산합니다.
  • 브라우저의 기본 글꼴 크기를 키운 상태에서 제목이 어색하게 커지지 않는지 확인합니다.
  • 본문에는 고정 rem 값을 쓰고, 유동 크기는 제목 같은 요소에만 적용했는지 확인합니다.
  • 계산 결과는 clamp 계산기에서 같은 입력으로 다시 확인합니다.

관련 도구