한글 웹 타이포그래피 (8) 속공간과 커닝

시리즈 한글 웹 타이포그래피 8 / 11
  1. 1한글 웹 타이포그래피 (1) 서구 규칙을 그대로 쓰면 안 되는 이유
  2. 2한글 웹 타이포그래피 (2) 명조와 고딕, 화면에서 무엇을 언제
  3. 3한글 웹 타이포그래피 (3) 글자 크기와 굵기, 그리고 본문 대비
  4. 4한글 웹 타이포그래피 (4) 글 길이와 줄끝 처리
  5. 5한글 웹 타이포그래피 (5) 자간·행간과 문단 간격
  6. 6한글 웹 타이포그래피 (6) 위계와 타입스케일: 본문에서 값을 뽑아 조립하기
  7. 7한글 웹 타이포그래피 (7) 웹폰트 로딩과 성능
  8. 8한글 웹 타이포그래피 (8) 속공간과 커닝
  9. 9한글 웹 타이포그래피 (9) 줄상자의 해부
  10. 10한글 웹 타이포그래피 (10) 문장부호가 데려오는 사이 공간
  11. 11한글 웹 타이포그래피 (11) 폴백 폰트가 밀어내는 줄
한글 웹 타이포그래피 (8) 속공간과 커닝

5편에서 본문 자간은 0, 행간은 1.8로 정했다. 그런데 이상하지 않은가. 둘 다 글자 사이의 빈 공간을 다루는 값인데, 하나는 손대지 말라 하고 하나는 넉넉히 벌리라 한다. 왜 자간은 그대로 두면서 행간은 벌리는가. 이 둘을 하나로 꿰는 뿌리가 있다. 글자 안의 흰 공간, 속공간이다.

본편은 7편에서 닫았지만, 이 속공간 하나를 붙잡으면 앞에서 정한 값들이 왜 그렇게 갈렸는지가 훨씬 또렷해져서 심화편으로 한 편 더 얹는다. 이 글은 두 가지를 다룬다. 하나는 속공간이 자간과 행간을 각각 어떻게 정하는가. 다른 하나는 그 사촌 격인 커닝(kerning)이 무슨 일을 하고, 한글 웹 본문에서는 왜 거의 손댈 일이 없는가.

속공간이란 무엇인가

속공간(counter)은 글자를 이루는 획들이 감싸 안은 흰 공간이다. 라틴으로 보면 쉽다. o의 뻥 뚫린 가운데, e의 안쪽 방, n의 아치 아래 빈 곳. 이 글자 속 빈 자리가 다 속공간이다. 한글도 마찬가지다. 의 네모 안, 의 동그라미 안, 그리고 닿자와 홀자 사이, 받침과 그 위 사이에 난 자잘한 틈이 전부 속공간이다.

라틴한글파랑 = 글자 안 속공간
o·e·n은 큰 속공간 하나씩, ㅁ·ㅇ·ㅎ은 획이 감싼 작은 속공간. 파란 자리가 전부 속공간이다.

여기에 하나를 더 붙이자. 글자는 자기 활자 칸 안에서 좌우로 조금씩 여백을 남기고 앉는다. 이 글자 곁의 여백을 사이드베어링(side bearing)이라 한다. 글자 안의 속공간과 글자 곁의 여백을 묶어서 보면, 조판이라는 일의 정체가 드러난다. 조판은 이 흰 공간들을 고르게 배치하는 일이다. 검은 획을 그리는 게 아니라 흰 공간을 배열하는 것, 이게 타이포그래피의 오래된 속내다.

글자를 둘러싼 흰 공간은 두 군데 — 안과 곁속공간 · 안사이드베어링 · 곁
글자 안의 흰 공간이 속공간(안), 글자 곁의 흰 공간이 사이드베어링(곁)이다. 조판은 이 안팎 흰 공간을 고르게 배치하는 일이다.

그런데 한글은 이 속공간이 작다. 3편에서 본 획밀도 때문이다. 한글은 네모틀 안에 자음과 모음을, 받침이 있으면 받침까지 모아써서, 같은 크기 상자에 라틴보다 훨씬 많은 획을 욱여넣는다. 획이 빽빽하면 그 사이를 지나는 흰 공간은 잘게 쪼개지고 좁아진다. o를 같은 크기로 나란히 놓아보자. o는 큼직한 흰 공간 하나를 품지만, 은 ㅎ의 꼭지 밑, 동그라미 안, ㅡ 위아래, 받침 ㄺ의 겹친 틈으로 자잘한 흰 공간이 여러 개 흩어진다. 그래서 한글은 속공간이 작고 촘촘하다. 이 사실 하나가 뒤에 나올 모든 결정을 끌고 간다.

