Technote

테마 · 플러그인 실무

연재 한글 웹 타이포그래피 8부 중 3부

keep-all 이 한글에 주는 것, 다른 언어에서 빼앗는 것

한글 어절이 중간에서 잘리는 문제는 CSS 한 줄로 해결됩니다. 그런데 그 한 줄은 공백이 없는 일본어 · 중국어에서 "끊을 자리가 없다"는 뜻이 되어 가로 스크롤을 만듭니다.

한글 본문을 좁은 칸에 넣으면 어절 한가운데서 줄이 바뀌는 일이 생깁니다. “최적화” 가 “최” 와 “적화” 로 갈리는 식입니다. 문법적으로는 아무 문제가 없지만, 읽는 사람은 한 덩어리로 인식하던 말이 쪼개지는 순간 흐름을 놓칩니다.

브라우저가 한글을 끊는 방식

기본값 word-break: normal에서 브라우저는 한중일 문자(CJK) 사이라면 어디서든 줄을 바꿀 수 있다고 봅니다. 중국어와 일본어에는 단어 사이 공백이 없어서 그렇게 하지 않으면 줄을 바꿀 수 없기 때문이고, 그 규칙 자체는 옳습니다. 문제는 한국어에는 공백이 있다는 점입니다. 어절이 이미 공백으로 구분돼 있는데 굳이 글자 사이에서 끊을 이유가 없습니다.

word-break: keep-all이 정확히 이 상황을 위한 값입니다. “단어 안에서는 끊지 않는다” 는 뜻이고, 한국어에서는 공백으로 구분된 어절이 통째로 유지됩니다.

한국어 화면에서 두 값의 차이 — 여기까지는 keep-all 이 명백히 낫다

그런데 일본어 · 중국어에는 공백이 없습니다

여기가 이 속성의 진짜 함정입니다. keep-all은 “단어 안에서 끊지 않는다” 는 규칙이고, 공백이 없는 언어에서는 문단 전체가 단어 하나가 됩니다. 즉 끊을 자리가 하나도 없다는 선언이 됩니다.

결과는 눈에 보이는 고장입니다. 문단이 한 줄로 쭉 늘어나 컨테이너를 뚫고, 그리드의 칸이 그 폭을 그대로 받아 부풀고, 페이지에 가로 스크롤이 생깁니다. 한국어와 영어 화면은 멀쩡하기 때문에 다국어를 켜 보기 전에는 드러나지 않습니다. 기계 번역 위젯을 붙이거나 일본어 페이지를 추가하는 날 처음 발견하게 됩니다.

함께 써야 하는 두 줄

해결은 keep-all을 버리는 것이 아니라 비상구를 함께 두는 것입니다.

body {
  word-break: keep-all;        /* 한글 어절을 지킨다 */
  overflow-wrap: anywhere;     /* 끊을 데가 없으면 어디서든 끊는다 */
}

.card-grid {
  display: grid;
  /* 1fr 이 아니라 minmax(0, 1fr) — 칸이 내용 때문에 부풀지 않게 */
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

overflow-wrap의 값으로 break-word가 아니라 anywhere를 쓰는 것이 핵심입니다. 두 값 모두 필요할 때 글자 사이에서 끊어 주지만, anywhere만이 요소의 최소 폭 계산에도 반영됩니다. break-word는 “이 문단은 최소 이만큼 넓어야 한다” 는 계산에서는 여전히 문단 전체를 한 덩어리로 보기 때문에, 그리드 칸이 부푸는 문제는 그대로 남습니다.

같은 이유로 그리드 트랙에 minmax(0, 1fr)을 씁니다. 1fr은 사실 minmax(auto, 1fr)이고, 그 auto내용의 최소 폭을 바닥으로 삼습니다. 긴 문단 · 코드 블록 · URL 하나가 그 바닥을 밀어 올리면 트랙이 함께 늘어납니다.

세 줄이 한 세트다 — 하나만 쓰면 다른 언어에서 무너진다

예외를 두는 자리

모든 요소에 같은 규칙을 줄 필요는 없습니다. 코드 블록과 URL은 중간에서 끊기면 오히려 읽을 수 없게 되므로, 줄바꿈 대신 가로 스크롤을 그 요소 안에만 두는 편이 낫습니다.

pre, code, .url {
  word-break: normal;
  overflow-wrap: normal;
  white-space: pre;
  overflow-x: auto;            /* 스크롤은 이 상자 안에서만 */
}

여유가 있다면 text-wrap: pretty(문단 끝 외톨이 단어 방지)와 text-wrap: balance(제목 줄 길이 균형)를 얹어도 좋습니다. 둘 다 지원하지 않는 브라우저에서는 아무 일도 일어나지 않으므로 안전하게 더할 수 있는 개선입니다.

레이아웃이 언어에 따라 무너지는 문제는 테마 · 플러그인 아카이브에서 더 다루고, 이미 운영 중인 사이트에서 이런 종류의 결함을 찾아내는 진단은 최적화 지원 사업에 포함돼 있습니다.

다음 회차

글자의 모양과 줄바꿈까지 정했으니, 이제 그 글자가 어떻게 도착하는가가 남았습니다. 다음 회차부터 세 편은 웹폰트입니다 — 먼저 자체 호스팅으로 무엇이 달라지는지부터 봅니다.

이 주제의 다른 글

노하우 목록으로

테마 · 플러그인 실무

편집 가능한 영역을 디자인 전에 정합니다

CMS 가 표현할 수 없는 디자인은 배포된 뒤에도 계속 협상 대상으로 남습니다. 어디까지 편집자가 바꿀 수 있는지를 먼저 정하면 그 협상 자체가 사라집니다.

디자이너 3분 읽기

테마 · 플러그인 입문

업데이트가 멈춘 플러그인을 판별하는 기준

마지막 업데이트 날짜 하나로는 방치를 판정할 수 없습니다. 판별 신호 다섯 개를 함께 보고, 대체 불가라면 격리 조건이라도 걸어야 합니다.

기획자 · 운영 · 관리자 2분 읽기

테마 · 플러그인 심화

JS 없이 만드는 상호작용과 그것을 안전하게 하는 규칙

details · :target · :focus-within · :has() · 스크롤 타임라인으로 상당수의 상호작용이 스타일시트 안에서 끝납니다. 안전하게 만드는 규칙은 하나입니다 — 기본값이 완성된 상태여야 합니다.

디자이너 6분 읽기

₩270,000 · 신청하기