같은 문장을 좁은 화면에 넣었을 때, 기본값에서는 "막힌"이 "막"과 "힌"으로 쪼개지고 word-break keep-all을 주면 단어가 통째로 다음 줄로 넘어가는 비교 화면.

·7분 읽기·업데이트:

영어권 템플릿 그대로 쓰다가 한글에서 깨진 것들


지난 글에서 배포하다 막힌 다섯 곳에 대해 썼습니다. 그건 하루면 끝나는 종류의 문제였습니다. 오래 붙잡고 있었던 건 오히려 그다음이었어요.

블로그가 뜨고 나서 화면을 계속 들여다보는데 뭔가 어색했습니다. 어디가 이상한지 딱 집어 말하기 어려운 종류의 어색함이요. 며칠을 보고 나서야 알았습니다. 전부 한글 때문이었습니다.

제가 쓴 템플릿은 영어권에서 만든 겁니다. 영어를 넣으면 아무 문제가 없어요. 한글을 넣는 순간 티가 납니다. 그리고 이런 건 아무도 알려주지 않습니다. 템플릿 문서에도 없고, 에러도 안 납니다. 그냥 조금 이상해 보일 뿐입니다.

네 가지였습니다.

1. 단어가 아무 데서나 잘린다

블로그 목록의 카드 제목을 보다가 발견했습니다. “막힌”이 “막”과 “힌”으로 쪼개져 두 줄에 걸쳐 있었습니다.

버그가 아닙니다. 브라우저가 정상적으로 동작한 결과예요. 브라우저는 한중일 문자를 어느 글자 사이에서든 줄을 바꿔도 되는 문자로 봅니다. 실제로 중국어와 일본어는 그게 맞습니다. 띄어쓰기가 없으니까요.

한국어만 다릅니다. 한글은 띄어쓰기가 있고, 사람은 어절 단위로 읽습니다. 그런데 브라우저 입장에서 한글은 그냥 CJK 문자일 뿐이라 같은 규칙을 적용합니다.

body {
  word-break: keep-all;
  overflow-wrap: break-word;
}

keep-all은 “단어 중간에서 끊지 마”라는 뜻입니다. 이것만 쓰면 함정이 하나 있습니다. 띄어쓰기 없는 긴 문자열, 예를 들어 URL이 들어오면 화면 밖으로 그대로 뚫고 나갑니다. overflow-wrap: break-word를 같이 써야 “평소엔 어절 단위로, 도저히 안 되면 그때만 잘라라”가 됩니다.

두 줄입니다. 그런데 이 두 줄이 한글 블로그의 인상을 꽤 많이 바꿉니다.

2. 날짜와 태그의 한글만 자간이 벌어진다

날짜와 태그를 고정폭 글꼴로 지정해뒀습니다. 숫자가 가지런히 서서 보기 좋거든요. 그런데 “2026년 9월 1일”에서 숫자는 멀쩡한데 “년”, “월”, “일”만 어색하게 벌어져 보였습니다.

원인을 알고 나면 당연합니다. Consolas나 Menlo 같은 서양 고정폭 글꼴에는 한글이 없습니다. 만든 사람들이 한글까지 그릴 이유가 없었으니까요. (D2Coding처럼 한글까지 넣어 만든 고정폭 글꼴은 따로 있습니다.)

여기서 브라우저가 하는 일이 재미있습니다. 글꼴은 문단 단위가 아니라 글자 하나하나마다 다시 고릅니다.

글꼴 스택에서 숫자는 첫 번째 고정폭 글꼴에서, 한글은 그 글꼴들을 모두 건너뛰고 Pretendard에서 가져오는 과정을 보여주는 도식

“2”를 그릴 때는 목록 맨 앞의 ui-monospace에 그 글자가 있으니 거기서 멈춥니다. “년”을 그릴 때는 앞의 고정폭 글꼴들에 그 글자가 없으니 계속 뒤로 넘어갑니다. 그리고 제 스택은 거기서 끝나 있었습니다. 그래서 브라우저가 알아서 시스템 기본 한글 글꼴을 골랐고, 그게 앞의 숫자들과 어울리지 않았던 겁니다.

해결은 스택 뒤에 한글 글꼴을 하나 얹는 것이었습니다.

--mono: ui-monospace, SFMono-Regular, Menlo, Consolas,
        'Pretendard Variable', sans-serif;

숫자와 영문은 앞쪽 고정폭에서, 한글은 Pretendard에서. 한 줄에 두 가지 글꼴을 섞어 쓰는 셈인데 티가 안 납니다.