o속공간 1개 · 큼속공간 여러 개 · 작음
같은 크기 상자에 라틴은 큰 속공간 하나, 한글은 획이 빽빽해 잘게 쪼개진 작은 속공간 여럿. 이 한 가지가 뒤의 모든 결정을 끌고 간다.

흰 공간에는 위계가 있다

조판에서 흰 공간은 한 종류가 아니다. 글자 안 속공간이 있고, 글자와 글자 사이가 있고(자간이 얹히는 자리), 낱말과 낱말 사이가 있고(띄어쓰기), 줄과 줄 사이가 있다(행간이 얹히는 자리). 잘 짜인 본문에서 이 넷은 아무렇게나 놓이지 않는다. 안쪽에서 바깥쪽으로 갈수록 커진다.

속공간 ≲ 글자사이(자간) < 낱말사이 < 글줄사이(행간)
속공간 ≲ 자간 < 낱말사이 < 행간속공간자간낱말사이행간속공간사이 공간
안쪽에서 바깥으로 흰 공간이 커진다. 파랑(속공간)이 제일 작고, 노랑 사이 공간은 자간 → 낱말사이 → 행간 순으로 넓어진다. 이 순서가 지켜져야 글자가 낱말로, 낱말이 줄로 묶인다.

왜 이 순서여야 하나. 눈이 가까운 것부터 한 덩어리로 묶어 읽기 때문이다. 이걸 근접성(proximity)이라 한다. 쉽게 말해, 서로 가까이 붙은 것들을 우리 눈은 한 무리로 본다. 글자 안 획들이 서로 제일 가까우니 한 글자로 묶이고, 글자들이 그다음으로 가까우니 낱말로 묶이고, 낱말이 줄로, 줄이 문단으로 묶인다. 이 묶임이 제대로 일어나려면 안쪽 간격이 바깥쪽 간격보다 작아야 한다.

이 위계가 깨지면 어떻게 되는지 상상해보자. 글자사이가 낱말사이보다 넓어지면, 눈은 낱말을 못 묶고 글자를 하나하나 흩어진 낱개로 읽는다. 안 녕 하 세 요처럼 보이는 것이다. 반대로 행간이 낱말사이보다 좁아지면, 줄이 위아래로 안 나뉘고 다음 줄 글자가 위 줄에 달라붙어 어디까지가 한 줄인지 눈이 헤맨다. 그러니까 조판을 잘한다는 건 이 위계를 지킨다는 것이고, 위계의 맨 안쪽 기준점이 바로 속공간이다.

레터링과 타입 디자인에는 오래 내려온 원리가 하나 있다. 글자 안의 속공간이 글자 곁의 사이드베어링을 정하고, 그 사이드베어링이 모여 글자와 글자 사이를 정한다는 것이다. 여기서 그 ‘사이’를 넉넉하게 또는 좁게 잡는 손은 우리가 CSS로 얹는 자간이 아니라, 폰트를 그리는 사람이 글자마다 붙여 내보내는 사이드베어링이다. 속공간이 크면 사이드베어링도 넉넉하게, 작으면 좁게 잡아야 안과 곁의 흰 공간이 한 리듬으로 이어져 고르게 읽힌다. 안쪽에서 바깥으로 흰 공간의 리듬이 이어진다고 보면 된다. 이건 통제된 실험이 증명한 상수라기보다 글자를 그려온 사람들의 오랜 감각이 정리된 원리인데, 이 블로그의 자간·행간 판단도 결국 여기에 기댄다. 이 원리를 한글에 대면, 앞 절의 결론(한글은 속공간이 작다)이 곧장 실무 규칙으로 바뀐다. 하나씩 보자.

속공간이 자간을 정한다

자간을 준다는 건 글자와 글자 사이의 흰 공간을 늘리거나 줄이는 일이다. 위계상 이 글자사이는 속공간보다는 크고 낱말사이보다는 작아야 한다. 이 좁은 구간 안에 글자사이가 들어앉아 있어야 글자가 낱말로 잘 묶인다.

