Help us understand the problem. What is going on with this article?

overflow-wrap: break-word; や word-break: break-all; が万能の改行処理だったなら、こんなに苦労していない

はじめに

今回解決したいのはこれです。
スクリーンショット 2020-01-20 21.44.22.png
overflow-wrapかけたのに改行されないしテーブルwidthもなんか勝手に伸ばされちゃってる問題」です。

こんなんHTML / CSSの初歩中の初歩じゃんwwwという方は、どうぞごゆるりとブラウザバックしてやってくださいませ…

「それ地味に悩んでた!」という方がもしいらっしゃいましたら、少しでも助けになれれば嬉しいです。というか一緒に悩みましょう。

あ、でも、もしそんな方が本当にいたら、こんなことに悩むよりも、
「全半角記号のブラウザテストだけ許容する」という呪文を唱えた方が5億倍早いです…というネタバレだけ先にしておきますね><

もくじ

当記事は、以下の内容に関するメモ書きです。

  • CSSの改行処理プロパティのメリデメ
  • 上記問題の暫定解決方法

対象のCSSプロパティは以下の通りです。

  • overflow-wrap: break-word;
  • word-wrap: break-word;
  • word-break: break-all;
  • word-break: break-word;

環境

記事のスクショは、下記環境で作成しています1

OS ブラウザ
MacOS 10.15 Chrome

overflow-wrap: break-word;

スクリーンショット 2020-01-22 23.56.05.png

こんな時にオススメ!:
「コンテナからなるべくはみ出したくはないけど…禁則処理2もなるべく入れたいし…英単語も可能な限り綺麗な状態で表示させたいなぁ〜!」という時。

メリット:

  • ブラウザ:Chrome, Edge, IE, FireFoxなど、主要ブラウザで対応
  • 禁則処理:可能な限り保たれる
  • コンテナ(テキストの表示領域)幅より長い英単語:強制的に折り返される
  • 記号の連続の折り返し:対応

デメリット:

  • テーブル内のセルでは適用されない…………(※詳細下記)

処理の詳細は、MDNのCSSリファレンスで以下のように定義されています。

インライン要素に対して、テキストが行ボックスをあふれないように、ブラウザーが不可分の文字列の途中で改行を入れるかどうかの設定を適用します。

下記サイトの説明がより分かりやすいです。

単語の途中で折り返さないと行ボックスの幅からあふれてしまうときのみ、その単語の途中で折り返します。単語の途中で折り返しが発生するのは、その単語の幅が行ボックスの幅より大きい場合のみとなります。つまり、可能な限り禁則処理が保持され、可能な限り単語途中での折り返しを避けることができます。
https://w3g.jp/blog/confusing_word-break_word-wrap より

overflow-wrap: break-word; は、「単語内改行をしないこと」より「コンテナ幅」を優先する設定です。次に入力される単語がコンテナ幅の残りを超えそうな場合、単語内で改行しないように単語ごと次の行に送る制御をします。

スクリーンショット 2020-01-23 0.01.22.png

上記の処理だけでは対応できない場合、例えば1語の長さがコンテナ幅を超えてしまう場合は、単語の途中で折り返すことを許容して、コンテナ幅に収めるという設定です。
たとえば、世界一長い地名Tetaumatawhakatangihangakoauaotamateaurehaeaturipukapihimaungahoronukupokaiwhenuaakitanarahuが入力されてコンテナを超えてしまうような場合、単語途中での折り返しが発生します。

逆に、「コンテナ幅」より「単語内改行をしないこと」を優先させたい場合は、overflow-wrap: normal; を設定します(デフォルトの値なので設定しなくても大丈夫です)。
Tetaumatawhakatangihangakoauaotamateaurehaeaturipukapihimaungahoronukupokaiwhenuaakitanarahuが入力された場合には、コンテナ幅をはみ出すことを許容して、単語内の改行を防ぐ結果になります。

スクリーンショット 2020-01-23 0.01.10.png

※ただし、overflow-wrap(word-wrap)プロパティはテーブル内のセルには使用できません

スクリーンショット 2020-01-23 0.06.34.png

