반응형 타이포그래피 토큰화 전략: 유연한 폰트 스케일링 가이드
해상도가 바뀔 때마다 일일이 폰트 크기를 미디어 쿼리로 조정하다가 코드가 스파게티처럼 꼬인 적 없으신가요? 모바일에서는 적당해 보이던 제목이 데스크톱으로 넘어가면 너무 작아 보이고, 반대로 데스크톱에 맞추면 모바일 화면이 글자로 꽉 차버리는 문제는 모든 프론트엔드 개발자와 디자이너의 공통된 고민입니다.
이 글을 읽고 나면 단순히 픽셀 값을 나열하는 수준을 넘어, 수학적 원리를 기반으로 한 ‘모듈러 스케일(Modular Scale)’과 브라우저의 ‘유동적 타이포그래피(Fluid Typography)’ 기술을 결합하여 어떤 기기에서도 완벽한 가독성을 유지하는 타이포그래피 토큰 시스템을 구축하는 방법을 완벽히 이해하시게 될 거예요.
모듈러 스케일: 수학적 질서가 만드는 시각적 리듬
타이포그래피 토큰화의 핵심은 단순히 ‘제목1’, ‘제목2’를 만드는 것이 아니라, 각 폰트 크기 사이의 ‘비율(Ratio)’을 정의하는 것입니다. 우리는 이를 모듈러 스케일이라고 부릅니다. 기준이 되는 기본 폰트 크기($Base$)에 일정한 비율($Ratio$)을 거듭제곱하여 계층을 만드는 방식이죠.
일반적으로 웹에서는 ‘Major Third(1.25)’나 ‘Perfect Fourth(1.333)’ 비율이 자주 쓰입니다. 예를 들어 기준 크기가 16px이고 비율이 1.25라면, 다음 단계는 20px, 그다음은 25px이 되는 식입니다. 이렇게 수학적으로 정의된 토큰은 디자이너가 임의로 “이건 23px로 해주세요”라고 요청하는 상황을 방지하고, 시스템 전체에 일관된 시각적 리듬을 부여합니다.
[💡 에디터의 실무 팁: 실무에서는 본문용 폰트는 1.125(Major Second)처럼 낮은 비율을 사용해 가독성을 높이고, 제목용 폰트는 1.414(Augmented Fourth)처럼 높은 비율을 써서 위계를 강조하는 이중 스케일 전략을 추천해요.]
유동적 타이포그래피: 미디어 쿼리 없는 반응형 구현
전통적인 방식에서는 sm:text-lg, lg:text-2xl처럼 브라우저 중단점(Breakpoint)마다 클래스를 갈아끼웠습니다. 하지만 이는 중단점 사이의 ‘애매한’ 해상도에서 폰트 크기가 갑자기 툭툭 튀는 현상을 유발합니다. 이를 해결하기 위해 최근에는 CSS의 clamp() 함수를 활용한 유동적 스케일링을 토큰화합니다.
/* 타이포그래피 토큰 예시 */
:root {
–font-size-h1: clamp(2rem, 5vw + 1rem, 4rem);
}
위 코드에서 clamp는 최소값, 유동값, 최대값을 설정합니다. 브라우저 너비에 따라 폰트 크기가 2rem에서 4rem 사이를 매끄럽게 오가게 되죠. 이렇게 설계된 토큰은 단 한 줄의 코드로 모든 해상도에 대응할 수 있게 해줍니다. Style Dictionary를 사용한다면, 빌드 시점에 픽셀 단위를 기반으로 이러한 유동적 수식을 자동 계산하여 CSS 변수로 추출하는 트랜스포머(Transformer)를 구축하는 것이 DesignOps의 핵심입니다.
트러블슈팅: 행간(Line-height)과 자간(Letter-spacing)의 함정
실무에서 가장 많이 발생하는 사고는 폰트 크기 토큰만 관리하고 행간과 자간을 방치할 때 일어납니다. 폰트가 커질수록 상대적으로 행간은 좁아져야 하고, 자간 또한 미세하게 조정되어야 합니다. 그렇지 않으면 큰 제목의 글자 사이가 너무 벌어져 가독성이 떨어지게 됩니다.
저는 이 문제를 해결하기 위해 ‘타이포그래피 컴포지트 토큰(Composite Tokens)’을 도입했습니다. 폰트 사이즈 하나에 해당하는 행간과 자간을 묶음으로 정의하는 것이죠. 예를 들어 display-01이라는 토큰 안에는 fontSize, lineHeight, letterSpacing이 하나의 세트로 들어있습니다.
실제로 대규모 뉴스 포털 프로젝트에서 폰트 크기만 따로 조정했다가 모바일에서 텍스트가 겹치는 대참사가 난 적이 있었는데, 모든 폰트 토큰에 line-height: 1.2와 같은 배수 단위를 강제하고 크기와 연동된 컴포지트 토큰으로 마이그레이션한 후에야 비로소 평화가 찾아왔습니다.
[💡 에디터의 실무 팁: 행간은 반드시 단위 없는 숫자(예: 1.5)나 em 단위를 사용하세요. 픽셀(px)로 고정하면 폰트 크기가 변할 때마다 행간이 깨지는 고통을 겪게 됩니다.]
타이포그래피 토큰의 코드 연동 및 자동화
결국 우리가 만든 이 복잡한 스케일링 규칙은 개발자가 쓰기 편해야 의미가 있습니다. Style Dictionary를 통해 JSON 데이터를 variables.css로 변환할 때, 타이포그래피 관련 토큰들은 별도의 mixin이나 유틸리티 클래스로 자동 생성되도록 구성하세요.
리액트 환경이라면 앞서 배운 테일윈드(Tailwind) 연동 전략과 결합하여 text-h1 클래스 하나만으로 clamp() 기반의 유동적 크기, 최적화된 행간, 브랜드 자간이 동시에 적용되도록 설계해야 합니다. 이것이 바로 디자인 엔지니어가 시스템을 통해 개발팀 전체의 코딩 퀄리티를 상향 평준화하는 방법입니다.
자주 묻는 질문(FAQ)
Q1. 본문 폰트도 clamp()로 유동적으로 조절하는 게 좋나요? 본문(Body) 폰트는 가독성이 최우선입니다. 너무 작아지거나 커지면 오히려 읽기 불편하므로, 본문은 고정된 rem 단위를 사용하거나 아주 좁은 범위 내에서만 변하도록 설정하는 것이 정석입니다. 주로 제목(Heading) 요소에 유동적 스케일을 적극 활용하세요.
Q2. 폰트 스케일 비율은 어떻게 정하는 게 가장 과학적인가요? 과학적인 정답은 없지만, 브랜드의 성격에 따라 다릅니다. 미니멀하고 차분한 서비스라면 1.125나 1.2 비율을, 역동적이고 화려한 마케팅 페이지라면 1.414나 1.618(황금비) 비율을 선택하는 것부터 시작해 보세요.
Q3. 픽셀(px) 대신 rem을 써야 하는 진짜 이유가 뭔가요? 접근성 때문입니다. 사용자가 브라우저 설정에서 기본 글꼴 크기를 키웠을 때, rem은 그 설정에 맞춰 함께 커지지만 px은 무시하고 고정됩니다. 모든 사용자를 포용하는 디자인 시스템을 지향한다면 rem 사용은 필수입니다.