한글은 이 자리가 이미 잘 맞춰져 있다. 속공간이 작은 데 맞춰, 잘 만든 폰트는 글자 곁의 사이드베어링도 그만큼 좁게 잡아서 내보낸다. 다시 말해 속공간과 글자사이의 균형이 네모틀 안에서 폰트가 출고될 때 이미 잡혀 있다. 그러니 바깥에서 자간을 더 얹어 흔들 이유가 별로 없다. 이게 5편에서 본문 자간을 0으로 두는 진짜 근거다. 네모틀이라 균등해서가 아니라, 작은 속공간에 맞춰 글자사이가 이미 조율돼 나오기 때문이다.

음수 자간이 위험한 이유도 여기서 정확히 설명된다. 자간을 음수로 주면 글자사이가 좁아진다. 그런데 한글은 속공간이 원래 작다. 글자사이를 조금만 줄여도, 글자사이가 속공간만큼 작아지는 지점에 금방 닿는다. 그 순간 위계가 무너진다. 글자 안의 흰 공간과 글자 사이의 흰 공간이 구별되지 않으니, 눈이 어디까지가 한 글자인지 못 가른다. 옆 글자의 획과 내 글자의 획이 같은 간격으로 붙어 서로 뭉갠다. 라틴은 속공간이 커서 음수를 좀 줘도 글자사이가 속공간까지 좁아지기 전에 여유가 있지만, 한글은 그 여유가 처음부터 얼마 없다. 같은 -1px이라도 라틴 본문은 버티고 한글 본문은 무너지는 이유다.

같은 -자간이라도 라틴은 버티고 한글은 무너진다자간 0사이 > 속공간 → 구분됨음수 자간사이 ≈ 속공간 → 뭉갬
자간을 음수로 주면 글자사이(노랑)가 좁아진다. 한글은 속공간(파랑)이 원래 작아, 조금만 줄여도 글자사이가 속공간만큼 작아지는 지점에 금방 닿는다. 그 순간 안팎 흰 공간의 구분이 사라져 획이 서로 뭉갠다.

큰 제목이 예외인 것도 속공간으로 설명된다. 글자가 커지면 속공간도 같이 커진다. 커진 속공간에 비하면 글자사이가 상대적으로 넓어 보인다. 그래서 큰 제목은 살짝 음수로 조여도 글자사이가 여전히 속공간보다는 크게 남아, 위계가 안 깨진 채로 덩어리만 단단해진다. 본문은 속공간이 이미 바닥이라 그 여유가 없다. 똑같은 -0.01em이 제목에서는 약이 되고 본문에서는 독이 되는 건, 두 자리의 속공간 크기가 다르기 때문이다.

/* 본문: 속공간이 작아 자간을 더 줄일 여유가 없다 → 0 */
.markdown {
  letter-spacing: 0;
}

/* 제목: 커지며 속공간도 커져 살짝 조일 여유가 생긴다 (도출은 6편) */
.markdown h1 {
  letter-spacing: -0.01em;
}

속공간이 행간을 정한다

행간은 줄과 줄 사이의 흰 공간이다. 위계의 맨 바깥이라 제일 커야 한다. 그래야 줄이 하나의 덩어리로 확실히 분리된다. 그런데 한글은 이 행간을 라틴보다 더 벌려야 하고, 그 이유 역시 속공간에 있다. 이번엔 세로 방향의 속공간이다.

글자는 자기 칸 안에서 위아래로도 여백을 남긴다. 라틴 소문자를 보자. 몸통(x-height) 위로는 bl의 어센더가 쓰는 여백이, 아래로는 gy의 디센더가 쓰는 여백이 있다. 대부분의 소문자는 이 위아래 여백을 다 안 쓰고 몸통만 채우니, 글자 자체가 세로 여백을 꽤 품고 있다. 줄을 위아래로 쌓아도 이 품은 여백이 줄 사이에 숨통을 얼마간 만들어준다. 한글은 다르다. 네모틀을 위아래로 거의 꽉 채워서, 글자가 품은 세로 여백이 별로 없다. 쉽게 말해 한글은 세로 속공간이 작다.

