word-break: break-word는 비추천입니다 — overflow-wrap: anywhere로 전환해야 하는 이유

2026-03-18 hit count image

word-break: break-word는 CSS 스펙에서 비추천(deprecated)된 레거시 속성입니다. 대안인 overflow-wrap: break-word도 intrinsic sizing 요소에서 동작하지 않는 함정이 있습니다. 올바른 대체 조합(overflow-wrap: anywhere + word-break: normal + line-break: strict)과 Stylelint 커스텀 플러그인을 통한 자동화 방법을 공유합니다.

web

개요

지금까지 긴 문자열이 컨테이너를 뚫고 나가는 문제를 해결하기 위해 word-break: break-word를 적용했습니다. 그런데 최근에 이 속성이 비추천(deprecated)이라는 것을 알게 되었습니다. MDN 공식 문서에 따르면, word-break: break-wordoverflow-wrap: anywhereword-break: normal을 조합한 것과 동일한 효과를 가지는 레거시 값으로, deprecated로 명시되어 있습니다.

이에 따라 overflow-wrap: break-word로 변경했더니, 특정 요소에서 줄바꿈이 동작하지 않는 현상이 발생했습니다.

원인을 조사한 결과, overflow-wrap: break-wordoverflow-wrap: anywhere의 미묘하지만 중요한 차이를 발견했습니다. 이번 글에서는 그 원인 분석과 해결 방법, 그리고 Stylelint 커스텀 플러그인을 통해 검사와 수정 방법 추천을 자동화하는 과정에 대해서 공유합니다.

Stylelint 설정에 관해서는 다음 글을 참고하세요.

overflow-wrap이란?

overflow-wrap은 컨테이너를 넘치는 긴 문자열을 강제로 줄바꿈하는 안전장치입니다. 평소에는 아무 일도 하지 않고, 넘칠 때만 작동합니다.

영어의 경우

일반적인 영어 문장은 다음과 같이 overflow-wrap과 관계없이 스페이스에서 자연스럽게 줄바꿈됩니다.

This is a sample
text for testing
word wrap behavior.

하지만 URL이나 시리얼넘버처럼 스페이스 없이 이어지는 긴 문자열은 넘침이 발생합니다. 이때 overflow-wrap을 설정한 경우, 넘치는 지점에서 강제로 줄바꿈합니다.

  • overflow-wrap 없음
https://example.com/very/long/path/to/resource  ← 넘침!
  • overflow-wrap 있음
https://example.co
m/very/long/path/t
o/resource

break-word와 anywhere의 차이

overflow-wrap의 두 값인 break-wordanywhere눈에 보이는 줄바꿈 결과는 동일합니다.

// break-word
Password:
aB3$kL9mNpQrStUvWx
Yz1234567890abcdef

// anywhere
Password:
aB3$kL9mNpQrStUvWx
Yz1234567890abcdef

차이는 **레이아웃 계산(min-content)**에서 발생합니다.

  • break-word: min-content 계산 시 줄바꿈 기회를 고려하지 않습니다. 즉, 단어 전체 폭이 최소 폭이 됩니다.
  • anywhere: min-content 계산 시 줄바꿈 기회를 고려합니다. 즉, 한 글자 폭까지 줄어들 수 있습니다.

MDN 공식 문서에서도 이 차이를 명확하게 설명하고 있습니다:

  • anywhere: “Soft wrap opportunities introduced by the word break are considered when calculating min-content intrinsic sizes.”
  • break-word: “Soft wrap opportunities introduced by the word break are NOT considered when calculating min-content intrinsic sizes.”

출처: MDN - overflow-wrap

이 차이가 바로 break-word가 특정 요소에서 동작하지 않는 원인이 됩니다.

break-word가 동작하지 않는 원인

문제의 요소에는 display: inline-block이 적용되어 있었습니다.

inline-block은 콘텐츠에 맞춰 크기가 결정되는 intrinsic sizing 요소입니다.

이 요소의 너비는 min-content를 기반으로 결정됩니다. 앞서 설명한 min-content 계산의 차이가 여기서 문제를 일으킵니다.

  • inline-block + break-word인 경우
