한글 웹 타이포그래피 (5) 자간·행간과 문단 간격

한글 웹 타이포그래피 (5) 자간·행간과 문단 간격

4편에서 한 줄에 몇 자를 담을지(measure)를 정했다. 한글 약 40자, 본문 폭 680px. 줄의 가로 폭이 정해졌으니 이제 남은 건 글자와 글자 사이, 줄과 줄 사이, 문단과 문단 사이다. 이 세 간격을 다룬다.

먼저 결론부터 박아두자. 본문 자간은 0, 행간은 1.8, 문단 간격은 약 24px. 이 글은 이 세 값이 왜 그런지, 그리고 어떤 순서로 손대야 하는지를 설명한다. 순서가 중요하다. 자간은 사실상 안 건드리고, 행간은 크기와 measure가 다 정해진 뒤 맨 마지막에 조율하고, 문단 간격은 그 행간에 맞춰 따라온다.

자간은 왜 0이 기본인가

자간(letter-spacing)부터 보자. 결론은 단순하다. 한글 본문은 자간을 0으로 두는 게 기본이고, 나는 특별한 이유가 없으면 아예 손대지 않는다.

이유는 글자 구조에 있다. 한글은 네모틀 글자다. 자음과 모음을 모아써서 하나의 네모 칸에 채우고, 그 칸의 폭이 글자마다 거의 균등하다. 쉽게 말해 한글은 활자를 만들 때 이미 글자 사이 간격을 칸 안에 품고 나온다. 라틴 알파벳은 다르다. iW의 폭이 완전히 다르고, AV가 붙으면 시각적으로 벌어져 보여서 글자 쌍마다 커닝(kerning)으로 간격을 일일이 조정해야 한다. 한글은 그 조정이 네모틀 안에서 미리 끝나 있는 셈이라, 바깥에서 자간을 더 줄 일이 라틴만큼 많지 않다.

여기서 정직하게 짚고 넘어갈 게 있다. 자간을 건드리지 말라는 이 말은 통제된 읽기 실험으로 증명된 상수가 아니다. 예를 들어 본문 크기 17px에서 자간 0과 -0.3px 중 어느 쪽이 완독률이 몇 퍼센트 높더라 하는 식의 깔끔한 대조 실험이 뒷받침하는 게 아니라는 뜻이다. 이건 네모틀이라는 글자 구조와, 오랫동안 쌓인 조판 관습에서 유도한 실무 기본값이다. 그러니 나는 이걸 절대 법칙이 아니라 손대기 전의 출발선으로 쓴다.

실제로 한국 웹 디자인 현장에는 본문에 -0.3px에서 -1px 정도의 약한 음수 자간을 습관처럼 주는 관행이 오래 있었다. 이게 완전히 근거 없는 습관은 아니다. 예전 한글 웹폰트들은 글자 사이가 다소 성기게(넓게) 나오는 경우가 있었고, 그럴 때 살짝 좁혀주면 덩어리감이 좋아 보였다. 다시 말해 음수 자간은 가독성 법칙이라기보다 특정 폰트가 성기게 빠졌을 때 그걸 보정하던 땜질에 가깝다. 요즘 Pretendard 같은 모던 웹폰트는 애초에 글자 간격을 촘촘하게 설계해서 나오기 때문에, 여기에 또 음수 자간을 얹으면 오히려 글자들이 서로 밀착해서 답답해진다.

음수 자간의 함정이 바로 이 지점이다. 자간을 조금만 좁혀도 화면에서는 글자 획들이 서로 달라붙기 시작한다. 한글은 획밀도가 높아서(한 글자 안에 획이 많아서) 조금만 좁혀도 속공간이 뭉개지고, 긴 글을 읽을 때 눈이 글자를 하나씩 떼어내는 데 힘이 더 든다. 짧은 배너 한 줄에서는 멀쩡해 보이던 -1px이 본문 스무 줄이 되면 피로로 돌아온다.