詳しく言うと、overflow-wrap(word-wrap)プロパティはテキストの長さとコンテナ幅を計算して折り返し可否を決めていますが、テーブルのデフォルトCSS設定である自動レイアウトアルゴリズムtable-layout:auto;も、中身のテキストによってレイアウトを計算するプロパティです。
このため、重ね掛けするとoverflow-wrap(word-wrap)側の計算がうまく効かなくなってしまうようなのです。

word-wrap: break-word;

word-wrapプロパティはoverflow-wrapプロパティの前身です。
CSS3の仕様書では現在、後方互換性のためにoverflow-wrapプロパティを使用する実装者は対応するword-wrapプロパティも併記することを推奨しています。

いやテーブルで改行したいねんな!!!!

overflow-wrapword-wrapは正直すごい。天才。

日本語も英語も記号も良きところで良き感じに改行してくれる。もうこれがベストプラクティス。
いや普通の実装だったらほんとoverflow-wrap先生に任せて、副担にword-wrapおじいちゃんをつけておいてあげればまず間違いない。分かってる。

でもこれで満足する人間だったらQiita書いてないんだな。

今回の課題はこれです(再掲)。
スクリーンショット 2020-01-20 21.44.22.png
そんな天才的なoverflow-wrap先生をかけたのに改行されないし、テーブルwidthもなんか勝手に伸ばされちゃってる問題」です。

自動計算アルゴリズムかなんか知らんが、やってくれやがりましたな…

大体のフォームやアンケートや個人情報ページなどには、文字数確定部分だけじゃなくて自由記述欄もあったりするかと思うのですが、
生半可にテキスト文字数可変項目を含むテーブルを作ると、自由記述欄に!マークが100文字とか入ったらレイアウトが死ぬ可能性が発生しちゃう…

次に紹介するのは、そんな逆境で出会った、悪魔のようなプロパティです。
どうぞ。

word-break: break-all;

スクリーンショット 2020-01-22 23.44.54.png

こんな時にオススメ!:
死んでも絶対レイアウト崩したくねえ〜〜〜〜!!!!!!行頭の句読点とか気にしないし、英語とかマジぶつ切りになってもいいから、とにかく絶対にコンテナからはみ出させねえ(強い意志)」という時。

メリット:

  • ブラウザ:Chrome, Edge, IE, FireFoxなど、主要ブラウザで対応
  • コンテナ幅より長い英単語:強制的に折り返される

デメリット:

  • 禁則処理:ほとんど解除されてしまう
  • コンテナ幅より短い英単語で、単語全体を次の行に送れば途中で改行を防ぐことができる場合であっても、テキストがコンテナから溢れたところで強制的に折り返してしまう
  • 一部記号(!や?など)の連続に対応していない……

MDNのCSSリファレンスでは以下のように定義されています。

単語中などでの文字の改行に関する禁則処理を解除し、どの文字の間でも改行するようにします。

みんな大好きword-break: break-all;何があっても強制改行してくれます。心強い。
英単語が入るとめちゃめちゃ読みづらいのですが、正直日本語は単語の区切れ目でなくても改行できる言語なので、そんなに気にしなくても…(悪魔のささやき)
overflow-wrapword-wrapの細かいプロパティでこちゃこちゃ悩みたくねえ!!とにかく「単語内改行をしないこと」より「コンテナ幅」を最優先したい!という場合は、結局これを選んでしまうのです…(悪魔のささやき)
しかし禁則処理の(ほぼ)全解除なので、日本語でも句読点が行頭に来るなど、若干気になる人は気になる処理になってしまいます。

ちなみに、overflow-wrap(word-wrap): break-word;word-break: break-all; を重ね掛けした場合は、word-break: break-all; が優先されてしまうそうです。圧倒的パワー。

何があっても強制改行と言ったな?あれは嘘だ

さて、禁則処理や英語をかなぐり捨てて「「「力」」」を手に入れた我々なので、きっと理想のテーブルが出来上がったことでしょう!!!!
スクリーンショット 2020-01-20 22.31.32.png
そうですね、無情ですね。

詳しい理由は分かりませんが、CSS3の仕様書でも、word-break: break-all;は以下のように説明されています。

Breaking is allowed within “words”
(「語句」内での改行を行う)

