폰트 크기 위계, 숫자를 직접 뽑아내는 계산법

디자인 파일을 열었더니 H1은 36px, H2는 26px, H3는 20px. 이 숫자들, 어디서 나온 걸까요?
전 직장 동료가 한번은 솔직하게 말하더라고요. "딱 봐서 맞을 것 같아서요." 뭐, 그게 나쁜 건 아닙니다. 문제는 나중에 폰트를 바꾸거나 기준 크기를 조금 손보려 할 때 터지거든요. H1부터 캡션까지 전부 하나씩 다시 계산하고, 눈으로 대조하고, 또 수정하고. 이 삽질이 반복됩니다.
폰트 크기 위계를 수학적 배율로 잡으면 이 문제가 사라집니다. 베이스 크기 하나와 배율 하나만 결정하면, H1부터 캡션까지 모든 층위가 공식 한 줄로 도출됩니다. 이 글에서는 그 원리와 함께, 배율 4종별 실제 수치표를 직접 계산해 정리했습니다.
직관으로 잡은 숫자가 무너지는 순간
직관으로 잡은 숫자가 나쁜 건 아닙니다. 다만 두 가지 상황에서 한계가 드러나거든요.
첫 번째는 수정할 때입니다. 베이스를 16px에서 18px로 올리기로 했다면, 직관 기반 체계에서는 H1·H2·H3·Small·캡션을 전부 각각 다시 들여다봐야 합니다. 배율 기반 체계는 base 하나만 바꾸면 나머지가 따라오고요. CSS 커스텀 프로퍼티나 디자인 토큰과 함께 쓰면 사이트 전체 타이포그래피를 변수 몇 줄로 교체할 수 있습니다.
두 번째는 일관성이에요. H1이 H2보다 크고, H2가 H3보다 크다는 사실만으로는 위계가 성립하지 않습니다. 각 단계 사이의 시각적 간격이 고르게 느껴져야 독자가 정보 층위를 무의식적으로 파악할 수 있거든요. 예를 들어 H1=48px, H2=32px, H3=24px, H4=20px처럼 직관으로 잡으면 H1→H2 간격(16px)과 H2→H3 간격(8px), H3→H4 간격(4px)이 전부 다른 비율로 줄어듭니다. 시각적 리듬이 흔들리는 것도 이 때문입니다.
이 개념은 음악에서 왔습니다. 음계(scale)의 각 음 사이 간격이 일정한 비율을 유지하듯, 폰트 크기도 같은 비율 관계로 쌓으면 조화로운 리듬이 만들어집니다. 이걸 Modular Scale이라고 부릅니다.
내 숫자를 직접 뽑는 3단계 워크시트
아래 순서대로 따라가면 자기 프로젝트에 맞는 수치를 바로 뽑을 수 있습니다. 공식은 단순합니다.
크기(px) = base × ratio^n
- base: 본문(body) 폰트 크기. 웹 표준은 16px(모든 주요 브라우저 기본값)
- ratio: 단계 간 배율. 1보다 크면 위로 갈수록 커지고, 아래 캡션 계산은 음수 n을 씁니다
- n: 본문을 0으로 놓았을 때 각 층위의 단계 수. H1=+4, H2=+3, H3=+2, H4=+1, 본문=0, Small=−1, 캡션=−2가 일반적입니다
1단계 — 본문 크기 결정 웹이라면 16px를 기본으로 시작하면 된다. 긴 글 위주 콘텐츠라면 18px가 가독성에 유리하고, 정보 밀도가 높은 데이터 UI라면 14px도 선택지다. 모바일 앱은 플랫폼 기본값(iOS 17pt, Android/Material Design 3 기준 16sp)을 base로 삼는 게 안전하다.
2단계 — 배율 선택 아래 배율 수치표를 참고해 프로젝트 성격에 맞는 ratio를 고릅니다. 처음이라면 1.333이 가장 무난한 출발점입니다. 강한 시각 대비가 필요하면 1.414, 정보 밀도 우선이면 1.25를 택합니다.
3단계 — 층위 배정 후 계산 각 층위에 n값을 배정하고 base × ratio^n을 적용합니다. 결과값은 소수 첫째 자리에서 반올림해도 충분합니다.
예를 들어 base=16px, ratio=1.333, H1(n=+4)이라면
16 × 1.333^4 = 16 × 3.157 ≈ 50.5px
rem 변환: 50.5 ÷ 16 = 3.16rem
막상 직접 계산해보면 생각보다 단순하다는 걸 알 수 있다. 곱셈 한 번, 나눗셈 한 번. 수식이 낯설어 보여서 그렇지, 공학 계산기가 아니라 스마트폰 계산기로도 충분하다.
rem으로 변환하는 이유는 접근성입니다. 사용자가 브라우저 기본 폰트를 크게 설정해두면 px값은 고정된 채 남지만, rem은 그 설정에 비례해 같이 커집니다. 시각 접근성이 필요한 분들이 폰트를 키웠을 때 레이아웃이 자연스럽게 따라가는 이유가 여기 있습니다. 이후 실제 폰트를 입혀 렌더링을 확인하고 ±1~2px 미세 조정을 합니다.
배율 4종, base 16px 기준 전 층위 수치
공식 16 × ratio^n을 직접 계산한 수치입니다. rem은 px ÷ 16으로 변환했습니다.
| 층위 | n | 1.25 Major Third | 1.333 Perfect Fourth | 1.414 Augmented Fourth | 1.618 Golden Ratio |
|---|---|---|---|---|---|
| H1 | +4 | 39.1px / 2.44rem | 50.5px / 3.16rem | 64.0px / 4.00rem | 109.7px / 6.85rem |
| H2 | +3 | 31.2px / 1.95rem | 37.9px / 2.37rem | 45.2px / 2.83rem | 67.8px / 4.24rem |
| H3 | +2 | 25.0px / 1.56rem | 28.4px / 1.78rem | 32.0px / 2.00rem | 41.9px / 2.62rem |
| H4 | +1 | 20.0px / 1.25rem | 21.3px / 1.33rem | 22.6px / 1.41rem | 25.9px / 1.62rem |
| 본문 | 0 | 16.0px / 1.00rem | 16.0px / 1.00rem | 16.0px / 1.00rem | 16.0px / 1.00rem |
| Small | -1 | 12.8px / 0.80rem | 12.0px / 0.75rem | 11.3px / 0.71rem | 9.9px / 0.62rem |
| 캡션 | -2 | 10.2px / 0.64rem | 9.0px / 0.56rem | 8.0px / 0.50rem | 6.1px / 0.38rem |
표를 보면 1.618(Golden Ratio)의 문제가 바로 보입니다. H1이 110px에 달하고 캡션이 6px로 내려가는데, 포스터나 대형 비주얼 작업에선 이 극단적 대비가 매력적이지만 웹 본문이나 앱 UI에서는 캡션이 사실상 읽히지 않는 수준이 됩니다. Material Design 3가 Display Large(57sp)부터 Label Small(11sp)까지 15개 스타일을 단일 배율 대신 별도 수치로 정의한 것도 이 때문입니다. 황금비 하나만으로 전체 스케일을 구성하면 양 끝이 실용 범위를 벗어납니다.
1.414(Augmented Fourth)는 수학적으로 √2입니다. H1이 64px의 강한 임팩트를 주면서도 캡션이 8px로 가까스로 실용 범위를 지킵니다. 두 단계마다 정확히 2배가 되는 특성 덕분에 그리드 시스템과 잘 맞는다는 장점도 있습니다.
베이스만 바꾸면 전체 층위가 같은 비율로 이동합니다. ratio 1.333 고정, base만 조정하면 H1이 이렇게 달라집니다.
- base 14px → H1 약 44.2px
- base 16px → H1 약 50.5px
- base 18px → H1 약 56.8px
H1만 크게 키우고 싶을 때는 base가 아니라 ratio를 높이는 게 맞습니다. base를 높이면 H1뿐 아니라 본문과 캡션까지 전체가 같은 비율로 올라가거든요.
프로젝트 유형으로 배율 고르기
배율 고르기가 막막하다면 아래 기준에서 내 프로젝트를 찾아보세요. 어디 해당하는지 보이면 바로 그게 출발점입니다.
- 1.25 (Major Third): 대시보드, 관리 툴, 모바일 앱. 층위 간 차이가 완만해 정보 밀도 우선 인터페이스에 잘 맞아요. Apple Dynamic Type의 Body(17pt)와 Large Title(34pt)은 상단 두 단계만 2.0배 차이로, 층위가 적은 모바일 맥락에선 1.25 이하 배율도 충분합니다.
- 1.333 (Perfect Fourth): 블로그, 에디토리얼, 뉴스. 웹에서 가장 많이 선택되는 배율로, H1~H4 네 단계가 고루 쓰이는 본문형 콘텐츠에 딱 맞습니다.
- 1.414 (Augmented Fourth): 랜딩페이지, 제품 소개. H1이 64px로 히어로 섹션에 임팩트를 주면서도 H3·H4가 무너지지 않아요.
- 1.618 (Golden Ratio): 포스터, 아트 방향 작업에 한정. 웹 UI에 전 층위를 그대로 쓰면 실용 범위를 벗어나므로, 층위 수를 줄이거나 캡션·레이블을 스케일 밖에서 별도 정의해야 합니다.
한글 폰트에서 계산값이 달라지는 지점
계산값은 시작점이지 최종값이 아닙니다.
한글은 영문보다 한 글자가 차지하는 면적이 큽니다. 알파벳은 소문자 높이(x-height)를 기준으로 시각적 크기감이 결정되지만, 한글은 네모꼴 전체가 글자 공간을 채우기 때문에 같은 px 크기라도 훨씬 크게 느껴지거든요. 같은 16px라도 나눔고딕은 크게 보이고 Pretendard는 상대적으로 작게 느껴지는 이유가 여기 있습니다.
특히 주의할 층위는 캡션(n=-2)입니다. 계산상 9~10px 안팎이 나오는데, 한글 폰트에서 10px 미만은 가독성이 크게 떨어질 수 있어요. 최소값을 11px 이상으로 별도 지정하는 편이 낫고, 스케일 체계는 그대로 두고 캡션만 예외 처리하는 방식이 관리하기 가장 편합니다.
행간(line-height)도 폰트별로 달리 잡아야 합니다. 한글은 알파벳보다 베이스라인이 아래에 위치해 같은 배수라도 더 빽빽해 보입니다. 본문 기준 1.6~1.8배, 제목 기준 1.2~1.3배를 출발점으로 삼고 렌더링을 보면서 조정하면 됩니다.
폰트 선택 후 실제 크기감을 확인하려면 폰트비의 폰트 상세 페이지를 활용해보세요. 큰 크기와 작은 크기를 함께 미리볼 수 있어, 계산으로 나온 수치가 해당 폰트에서 실제로 어떻게 보이는지 확인하고 최종값을 결정하는 데 도움이 됩니다.
CSS 커스텀 프로퍼티로 바로 쓰기
계산값을 CSS 커스텀 프로퍼티로 선언하면 base나 ratio를 바꿀 때 :root 블록 안의 수치만 교체하면 됩니다. CSS calc()로 ratio 거듭제곱을 런타임에 계산하는 건 현재 CSS 표준으로 직접 지원되지 않으므로, 빌드 타임에 계산한 값을 직접 넣거나 Sass math.pow() 함수를 씁니다.
:root {
/* base 16px, ratio 1.333 (Perfect Fourth) */
--step-4: 3.157rem; /* H1 ≈ 50.5px */
--step-3: 2.369rem; /* H2 ≈ 37.9px */
--step-2: 1.777rem; /* H3 ≈ 28.4px */
--step-1: 1.333rem; /* H4 ≈ 21.3px */
--step-0: 1rem; /* 본문 = 16px */
--step--1: 0.75rem; /* Small ≈ 12px */
--step--2: 0.563rem; /* 캡션 ≈ 9px */
}
h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }
body { font-size: var(--step-0); }
small, .caption { font-size: var(--step--2); }
배율을 1.414로 바꾸고 싶다면 :root 안의 수치를 4.00rem · 2.83rem · 2.00rem · 1.41rem · 1rem · 0.71rem · 0.50rem으로 교체하면 끝입니다. 변수 이름 체계(--step-N)는 그대로라 h1, h2 셀렉터는 건드릴 필요가 없습니다. 한글 폰트 별 미세 조정이 필요하면 특정 셀렉터에서 calc(var(--step-4) + 1px) 식으로 개별 오버라이드하면 전체 체계를 유지하면서 예외를 처리할 수 있습니다.
디자인 시스템 수준에서 관리할 때는 Figma 변수나 Design Token 형식(JSON)으로 같은 값을 내보낸 뒤 CSS와 동기화하는 방식이 많이 쓰입니다. 기준값 두 개(base, ratio)만 바꾸면 모든 토큰이 자동으로 재생성되니 배율 기반 체계와 자연스럽게 맞습니다.
아직 배율을 못 고르겠다면 1.333에서 시작해보자. 베이스 16px에 위 수치표 값을 그대로 CSS 변수로 붙여넣고, 실제 폰트로 렌더링을 켜보면 된다. 눈에 걸리는 층위가 생기면 그때 미세 조정하면 그만이다. 나머지는 모니터가 알려준다.
이 글이 도움이 됐나요?
여러분의 반응이 다음 글의 방향이 돼요