예외는 있다. 큰 제목이다. 글자가 커지면 같은 자간이라도 사이 간격이 상대적으로 넓어 보인다. 그래서 h1처럼 큰 제목에는 약한 음수 자간을 줘서 덩어리를 단단하게 조여주면 보기 좋다. 다만 이건 본문 규칙이 아니라 제목 규칙이고, 제목용 자간과 행간을 어떻게 도출하는지는 6편에서 타입스케일과 함께 다룬다. 이 글에서 못박는 건 본문뿐이다.

/* 본문: 자간 0이 기본. 손대지 않는다 */
.markdown {
  letter-spacing: 0;
}

/* 예외: 큰 제목에만 약한 음수. (이 값의 도출은 6편) */
.markdown h1 {
  letter-spacing: -0.01em;
}

행간은 왜 라틴보다 넓게, 언제 조율하나

행간(line-height)은 반대로 라틴보다 넓게 잡는다. 본문 1.8을 기본으로 쓰고, 범위로는 1.6에서 1.9 사이에서 움직인다.

넓게 잡는 이유도 글자 구조에서 나온다. 한글은 네모 칸을 꽉 채우는 글자라, 한 글자가 세로로 차지하는 높이가 라틴보다 크고 고르다. 라틴은 소문자 x 높이 위아래로 여백이 꽤 있어서 줄과 줄 사이에 숨 쉴 틈이 자연스럽게 생기는데, 한글은 그 여백이 글자 안에 별로 없다. 게다가 획밀도가 높아서 글자 자체가 시각적으로 무겁다. 이 무거운 네모들이 위아래로 촘촘히 쌓이면 줄바꿈할 때 눈이 다음 줄 첫 글자를 못 찾고 헤맨다. 그래서 라틴에서 흔히 쓰는 1.5로는 한글 장문이 답답하고, 한 단계 더 벌려줘야 한다. CJK 본문에 대략 1.7 이상을 권하는 조판 관례가 여기서 나온다.

행간에서 진짜 중요한 건 값 자체보다 언제 정하느냐다. 행간은 혼자 정할 수 없다. 글자 크기와 measure에 딸려 움직이기 때문이다. 규칙은 이렇다. 크기가 커지거나 줄이 길어질수록 행간을 위쪽으로 올린다.

왜 그런지 예를 들어보자. 한 줄이 짧으면(measure가 좁으면) 눈이 줄 끝에서 다음 줄 앞으로 돌아오는 거리가 짧아서, 행간이 좁아도 다음 줄을 쉽게 찾는다. 반대로 한 줄이 길면 되돌아오는 거리가 멀어져서, 행간이 넉넉하지 않으면 엉뚱한 줄로 눈이 튄다. 같은 줄을 두 번 읽거나 한 줄을 건너뛰는 그 짜증이 대개 좁은 행간과 긴 줄의 조합에서 온다. 그래서 measure를 넓게 가져갔다면 행간도 같이 올려줘야 한다.

이 의존 관계 때문에 나는 작업 순서를 이렇게 둔다. 서체를 고르고(2편), 본문 크기와 굵기를 정하고(3편), measure로 줄 길이를 정한(4편) 다음, 맨 마지막에 행간을 조율한다. 크기와 줄 길이가 확정되기 전에 행간부터 만지면, 나중에 크기나 폭을 바꿀 때마다 행간을 다시 처음부터 잡아야 한다. 행간은 다른 값들이 다 자리 잡은 뒤에 그 위에서 미세 조정하는 마지막 손질이라고 생각하면 된다.

우리 블로그의 확정값 안에서 계산해보면 이렇다. 본문 17px, measure 680px에 한글 약 40자. 이 조합은 줄이 짧지도 길지도 않은 중간이라, 1.8이 편안하게 떨어진다. 만약 본문을 20px로 키우거나 폭을 800px로 넓혔다면 1.8로는 살짝 답답해서 1.85에서 1.9 쪽으로 올렸을 것이다.

.markdown {
  font-size: 17px;
  line-height: 1.8; /* 크기·measure가 다 정해진 뒤 마지막에 조율한 값 */
}

행간을 단위 없는 숫자(1.8)로 쓰는 것도 이유가 있다. 1.8은 그 요소의 글자 크기에 비례해서 계산되기 때문에, 큰 제목이든 캡션이든 각자의 크기에 맞는 줄 높이를 자동으로 갖는다. 28.8px처럼 고정 픽셀로 박아두면 크기가 다른 요소에서 비율이 깨진다.

