design system에서 font size별 line-height를 설정할 때 짝수 값을 써야 하는 이유에 대해 정리합니다.
Figma에서 line-height를 120% 같은 percentage로 지정하면 내부적으로 pixel 변환 시 반올림 처리를 합니다. font-size 14px 기준 14 1.2 = 16.8은 17px, 16px 기준 16 1.2 = 19.2는 19px이 됩니다.
CSS에서 line-height: 120%를 그대로 쓰면 소수점이 살아있어서 Figma 렌더링 결과와 미세하게 달라집니다. Figma와 정확하게 맞추려면 반올림된 값을 직접 지정해야 합니다.
font icon과 text를 align-items: center로 나란히 배치하면, 홀수 line-height에서 text가 정확히 center에 오지 않습니다. 육안으로 가볍게 보면 모를 정도지만 자세히 보면 확인할 수 있는 수준입니다. font icon의 baseline이 일반 font 대비 살짝 낮게 제작되어 있는 점까지 더해지면 어긋남이 좀 더 눈에 띕니다.
font-size: 16px이라고 해서 글자가 차지하는 실제 높이가 16px은 아닙니다. font 파일 내부의 ascender + descender 값으로 결정되는 content-area가 실제 높이이고, 같은 font-size라도 font family마다 이 값이 다릅니다.
browser는 line-height에서 content-area를 뺀 값인 leading을 위아래로 절반씩(half-leading) 분배합니다.
이 leading이 홀수면 half-leading이 0.5px 단위가 되는데, CSS spec에서는 이 sub-pixel 값의 rounding 방식을 명시하지 않습니다. browser마다 처리가 다르고, 이게 flex 정렬과 맞물리면 시각적 어긋남으로 나타납니다.
정확히는 line-height의 홀짝이 아니라 leading이 홀수일 때 문제가 생기는 건데, content-area는 font마다 다르고 직접 제어할 수 없기 때문에 line-height를 짝수로 맞추는 게 가장 현실적인 대응입니다.
120%에서 반올림한 값이 홀수인 경우, 1px 올려서 짝수로 맞추면 됩니다.
| font-size | 120% | 반올림 | 최종 line-height |
|---|---|---|---|
| 12px | 14.4 | 14 | 14 (유지) |
| 13px | 15.6 | 16 | 16 (유지) |
| 14px | 16.8 | 17 | 18 (올림) |
| 16px | 19.2 | 19 | 20 (올림) |
| 18px | 21.6 | 22 | 22 (유지) |
| 20px | 24.0 | 24 | 24 (유지) |
| 24px | 28.8 | 29 | 30 (올림) |
Figma 기준에서 1px 차이가 생기는 케이스가 있지만 시각적으로 구분되지 않고, 정렬 정확도가 올라가는 이점이 더 큽니다.
Figma의 percentage line-height 반올림 결과를 그대로 가져오면 홀수 값이 섞이게 되고, flex 정렬에서 sub-pixel 이슈로 이어집니다. design system에서 line-height를 짝수로 통일하면 이 문제를 피할 수 있습니다.