그래서 라틴에서 쓰는 행간(대개 1.4에서 1.5)을 한글에 그대로 주면, 글줄 사이 흰 공간이 글자의 세로 밀도에 비해 모자라서 줄이 안 벌어지고 답답하다. 라틴은 글자가 세로 여백을 스스로 대주지만, 한글은 안 대주니 그만큼을 행간이 바깥에서 더 채워줘야 한다. 이게 한글 본문 행간을 라틴보다 한 단계 넓게 잡는 이유다. 얼마나 넓힐지는 관례의 폭이 있어서, 접근성 기준과 정부 디자인 시스템은 1.5를 하한으로 두고 CJK 조판을 다루는 곳은 1.7 언저리를 권한다. 이 블로그는 장문을 느긋하게 읽히려고 그보다 살짝 위인 1.8을 골랐다. 절대 상수가 아니라 이 블로그의 선택이다.

한글에는 세로 여백을 더 출렁이게 만드는 요인이 하나 더 있다. 받침이다. 받침이 있는 글자(, )는 초성·중성·종성이 세로로 삼사 단을 쌓아 칸을 위아래로 길게 채우고, 받침이 없는 글자(, )는 위쪽만 채우고 아래가 빈다. 그래서 한 줄 안에서도 글자마다 세로로 차는 정도가 들쭉날쭉하다. 행간이 좁으면, 받침이 아래로 뻗은 글자와 그 밑 줄의 초성이 시각적으로 가까워지는 자리가 생겨 줄 사이 간격이 고르지 않게 좁아 보인다. 행간을 넉넉히 주면 이 출렁임을 흡수해서 줄 사이가 어디서나 고르게 유지된다. 한글이 라틴보다 행간에 더 민감한 숨은 이유가 이 받침의 세로 출렁임이다.

라틴한글몸통만 채움 → 여백 품음꽉 참 → 행간 더 벌려야
라틴 소문자는 몸통만 채우고 어센더·디센더 자리를 비워 세로 여백(파랑)을 스스로 품지만, 한글은 네모틀을 위아래로 꽉 채워 세로 속공간이 작다. 그만큼을 행간이 바깥에서 채워야 한다.

물론 행간은 속공간만으로 정해지지 않는다. 줄이 길수록 눈이 다음 줄 앞으로 되돌아오는 거리가 멀어져 행간을 더 벌려야 하는데, 이 measure와의 관계는 5편에서 다뤘다. 여기서 더한 건, 그 행간의 출발점 자체를 한글의 작은 세로 속공간이 이미 위로 밀어 올려놓았다는 것이다.

.markdown {
  line-height: 1.8; /* 세로 속공간이 작아 라틴보다 위에서 시작한다 */
}

지금까지의 값을 직접 만져 보자. 자간을 음수로 밀면 사이가 속공간만큼 좁아져 글자가 뭉개지고, 행간을 줄이면 줄이 답답해진다. ‘글자 칸 보기’를 켜면 자간이 조절하는 글자 곁 공간이 눈에 보인다.

글자 안의 흰 공간이 자간과 행간을 정한다. 값을 밀고 당겨 흰 공간의 리듬이 어떻게 바뀌는지 직접 보자.

한글 본문 기본값은 자간 0, 행간 1.8. 여기서 왜 그렇게 갈리는지 직접 만져 보자.

자간은 글자 곁 공간(사이드베어링)에 얹혀 사이를 늘리고 줄인다. 음수로 너무 줄이면 사이가 속공간만큼 좁아져 뭉갠다. 행간은 줄과 줄 사이를 벌린다.

커닝은 무슨 일을 하나

커닝은 자간의 사촌이지만 하는 일이 다르다. 자간이 모든 글자 사이를 한꺼번에 밀거나 당긴다면, 커닝은 특정 글자쌍 하나만 콕 집어 사이를 좁히거나 벌린다. 목적은 같다. 위계를 지키는 것, 곧 어떤 쌍에서 유독 튀는 글자사이를 주변과 고르게 되돌리는 것이다.

라틴에서 커닝이 중요한 이유는 글자 모양이 제각각이기 때문이다. AV를 나란히 놓으면 두 사선이 서로 등을 지고 벌어져, 그 쌍 사이에만 흰 공간이 툭 커진다. 위계로 보면 그 한 쌍의 글자사이가 낱말사이만큼 벌어져, 낱말이 거기서 갈라져 보인다. ToWe도 마찬가지다. 그래서 라틴 폰트는 이런 쌍마다 얼마씩 당길지를 커닝 테이블에 미리 적어두고, 브라우저가 그걸 읽어 자동으로 보정한다.

