Figma 행간 맞췄는데 브라우저에서 틀어지는 진짜 이유

배포 직전 QA에서 "행간이 다른데요"라는 메시지가 오면, 디자이너 입장에서는 황당하다. Figma에는 분명 수치가 들어가 있다. 개발자도 그 수치를 받았다. 그런데 화면이 다르다. 이 상황을 처음 겪으면 서로 뭔가 실수했나 싶어 Figma와 브라우저를 번갈아 확인하게 된다. 정작 두 화면이 구조적으로 달라질 수밖에 없는 이유는 확인 목록에 없는 경우가 많다.
어긋남이 생기는 지점은 대부분 세 곳이다. 그리고 그 세 지점은 전부 핸드오프 순간에 숨어 있다.
같은 수치인데 왜 달라 보이냐면
QA에서 "행간 달라요"가 나왔을 때 가장 먼저 확인해야 하는 건 Figma의 행간 모드가 Auto였는지 여부다.
Figma Auto는 폰트 파일 내부에 저장된 기본 행간 값을 읽어온다. Noto Sans KR이면 Noto 설계자가 정한 값, Pretendard이면 Pretendard 설계자가 정한 값. 이 숫자는 폰트의 OS/2 테이블 또는 hhea 테이블에 박혀 있고, 보통 font-size의 1.1~1.3배 범위에 분포한다. 같은 16px 폰트라도 폰트에 따라 Auto가 17px이 되기도 하고 21px이 되기도 한다.
CSS에서 line-height: normal을 쓰거나 아예 생략하면 브라우저가 자체 기준으로 추정한 값을 쓴다. 대략 1.2 전후인데, 브라우저와 OS마다 다르다. Figma Auto와 CSS normal은 서로 다른 기준에서 출발한다. 디자이너가 Auto로 맞추고 개발자가 line-height: normal을 쓰거나 생략하는 것만으로 두 화면의 여백은 구조적으로 달라진다. 실수가 아니라 설계다.
수치를 맞춰도 위아래 여백이 어긋나는 건 half-leading 때문이다
출발점을 맞췄다고 해도 어긋나는 두 번째 지점이 있다. 행간이 어긋나는 물리적인 원인은 half-leading 분배에 있다.
브라우저는 line-height에서 실제 글자 영역(content-area)을 뺀 나머지 여백, 즉 leading을 위아래로 절반씩 나눠 배분한다. Figma도 같은 원리다. 문제는 이 계산의 기준이 되는 폰트 높이, 즉 content-area가 폰트마다 다르다는 점이다.
CSS에서 font-size를 100px로 고정해도 폰트에 따라 실제 렌더링 높이가 100px보다 크거나 작게 나올 수 있다. 폰트 설계자가 em-square 안에 글자를 어떻게 배치했느냐에 따라 생기는 차이다. 폰트를 교체했을 때 수치를 바꾸지 않았는데 여백이 달라졌다면, 이 half-leading 분배가 조용히 바뀐 것이다. 같은 숫자를 입력해도 폰트가 다르면 시각적 여백이 달라지는 이유가 여기 있다.
px를 그대로 넘기면 반응형이 조용히 무너진다
세 번째 지점은 핸드오프 순간에 가장 자주 발생하는 패턴이다.
Figma에서 Auto 행간, 16px 폰트로 디자인하면 Figma는 내부적으로 약 19~20px를 계산한다. Dev Mode에서 이 값이 "120%" 또는 "19px"로 표시되고, 개발자가 그 숫자를 line-height: 120%나 line-height: 19px로 그대로 입력한다. 당장 그 화면에서는 맞아 보인다. 나중에 터진다.
120%나 1.5em 같은 단위는 부모에서 계산된 절댓값이 자식 요소로 그대로 상속된다. 부모가 font-size: 16px; line-height: 1.5em이면, 자식에 font-size: 24px를 써도 line-height는 여전히 24px다. 글자가 행간보다 커져 줄들이 겹쳐 보이기 시작하는데, 이게 특정 컴포넌트 안에서만 생기면 원인을 찾는 데 시간이 걸린다.
반면 unitless 1.5는 배율 자체가 상속된다. 자식은 자기 font-size인 24px에 1.5를 다시 곱해 36px로 계산한다. 19px를 px 고정으로 넘기는 패턴도 마찬가지 함정이다. 반응형 환경에서 폰트 크기가 바뀌어도 행간이 19px에 고정돼 버린다.
Figma Dev Mode에서 px 값이 넘어왔다면, font-size로 나눠 unitless로 바꾸는 게 CSS에서 가장 예측 가능하게 동작한다. 19px ÷ 16px ≈ 1.19, 즉 line-height: 1.19 정도가 된다.
이 피드백 루프를 막는 방법
세 지점을 알면 예방 루틴은 단순하다.
Figma 쪽에서는 Auto 대신 px나 %로 명시한다. 개발자가 정확한 기준값을 받아야 unitless로 변환할 수 있다. Dev Mode 숫자를 그대로 넘기지 않고, Auto일 경우 실제 계산값으로 확정해서 넘기는 것이 시작이다.
CSS에서는 em·% 대신 unitless를 쓴다. 이 하나만 지켜도 반응형 환경에서 행간 자식 상속 문제가 구조적으로 사라진다.
그리고 폰트를 교체할 때는 행간을 반드시 재검토한다. 폰트 메트릭이 달라지면 half-leading 분배가 바뀌기 때문이다. Figma와 CSS 양쪽에서 동일한 폰트를 쓰고 있는지 먼저 대조하는 게 출발점이다. 웹 폰트를 탐색 중이라면 폰트비에서 폰트 상세 페이지를 열면 @font-face 코드와 라이선스 범위를 바로 확인할 수 있다. "왜 달라 보이냐"는 피드백이 반복된다면 폰트 메트릭부터 맞추는 게 제일 빠르다.
세 군데만 루틴으로 챙기면 "행간이 달라요" 피드백은 잘 안 온다.
이 글이 도움이 됐나요?
여러분의 반응이 다음 글의 방향이 돼요