min-content = 단어 전체 폭 (260px)
→ 요소가 260px로 넓어짐
→ 넘침이 발생하지 않음
→ break-word가 트리거되지 않음
→ 줄바꿈 안 됨!
  • inline-block + anywhere인 경우
min-content = 한 글자 폭 (~8px)
→ 부모에 맞춰 너비가 제한됨
→ 넘침 발생
→ 줄바꿈 발생!

정리하면, break-word는 “넘칠 때만 줄바꿈”하는데, intrinsic sizing 요소의 min-content 계산에 줄바꿈 기회를 포함하지 않으므로 요소 자체가 넓어져서 넘침 자체가 발생하지 않게 됩니다. 결국 줄바꿈이 트리거되지 않는 것입니다.

같은 문제가 발생하는 CSS 속성들

inline-block 외에도 intrinsic sizing을 사용하는 CSS 속성은 모두 동일한 문제가 발생합니다.

CSS 속성이유
display: inline-block콘텐츠에 맞춰 너비 결정
display: inline-flexinline-level flex container
display: inline-gridinline-level grid container
display: table-cell콘텐츠 기반 너비
float: left / rightshrink-to-fit
position: absolute / fixed (width 미지정)shrink-to-fit
width: min-content / fit-content명시적 intrinsic sizing

이런 속성들은 모두 콘텐츠에 맞춰 너비가 결정되기 때문에, break-word의 min-content 계산 방식으로 인해 줄바꿈이 동작하지 않게 됩니다.

권장하는 CSS 조합

이 문제를 해결하기 위해 다음 3개의 CSS 속성을 함께 사용하는 것을 권장합니다.

overflow-wrap: anywhere;
word-break: normal;
line-break: strict;

각 속성의 역할

overflow-wrap: anywhere

긴 문자열이 컨테이너를 넘지 않도록 강제 줄바꿈합니다. break-word와 달리 min-content 계산에 줄바꿈 기회를 포함하므로, intrinsic sizing 요소에서도 정상적으로 동작합니다.

word-break: normal

기본 단어 분리 규칙을 사용합니다. 영어는 스페이스에서, 일본어, 중국어(CJK)에서는 문자 단위로 줄바꿈합니다. 기본값이므로 생략할 수 있지만, 이전에 word-break: break-word가 적용되어 있던 곳에서는 명시적으로 추가하여 의도를 명확히 하는 것이 좋습니다.

word-break의 각 값에 따른 동작 차이는 다음과 같습니다:

영어일본어, 중국어(CJK)
normal단어 단위 줄바꿈문자 단위 줄바꿈
break-all문자 단위 줄바꿈normal과 동일
keep-allnormal과 동일단어 단위 줄바꿈 (넘침 위험)

line-break: strict

일본어 금칙처리(禁則処理)를 엄격하게 적용합니다. 행의 시작에 오면 안 되는 문자( 등)를 제어하여 더 자연스러운 텍스트를 만듭니다.

  • strict 없음 → 「々」가 행두에 옴 (부자연스러움)
そこは湖のほ
とりで木
々が輝いてい
  • strict 있음 → 「木々」를 함께 유지 (자연스러움)
そこは湖の
ほとりで
木々が輝い

영어에는 실질적 영향이 없으므로 함께 적용해도 부작용이 없습니다.

참고:

3개 속성의 결합 효과

영어 텍스트의 경우:

# 입력: "Visit this link: https://example.com/very/long/path/to/resource"

Visit this link:      ← word-break: normal (스페이스에서 줄바꿈)
https://example.co    ← overflow-wrap: anywhere (넘치는 지점에서 강제 줄바꿈)
m/very/long/path/t
o/resource

일본어 텍스트의 경우:

# 입력: "デバイスID: ABCDEFGHIJKLMNOPQRSTUVWXYZ を確認してください。"

デバイスID:           ← word-break: normal (CJK 문자 단위 줄바꿈)
ABCDEFGHIJKLMNOPQR   ← overflow-wrap: anywhere (영문 강제 줄바꿈)
STUVWXYZを確認し
てください。          ← line-break: strict (「。」가 행두에 오지 않음)

anywhere로 통일해도 되는가?

break-wordanywhere의 시각적 줄바꿈 결과는 동일하고, 차이는 min-content 계산뿐입니다.