한글 본문에서는 이 일이 거의 필요 없다. 네모틀이 고정폭이라, 어떤 글자와 어떤 글자가 만나도 네모 옆에 네모가 붙는 꼴이라 사이 흰 공간이 튀지 않는다. AV처럼 특정 쌍만 벌어지는 사고가 안 난다. 그 고른 간격을 폰트가 이미 칸 설계로 맞춰놨다. 5편에서 네모틀 안에서 조정이 미리 끝나 있다고 스친 게 바로 이것이다. 라틴이 커닝 테이블로 하는 일을, 한글은 네모 칸 설계가 통째로 대신하고 있는 셈이다.

그럼 한글에서 커닝이 고개를 드는 자리는 어디인가. 세 곳이다. 첫째, 큰 제목이나 로고. 글자가 커지면 아주 미세한 불균형도 눈에 걸려서, 특정 쌍을 손으로 조여준다. 둘째, 한글 사이에 라틴 글자와 숫자, 문장부호가 섞여 들어오는 자리. 여는 괄호 (나 따옴표 뒤, 마침표 다음처럼 한쪽이 비어 보이는 지점은 간격이 튄다. 셋째, 네모틀을 벗어난 탈네모틀 폰트. 글자 폭이 들쭉날쭉해지는 만큼 커닝 여지가 생긴다.

CSS에서 이걸 만지는 손잡이는 몇 개인데, 자주 헷갈리니 구분해두자.

/* font-kerning: 폰트에 내장된 커닝 테이블을 켤지(기본 auto) 끌지(none) */
.title { font-kerning: auto; }

/* 같은 걸 저수준 OpenType 기능으로 켜는 방법. 요즘은 위 한 줄로 충분 */
.title { font-feature-settings: "kern" 1; }

/* 주의: letter-spacing은 커닝이 아니다. 특정 쌍이 아니라
   모든 글자 사이를 일괄로 미는 자간이다 */
.title { letter-spacing: -0.01em; }

여기서 제일 흔한 오해를 짚자. 웹에서 커닝을 하고 싶다며 본문에 letter-spacing 음수를 주는 경우가 많은데, 그건 커닝이 아니다. 특정 쌍만 고르는 게 커닝이고, letter-spacing은 모든 글자 사이를 똑같이 당기는 자간이다. 그리고 앞에서 봤듯 한글 본문에 음수 자간을 일괄로 주는 건 작은 속공간을 뭉개 위계를 깨는 바로 그 행위다.

그래서 한글 웹 본문에서 커닝의 실무 결론은 싱겁다. 손댈 게 거의 없다. font-kerning은 기본값 그대로 두면 되고, 한글 폰트는 네모틀 특성상 글자쌍 커닝에 기댈 일이 적어 켜도 본문에서 체감 차이가 크지 않은 경우가 많다. 제목이나 문장부호가 섞인 자리에서 특정 쌍이 거슬릴 때만 국소적으로 손보고, 본문 전체에 letter-spacing을 커닝인 척 두르지 않는다. 그게 전부다.

정리

속공간 하나를 쥐면 5편의 값들이 다시 읽힌다.

자간 0     : 한글은 속공간이 작아 글자사이를 더 줄일 여유가 없다
행간 1.8   : 세로 속공간이 작아 줄사이를 바깥에서 더 대줘야 한다
커닝 최소  : 네모틀이 커닝의 일을 칸 설계로 이미 끝내놨다

세 결정이 따로 노는 규칙이 아니라 하나의 원리에서 갈라져 나온다. 흰 공간에는 위계가 있고, 그 맨 안쪽 기준이 속공간이다. 한글은 속공간이 작으니, 안쪽 공간은 건드리지 말고(자간은 0, 커닝은 최소로) 대신 바깥쪽 공간을 벌린다(행간을 넓게). 안을 조이면 뭉개지고, 밖을 안 벌리면 답답하다. 이 두 방향이 같은 하나의 사실, 곧 한글의 작은 속공간에서 나온다.

이 시리즈가 내내 했던 말을 여기서도 한다. 값을 외우지 말고 왜 그 값인지를 쥐라는 것이다. 자간 0과 행간 1.8을 외우는 대신 속공간의 위계를 쥐고 있으면, 폰트가 바뀌고 화면이 바뀌어도 그 자리에서 다시 값을 찍어낼 수 있다. 흰 공간을 배열하는 눈, 그게 조판이다.

이 글, 어떠셨어요?