문단 간격은 어느 정도가 적당한가

마지막은 문단 사이 간격이다. 문단과 문단 사이를 얼마나 띄울지, CSS로는 문단에 주는 아래 여백(margin)의 크기다.

기준은 행간의 0.7배에서 1배 사이다. 본문 행간이 1.8이니 한 줄 높이가 대략 30px이고, 문단 간격은 그 70%에서 100%인 20px에서 30px 사이가 자연스럽다. 나는 그 사이인 24px, 곧 행간의 0.8배쯤을 기본으로 둔다. 본문 17px 기준으로 한 글자 크기를 살짝 넘는 정도다.

왜 이 정도냐면, 문단 간격이 줄 사이 간격(행간)과 너무 비슷하면 문단이 어디서 끊기는지 눈에 안 들어오고, 반대로 너무 크게 벌리면 글이 뚝뚝 끊긴 조각처럼 보여서 흐름이 죽는다. 문단 간격은 행간보다 확실히 넓되, 문단들이 여전히 한 덩어리 글로 읽히는 선에서 멈춰야 한다. 그래서 행간에 연동해서 그 살짝 위로 잡는 것이다. 여기서도 문단 간격이 행간에 딸려 정해진다는 걸 볼 수 있다. 행간을 마지막에 조율하는 이유가 하나 더 늘어나는 셈이다.

그런데 간격 값보다 완독률에 훨씬 크게 작용하는 게 따로 있다. 한 문단의 길이다. 한 문단이 화면 한 판을 넘겨서 스크롤을 해야 끝나는 길이면, 읽는 사람은 그 문단 안에서 길을 잃고 중간에 이탈한다. 이건 CSS로 여백을 아무리 예쁘게 잡아도 해결되지 않는다. 글을 쓰는 단계에서 문단을 잘게 끊어야 풀린다.

예를 들어 이런 상황이다. 개념 하나를 설명하는데 정의, 이유, 예시, 반례, 정리를 한 문단에 다 몰아넣으면 그 문단이 열 줄, 열두 줄로 늘어난다. 화면을 꽉 채우고도 안 끝난다. 이걸 정의와 이유 한 덩어리, 예시 한 덩어리, 정리 한 덩어리로 세 문단으로 쪼개면, 문단 사이의 여백마다 눈이 잠깐 쉬고 다음 덩어리로 넘어간다. 여백은 그 쉼표를 시각적으로 만들어줄 뿐이고, 쉼표가 들어갈 자리를 만드는 건 문단을 끊는 글쓰기다.

그러니 문단 간격은 CSS에서 한 줄로 끝내고, 진짜 공은 원고 단계에 들인다. 한 문단이 화면을 넘기려 하면 거기서 끊는다.

.markdown p {
  margin: 0 0 24px; /* 문단 사이 약 24px. 행간 1.8의 0.8배쯤 */
}

정리

이 글에서 못박은 본문 값은 셋이다.

자간(letter-spacing): 0        (네모틀 구조·조판 관습에서 유도. 실증 상수 아님)
행간(line-height): 1.8         (라틴보다 넓게. 크기·measure 확정 뒤 마지막에 조율)
문단 간격(margin): 약 24px     (행간의 0.8배쯤. 진짜 관건은 문단을 잘게 끊는 글쓰기)

세 값을 관통하는 원리는 순서다. 자간은 손대지 않는 출발선, measure까지 다 정한 다음 행간을 마지막에 조율, 문단 간격은 그 행간에 맞춰 따라온다. 자간을 굳이 음수로 조이지 말고, 행간은 크기와 줄 길이가 커질수록 위로 올리고, 문단은 화면을 넘기기 전에 끊는다. 이걸 지키면 한글 본문이 답답하지도 흩어지지도 않는다.

여기서 다룬 건 본문뿐이다. 큰 제목의 자간과 행간, 그리고 본문 17px에서 h1까지 크기를 어떻게 뽑아내는지는 6편에서 타입스케일과 함께 하나의 CSS 변수 블록으로 조립한다.