anywhere로 통일했을 때 이론적으로 flex/grid/table 레이아웃에서 공간 배분이 달라질 수 있습니다. anywhere는 min-content가 한 글자 폭까지 줄어들 수 있으므로, flex item이 예상보다 작게 축소되거나 grid 트랙이 좁아지는 경우가 있을 수 있습니다.

하지만 실무에서 이것이 문제가 되는 경우는 거의 없습니다. 그 이유는 다음과 같습니다:

  • min-content는 하한값일 뿐입니다. 실제 렌더링 너비는 flex-basis, width, grid-template-columns 등 다른 속성에 의해 결정됩니다. min-content가 작아졌다고 해서 요소가 바로 그 크기로 줄어드는 것이 아닙니다.
  • flex 레이아웃에서는 flex-grow/flex-shrink가 공간을 배분합니다. 대부분의 flex item은 flex: 1이나 고정 flex-basis를 가지고 있어, min-content 차이가 최종 너비에 영향을 미치지 않습니다. min-content가 관여하는 것은 item이 더 이상 줄어들 수 없는 최소 한계를 결정할 때뿐입니다.
  • grid 레이아웃에서도 트랙 크기가 명시적으로 지정됩니다. grid-template-columns: 1fr 2fr이나 minmax(200px, 1fr) 같은 선언이 일반적이므로, min-content가 달라져도 트랙 크기에 영향을 주지 않습니다. min-content 키워드를 트랙 크기로 직접 사용하는 경우에만 차이가 생길 수 있지만, 이는 드문 패턴입니다.
  • 테이블에서는 table-layout: fixed가 일반적입니다. 고정 레이아웃에서는 셀 내용이 아닌 열 너비 선언에 따라 크기가 결정되므로 min-content 차이가 무시됩니다. table-layout: auto(기본값)에서만 영향이 있을 수 있지만, 이 경우에도 텍스트가 길어서 넘치는 문제보다는 적절히 줄바꿈되는 것이 더 나은 결과를 줍니다.

오히려 break-word를 사용하면 앞서 살펴본 것처럼 intrinsic sizing 요소에서 줄바꿈이 동작하지 않는 실질적인 버그가 발생합니다. 따라서 anywhere로 통일하는 것이 안전합니다.

word-break: break-word는 왜 비추천인가?

word-break: break-word는 CSS3 사양에서 정식으로 정의된 값이 아닙니다. 원래 overflow-wrap: break-word의 레거시 별칭(legacy alias)으로 브라우저들이 호환성을 위해 지원해 왔습니다. CSS Text Level 3 스펙에서도 이 값을 비추천으로 명시하고 있으며, overflow-wrap: anywhere를 대신 사용할 것을 권장하고 있습니다.

Stylelint 커스텀 플러그인으로 자동화

이 규칙을 개발자가 매번 기억하기는 어렵습니다. 그래서 Stylelint의 커스텀 플러그인을 만들어 자동으로 감지하고, 에러 메시지와 함께 올바른 대체 조합을 안내하도록 설정했습니다.

Stylelint 설정에 관해서는 다음 글을 참고하세요.

감지 규칙

감지 대상에러 메시지
overflow-wrap: break-word기대대로 줄바꿈되지 않는 케이스가 있으므로 비추천 → 3개 세트 안내
word-break: break-word비추천(deprecated) → 3개 세트 안내
overflow-wrap: anywhere + line-break: strict 없음line-break: strict를 추가하세요’로 안내

플러그인 코드

프로젝트 루트에 plugins/require-strict-wrap-rules.js 파일을 생성하고 다음과 같이 작성합니다.

'use strict';

const stylelint = require('stylelint');

const ruleName = 'custom/require-strict-wrap-rules';

const REPLACEMENT =
  ' 대신 "overflow-wrap: anywhere; word-break: normal; line-break: strict;"를 사용하세요.';

const messages = stylelint.utils.ruleMessages(ruleName, {
  rejectedOverflowWrapBreakWord:
    '"overflow-wrap: break-word"는 기대대로 줄바꿈되지 않는 케이스가 있어 비추천(deprecated)입니다.' +
    REPLACEMENT,
  rejectedWordBreakBreakWord:
    '"word-break: break-word"는 비추천(deprecated)입니다.' + REPLACEMENT,
  rejectedLineBreak:
    'overflow-wrap: anywhere를 사용하는 경우 "line-break: strict"도 함께 지정하세요' +
    '(일본어 금칙처리를 위해 필요합니다).',
});

const ruleFunction = (primary) => {
  return (root, result) => {
    const validOptions = stylelint.utils.validateOptions(result, ruleName, {
      actual: primary,
      possible: [true],
    });

    if (!validOptions) return;

    root.walkRules((rule) => {
      let anywhereNode = null;
      let hasLineBreakStrict = false;

      rule.walkDecls((decl) => {
        if (decl.prop === 'overflow-wrap' && decl.value === 'break-word') {
          stylelint.utils.report({
            message: messages.rejectedOverflowWrapBreakWord,
            node: decl,
            result,
            ruleName,
          });
        }
        if (decl.prop === 'word-break' && decl.value === 'break-word') {
          stylelint.utils.report({
            message: messages.rejectedWordBreakBreakWord,
            node: decl,
            result,
            ruleName,
          });
        }
        if (decl.prop === 'overflow-wrap' && decl.value === 'anywhere') {
          anywhereNode = decl;
        }
        if (decl.prop === 'line-break' && decl.value === 'strict') {
          hasLineBreakStrict = true;
        }
      });

      if (anywhereNode && !hasLineBreakStrict) {
        stylelint.utils.report({
          message: messages.rejectedLineBreak,
          node: anywhereNode,
          result,
          ruleName,
        });
      }
    });
  };
};

ruleFunction.ruleName = ruleName;
ruleFunction.messages = messages;

module.exports = stylelint.createPlugin(ruleName, ruleFunction);

Stylelint 설정

프로젝트 루트의 .stylelintrc.json 파일에 플러그인과 규칙을 추가합니다.

{
  "plugins": ["./plugins/require-strict-wrap-rules.js"],
  "rules": {
    "custom/require-strict-wrap-rules": true
  }
}

실행 결과

이렇게 설정한 규칙을 적용하여, Stylelint를 실행하면 다음과 같은 에러 메시지가 출력됩니다.

  • overflow-wrap: break-word 사용 시
 "overflow-wrap: break-word" 기대대로 줄바꿈되지 않는 케이스가 있어 비추천입니다.
  대신 "overflow-wrap: anywhere; word-break: normal; line-break: strict;" 사용하세요.
  • word-break: break-word 사용 시
 "word-break: break-word" 비추천(deprecated)입니다.
  대신 "overflow-wrap: anywhere; word-break: normal; line-break: strict;" 사용하세요.
  • overflow-wrap: anywhere에서 line-break: strict 누락 시
 overflow-wrap: anywhere를 사용하는 경우 "line-break: strict" 함께 지정하세요
  (일본어 금칙처리를 위해 필요합니다).

마무리

CSS의 줄바꿈 속성은 비슷해 보이지만 미묘한 차이가 있어 의도대로 동작하지 않는 경우가 있습니다. 이번 글에서 다룬 내용을 정리하면 다음과 같습니다.

비추천권장
word-break: break-wordoverflow-wrap: anywhere
overflow-wrap: break-wordword-break: normal
line-break: strict
  • overflow-wrap: anywherebreak-word와 달리 intrinsic sizing 요소(inline-block, inline-flex, float 등)에서도 정상적으로 동작합니다.
  • word-break: normal은 영어와 일본어(CJK) 모두에서 가장 자연스러운 줄바꿈을 제공합니다.
  • line-break: strict는 일본어 금칙처리를 엄격하게 적용하여 텍스트 품질을 높입니다.
  • Stylelint 커스텀 플러그인으로 이 규칙을 자동화하면 개발자가 매번 기억할 필요가 없습니다.

참고

제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!

앱 홍보

책 홍보

블로그를 운영하면서 좋은 기회가 생겨 책을 출판하게 되었습니다.

아래 링크를 통해 제가 쓴 책을 구매하실 수 있습니다.
많은 분들에게 도움이 되면 좋겠네요.



SHARE
Twitter Facebook RSS