Figma에서는 예쁜데, 웹에서는 왜 더 두꺼워 보일까?
프론트엔드에서 Figma는 빼놓을 수 없는 툴이죠. 그런데 막상 Figma 시안을 웹에 올리면 글자가 미묘하게 더 굵거나 답답하게 보이는 현상이 생깁니다. 같은 font-weight: 500인데도 macOS, Windows, Chrome, Safari마다 굵기가 제각각이기 때문입니다.
저도 최근에 Pretendard 폰트가 미묘하게 다른 트러블슈팅이 있었습니다. 처음엔 제가 뭘 잘못 넣었나 싶어 CSS를 몇 번이나 다시 봤습니다.
"분명 같은 폰트, 같은 weight인데 왜 다르지?"
제가 해결한 방법과 그 이유를 알아보겠습니다.
브라우저는 OS의 폰트 렌더러를 빌려 쓴다
브라우저가 텍스트를 그릴 때는 OS의 폰트 렌더러를 씁니다. 해당 렌더러는 폰트를 그리는 방식이 다르니까 같은 Pretendard라도 환경마다 다르게 보입니다.
폰트는 벡터 기반으로 만들어집니다. 즉, 글자의 획은 수학적으로 정의된 곡선입니다. 하지만 실제 화면은 픽셀(pixel)이라는 네모난 점들로 이루어져 있죠. 그래서 "이 곡선을 픽셀 그리드 위에 어떻게 표현할 것인가" 를 각 OS가 각자의 방식으로 결정합니다. 이게 바로 렌더링 엔진의 차이입니다.
Windows는 힌팅을 충실히 지킨다
Windows의 렌더링 엔진(ClearType)은 텍스트를 서브픽셀(subpixel) 단위로 정밀하게 계산하고, 폰트 안에 포함된 힌팅(hinting) 정보를 매우 충실히 따릅니다.
픽셀 하나는 사실 RGB 세 개의 막대(서브픽셀)로 구성돼 있습니다. ClearType은 이 RGB를 독립적으로 조작해서 글자의 가장자리를 더 세밀하게 표현합니다. 수평 해상도가 3배로 늘어난 효과를 내는 거죠. 여기에 더해 폰트 디자이너가 "이 획은 픽셀 경계에 딱 맞춰야 한다" 고 심어둔 힌팅 정보를 정확히 지키는 것을 최우선으로 합니다. 그 결과 획이 또렷하고 균일하게 보이고, 디자인 원형보다 약간 두텁게 보일 수 있습니다.
macOS는 디자이너의 원형을 우선한다
macOS의 CoreText는 정반대 철학을 가지고 있습니다. "폰트는 디자이너의 원형에 가깝게 보여야 한다" 는 원칙입니다.
서브픽셀을 따로 다루지 않고, 각 픽셀의 밝기(intensity)만 조절해서 윤곽선을 표현합니다. 그래서 글자 가장자리가 부드럽고 매끄럽게 보이죠. 픽셀 그리드보다는 곡선의 형태를 우선하고, 힌팅 정보는 최소한으로만 적용합니다. 획이 얇고 자연스럽게 보이지만 약간 흐릿하거나 연하게 보일 수도 있습니다.
| OS/엔진 | 렌더러 방식 | 시각적 특징 |
|---|---|---|
| Windows (ClearType) | 서브픽셀 렌더링 + 힌팅 우선 | 수평선이 또렷하고 두텁게 보임 |
| macOS (CoreText) | 그레이스케일 렌더링 + 부드러움 우선 | 곡선이 매끄럽고 얇게 보임 |
즉, 같은 Pretendard 500이라도 macOS에서는 "슬림하고 부드럽게", Windows에서는 "선명하고 두텁게" 보이는 이유가 바로 이 렌더링 엔진의 철학 차이 때문입니다. 렌더링 엔진은 "폰트를 어떻게 픽셀로 번역할지" 를 결정하고, 이 차이가 Figma(디자인)와 웹(브라우저) 간의 굵기 체감 차이를 만듭니다.
완전히 같게는 못 만들어도, 좁힐 수는 있다
Windows와 macOS는 텍스트 렌더링 철학 자체가 다르기 때문에 완벽히 동일한 폰트 표현을 만드는 건 불가능에 가깝습니다.
하지만 몇 가지 CSS 속성을 조정하면, 브라우저마다의 렌더링 차이를 체감상 거의 비슷한 수준으로 줄일 수 있습니다.
-webkit-font-smoothing으로 서브픽셀을 끈다
이 속성은 macOS 기반 브라우저(Safari, Chrome, Edge 등)에서 서브픽셀 렌더링을 강제로 비활성화하거나, 그레이스케일 렌더링 강도를 조절할 수 있습니다.
html,
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
antialiased는 텍스트를 그레이스케일로 부드럽게 표현하는 기본 macOS 스타일이고, subpixel-antialiased는 픽셀 단위로 조금 더 또렷하게 표현해서 Windows 느낌에 가깝습니다. macOS에서 antialiased를 적용하면 글자가 살짝 얇아지고 부드러워져서 Figma의 폰트 느낌과 비슷하게 만들 수 있습니다.
text-rendering으로 최적화 방향을 정한다
이 속성은 브라우저의 텍스트 렌더링 최적화 모드를 지정합니다. 폰트 힌팅을 얼마나 따를지, 자간을 어떻게 계산할지를 제어하죠.
body {
text-rendering: optimizeLegibility;
}
| 값 | 설명 |
|---|---|
auto | 기본값. 브라우저가 알아서 결정 |
optimizeLegibility | 부드러운 곡선과 자연스러운 커닝 적용 (macOS처럼) |
geometricPrecision | 픽셀 정확도 우선 (Windows 느낌에 가까움) |
font-synthesis: none으로 가짜 굵기를 막는다
macOS Safari는 폰트에 존재하지 않는 굵기나 스타일(예: 500, italic)을 자동으로 "합성(synthesize)" 해서 보여주는 경우가 있습니다. 이게 때로는 디자이너 의도와 다른 굵기로 보이게 만드는 원인이 되죠.
body {
font-synthesis: none;
}
이 속성을 추가하면 브라우저가 인위적으로 굵기를 보정하지 않아서 Figma에서 본 폰트 두께와 더 일치하게 됩니다.
그래도 안 맞으면 눈으로 보정한다
결국 환경별 렌더링 차이를 완벽히 제거할 수는 없으니까 시각적 보정(visual compensation)이 필요할 때도 있습니다. macOS에서 너무 얇게 보인다면 font-weight: 600, Windows에서 너무 두껍게 보인다면 font-weight: 400처럼 운영체제 감별(@supports 또는 navigator.userAgent)을 통해 미세하게 조정할 수도 있습니다.
운영체제의 렌더링 철학은 다르지만, 위 CSS 속성들을 조합하면 "디자인 시안과 거의 동일한 시각적 톤" 을 구현할 수 있습니다. 완벽히 같을 수는 없지만, 사용자 경험에 영향을 주지 않을 정도의 일관성은 충분히 확보할 수 있습니다.
Figma는 애초에 OS 렌더러를 쓰지 않는다
OS 간 차이 외에도 근본적인 문제가 하나 더 있습니다. Figma는 OS 폰트 렌더러를 쓰지 않습니다.
Figma는 자체적인 텍스트 렌더링 엔진을 가지고 있기 때문입니다. 일관된 디자인 경험을 제공하려고 macOS/Windows/웹 어디서 보든 동일하게 보이도록 폰트를 직접 처리합니다. 즉, Figma에서 본 Pretendard 500은 어떤 OS에서도 같아 보이지만, 브라우저에서 본 Pretendard 500은 OS 렌더러에 따라 달라집니다.
Figma 디자인과 웹 구현의 차이가 생기는 이유는 결국 두 가지입니다.
- Figma는 자체 렌더링 엔진을 쓰고, 브라우저는 OS 렌더러를 씁니다.
- OS마다 렌더러 철학이 다릅니다.
이 차이를 완전히 없애는 건 불가능합니다. 현실적인 목표는 "Figma와 완전히 같게" 가 아니라 "디자이너와 개발자가 협의한 수용 범위 안에서 일관되게" 입니다.
로딩 타이밍도 폰트 체감을 바꾼다
웹폰트가 아직 로드되지 않은 상태에서 텍스트가 표시되는 방식도 폰트 체감 품질에 영향을 줍니다.
font-display 값 | 동작 | 특징 |
|---|---|---|
auto | 브라우저 기본 동작 | 예측하기 어려움 |
block | 폰트 로드 전까지 텍스트 숨김 | FOIT 발생 |
swap | 시스템 폰트 먼저 → 로드 후 교체 | FOUT 발생, SEO 친화적 |
fallback | 짧게 숨김 → 시스템 폰트 → 교체 | 절충안 |
optional | 네트워크 상태에 따라 교체 안 할 수도 있음 | 가장 부드러운 UX |
Pretendard처럼 한글 폰트는 파일 크기가 크니까, font-display: swap을 쓰면 로딩 초기에 시스템 폰트(애플 SD 산돌고딕 등)가 보였다가 Pretendard로 바뀌는 레이아웃 시프트가 발생합니다. 렌더링 안정성을 위해 font-display: optional을 쓰거나, <link rel="preload">로 폰트를 미리 받아두는 방식이 좋습니다.
<link
rel="preload"
href="/fonts/Pretendard-Variable.woff2"
as="font"
type="font/woff2"
crossorigin
/>
마치며
처음엔 "Figma 시안이랑 왜 다르게 나오지?" 라는 막연한 의문이었는데, 파고들수록 OS 렌더러 철학 차이, Figma 자체 엔진, 폰트 로딩 타이밍이 얽혀 있다는 걸 알게 됐습니다.
완벽한 크로스 플랫폼 폰트 일치는 애초에 불가능한 목표입니다. 그보다는 -webkit-font-smoothing: antialiased와 font-synthesis: none을 기본값으로 설정해두고, 환경별 체감 차이를 미리 팀과 공유해두는 게 실용적일 것 같습니다. 디자이너와 개발자가 "이 정도는 허용 범위" 라는 기준을 공유하고 있으면, 사소한 차이로 소모되는 시간을 줄일 수 있지 않을까요.