3. 날짜가 영어로 나온다

이건 부끄러운 축입니다. 템플릿에 이렇게 박혀 있었어요.

date.toLocaleDateString('en-us', { year: 'numeric', month: 'short', day: 'numeric' })

그래서 한국어로 쓴 글에 “Aug 30, 2026”이 붙어 있었습니다. 며칠을 봤는데도 못 알아챘습니다. 워낙 익숙한 형식이라 그냥 넘어갔던 것 같습니다.

date.toLocaleDateString('ko-KR', { year: 'numeric', month: 'long', day: 'numeric' })

'ko-KR' 하나 바꾸니 “2026년 8월 30일”이 됐습니다. 한국어 사이트에 영어 날짜가 섞여 있으면, 딱히 뭐라고 말하기는 어려운데 번역이 덜 끝난 사이트 같은 인상을 줍니다.

4. 읽는 시간이 엉터리로 나온다

글 위에 “몇 분 읽기”를 붙이고 싶었습니다. 검색해보면 계산법이 나옵니다. 영어권 방식은 이렇습니다.

const words = text.split(/\s+/).length;
const minutes = Math.round(words / 200);

띄어쓰기로 잘라 단어 수를 세고, 분당 200단어로 나눕니다. 영어에서는 잘 맞습니다.

한국어에 그대로 쓰면 안 됩니다. “나는 오늘 블로그를 만들었다”는 4단어입니다. 같은 뜻의 영어 문장은 7단어쯤 되고요. 게다가 한국어는 조사가 붙어서 어절 길이가 제각각입니다. “글을”과 “만들어보려고”가 똑같이 1단어로 세어집니다.

그래서 단어가 아니라 글자 수로 셌습니다.

export function estimateReadingMinutes(markdown: string): number {
  const charCount = markdown.replace(/\s+/g, '').length;
  return Math.max(1, Math.round(charCount / 500));
}

공백을 다 지우고 글자 수를 센 다음 분당 500자로 나눕니다. 한국어 읽기 속도는 보통 분당 500자에서 700자 사이로 이야기되는데, 저는 넉넉하게 500으로 잡았습니다. 실제보다 조금 길게 나오는 편이 낫다고 봤어요. “3분 읽기”라고 해놓고 5분 걸리는 것보다는 나으니까요.

덤. 이건 한글 문제가 아니었다

같이 발견한 김에 하나 더 적습니다.

모바일에서 화면이 좌우로 미세하게 흔들렸습니다. 재보니 가로로 9px씩 삐져나가고 있었어요. 원인은 이겁니다.

main {
  width: 720px;
  max-width: calc(100% - 2em);
  padding: 1.5em 1.25em;
}

문제없어 보이지만, CSS는 기본적으로 width를 안쪽 여백을 뺀 값으로 계산합니다. 그러니까 max-width로 폭을 제한해놓아도 padding이 그 바깥에 따로 더해집니다. 계산해보면 딱 9px 초과였습니다.

*, *::before, *::after {
  box-sizing: border-box;
}

이 세 줄을 맨 위에 깔면 여백이 너비 안쪽으로 들어옵니다. 요즘 만들어진 CSS 프레임워크는 거의 다 기본으로 넣어두는데, 제가 쓴 템플릿에는 없었습니다.

정리

네 가지 다 에러가 아니었습니다. 브라우저도 템플릿도 각자 자기 일을 정상적으로 했어요. 다만 그 기본값이 영어를 기준으로 정해져 있었을 뿐입니다.

한글로 뭔가를 만들 때는 기본값을 한 번씩 의심해보는 게 좋겠다는 걸 배웠습니다. 특히 줄바꿈, 글꼴, 날짜, 글자 수처럼 언어에 따라 답이 달라지는 것들이요.

다음에는 NAS로 백업 붙이는 이야기를 쓸까 합니다. 아직 안 해놔서, 하고 나서요.

고친 곳

2026년 9월 29일, 글에 붙일 참고 문서를 하나씩 다시 열어보다가 본문과 어긋나는 곳을 찾아 고쳤습니다.

  • “고정폭 글꼴에는 한글이 없다”를 “서양 고정폭 글꼴에는”으로 좁혔습니다. 한글이 들어 있는 고정폭 글꼴도 있습니다.

참고한 문서


댓글

로그인도 이메일도 필요 없습니다. 이름만 적고 편하게 남겨주세요.