stackoverflowでも「記号$がword-break: break-all;で改行されない」という質問に対して、以下のような回答がついています。

ユニコードで「文字」「数字」ではなく「記号」として分類されているものは、禁則処理が弱いのでは

word-break: break-all; でも、テーブル内で一部記号の連続を改行することは難しいのかな…
としょげたその時、

天使が現れました。

word-break: break-word;

はい天才。完成。
スクリーンショット 2020-01-23 0.18.36.png

こんな時にオススメ!:
IEとEdgeは捨てた。改行させてくれ

メリット:

  • 禁則処理:可能な限り保たれる!
  • コンテナ(テキストの表示領域)幅より長い英単語:強制的に折り返される!!
  • 記号の連続の折り返し:対応!!!
  • テーブル内のセルにかけてもちゃんと効く!!!!

デメリット:

  • ブラウザ:IEとEdgeには非対応

公式では以下のように定義されています。

行内で適切に改行できる場所が他にない場合に限って、単語の途中でも改行するようにします。
https://developer.mozilla.org/ja/docs/Web/CSS/word-breakより)

いやこれがマジでやりたかった(なおIEとEdgeは非対応)。
これがマジでやりたかったんだが、word-breakプロパティの中でもなぜかこれだけIEとEdge非対応なんだな…………
IEとEdgeのことだけ都合よく記憶喪失になった人にだけ使用が許される、天使のように天真爛漫純粋無垢かつ無情なプロパティ。

暫定解決方法

このようにいろいろ試行錯誤しまして、以下条件での暫定の解決方法を見つけました。

  • 主要ブラウザ(Chrome, FireFox, IE, Edge)対応
  • 英語や句読点にはなるべく禁則処理を入れたい
  • コンテナ幅を超える英単語だけは単語の途中で折り曲げても良い
  • 記号の連続も折り返したい
  • とにかく枠を広げたくない

無理やろ…と思いましたが、案外いけたんですよね。

スクリーンショット 2020-01-20 23.36.31.png

tdの中にdivを作成し、クラス属性に以下を設定する

  • width
  • overflow-wrap: break-word;

これだけでした。なんて簡単なんだ…divだったのか…
tdにwidth, overflow-wrap: break-word;を直接指定してもうまくいかなかったです。table-layout: auto;のせいですかね…

おわりに

試行錯誤してやっと見つけたわりにはしょぼい解決法ですし、テーブル設計的に一部のtdだけ中にdiv入れるのってどうなの?とも思うのですが、自分はちょっとこれで力尽きました。。
HTML / CSSに詳しい人にぜひイケてるHTML設計アドバイス欲しいです…
「暫定解決方法でも、まあ、ウン…大丈夫だよ!動くよ!(生暖かい目)」ということであれば、そっといいねしていただけると嬉しいです😂

お読みいただきありがとうございました!

暫定解決方法②(2020/01/29追記)

table-layout: auto;table-layout: fixed;に変更する

今回やりたいこと自体はoverflow-wrap: break-wordの章でちらっと触れたtable-layoutプロパティを
auto(デフォルト)→fixedに変更することで、td配下にdivの入れ子を作らなくても実現可能です!むしろこっちの方が簡単でした!
(コメント欄で検証いただいています。@yshimizu125 さん、ありがとうございます!)

ただし、デメリットとして
「既存サイトのtableのCSSを変えると、影響範囲が大きくなってしまう」
という理由があり、自分は使用できなかったのですが、
新規のHTMLページを作る予定で、table-layout: auto;にする必要がない人は、初めからtable-layout: fixed;をtableのCSSとして設定しておくと良いかもしれません!


  1. 暫定解決方法については、Windows 10やIE, Edge, FireFoxでも試行しましたが、間違い等ありましたら申し訳ありません。 

  2. 句読点、とじかっこなどの記号が行頭に来ないようにするルール。https://ja.wikipedia.org/wiki/%E7%A6%81%E5%89%87%E5%87%A6%E7%90%86 

akane_kato
2年目アプリエンジニアさんです。Java勉強中。
is-tech
大手優良企業特化型システム内製支援事業。ご連絡は https://www.is-tech.co.jp/ の問い合わせフォームをご利用ください。
https://www.is-tech.co.jp/recruit/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした