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の2つの値であるbreak-wordanywhereは、見た目の折り返し結果は同一です。

// break-word
Password:
aB3$kL9mNpQrStUvWx
Yz1234567890abcdef

// anywhere
Password:
aB3$kL9mNpQrStUvWx
Yz1234567890abcdef

違いは**レイアウト計算(min-content)**で発生します。

  • break-word: min-content計算時に折り返し機会を考慮しません。つまり、単語全体の幅が最小幅になります。
  • anywhere: min-content計算時に折り返し機会を考慮します。つまり、1文字幅まで縮小できます。

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 = 1文字幅 (~8px)
→ 親に合わせて幅が制限される
→ はみ出し発生
→ 折り返し発生!

まとめると、break-wordは「はみ出した時だけ折り返す」のですが、intrinsic sizing要素のmin-content計算に折り返し機会を含めないため、要素自体が広がってはみ出し自体が発生しなくなります。結果として折り返しがトリガーされないのです。

同じ問題が発生するCSS属性

inline-block以外にもintrinsic sizingを使用するCSS属性はすべて同じ問題が発生します。

CSS属性理由
display: inline-blockコンテンツに合わせて幅決定
display: inline-flexinline-level flexコンテナ
display: inline-gridinline-level gridコンテナ
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が1文字幅まで縮小できるため、flex itemが予想より小さく縮小したり、gridトラックが狭くなる場合があり得ます。

しかし、実務でこれが問題になることはほとんどありません。その理由は以下の通りです:

  • min-contentは下限値に過ぎません。 実際のレンダリング幅はflex-basiswidthgrid-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 2frminmax(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" は期待通りに折り返されないケースがあるため非推奨です。' +
    REPLACEMENT,
  rejectedWordBreakBreakWord:
    '"word-break: break-word" は非推奨です。' + 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" は非推奨です。
  代わりに "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-blockinline-flexfloatなど)でも正常に動作します。
  • word-break: normalは英語と日本語(CJK)の両方で最も自然な折り返しを提供します。
  • line-break: strictは日本語の禁則処理を厳格に適用してテキスト品質を高めます。
  • Stylelintカスタムプラグインでこのルールを自動化すれば、開発者が毎回覚える必要がなくなります。

参考

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

アプリ広報

今見てるブログを作成たDekuが開発したアプリを使ってみてください。
Dekuが開発したアプリはFlutterで開発されています。

興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。



SHARE
Twitter Facebook RSS