overflow の役割
内容がボックスより大きいとき (固定の高さ、長い単語、幅の広いテーブル)、内容ははみ出します。はみ出した部分をどうするかを決めるのが overflow プロパティです:
| 値 | 見え方 | スクロールコンテナになるか |
|---|---|---|
visible (初期値) | 内容がボックスからあふれ、後に続くものと重なる | いいえ |
hidden | padding の端で切り取られ、スクロールバーは出ない (スクリプトではスクロールできる) | はい |
clip | 切り取られ、スクリプトでもまったくスクロールできない | いいえ |
scroll | 内容が収まっていても常にスクロールバーを表示 | はい |
auto | 内容が収まらないときだけスクロールバーを表示 | はい |
macOS やスマートフォンではスクロールバーが内容の上に重なって消えるので、スクロールするまで scroll と auto が同じに見えることがあります。
スクロールできるボックスを作る
ボックスがはみ出すのは、何かがそのサイズを制限しているときだけです。height か max-height に overflow-y: auto を加えると、長いリストがスクロールするパネルになります:
ここでは height より max-height が適しています。短いリストは短いままで、長いリストだけがスクロールします。内側にフォーカスできる要素がないスクロール領域には tabindex="0" を付けて、キーボードでもスクロールできるようにしましょう。
overflow-x と overflow-y
2 つの軸は別々に指定できます。よくある使い方は、幅の広いテーブルをページ全体を広げずに、コンテナの中で横スクロールさせることです:
覚えておきたいルールが 1 つあります。片方の軸が hidden、scroll、auto のとき、もう片方の軸の visible は auto になります。そのため overflow-x: hidden だけで、思わぬ縦のスクロールバーが出ることがあります。overflow-x: clip にはこの影響がありません:
.a { overflow-x: hidden; } /* overflow-y computes to auto */
.b { overflow-x: clip; } /* overflow-y stays visible */
文字を省略記号で切る
text-overflow: ellipsis は、切り取られた行の末尾を「…」に置き換えます。制限された幅、折り返せない文字、隠された overflow の 3 つがそろって初めて効きます:
-webkit- 付きの line clamp は Chrome、Firefox、Safari で動きます。スクリーンリーダーは全文を読むので、切り取られた言葉が失われることはありません。
overflow の副作用
overflow を visible と clip 以外にすると、切り取り以外にも変化があります:
- float と子要素の margin を内側に収めます。 要素が新しいブロック整形コンテキストを作るので、float した子要素を包むように大きくなります。
display: flow-rootなら何も切り取らずに同じ効果が得られます。 - 内側の
position: stickyが効かなくなります。 sticky の子要素は一番近いスクロールコンテナに張り付きます。そのコンテナがスクロールしなければ、何も張り付きません。 - absolute で配置した子要素を切り取ります (はみ出す要素がその子の包含ブロックでもある場合)。ドロップダウンやツールチップも含まれ、子要素の box-shadow も切り取られます。
スクロールバーを隠す
scrollbar-width: none を使うと、スクロールできるままスクロールバーを隠せます。使いすぎに注意しましょう。スクロールバーがないと、続きがあることに気づかない読者が多いからです。scrollbar-gutter: stable は逆の役割で、スクロールバーの場所を確保して、スクロールバーが出たときに内容がずれないようにします。
よくある間違い
- サイズの制限なしにはみ出すと思う。
heightもmax-heightもないボックスは、はみ出さずに大きくなります。 - 横スクロールを「直す」ために
bodyにoverflow: hiddenを付ける。 代わりに幅が広すぎる要素を探しましょう (固定のwidth、長い URL、スクロールバーがあるときの100vwがよくある原因です)。 white-space: nowrapなしの省略記号。 文字が折り返されるので横にはみ出さず、省略記号は出ません。overflow-x: hiddenで縦のスクロールバーが出る。clipを使いましょう。- ドロップダウンがカードで切れる。 カードの
overflow: hiddenが切り取っています。overflow の指定を移すか、ドロップダウンを外側に描画しましょう。
よくある質問
overflow: hidden は何をしますか?
要素の padding ボックスに収まらない内容を、スクロールバーなしで切り取ります。隠れた部分も、スクリプトや内側の要素へのフォーカスでスクロールして表示されることはあります。
overflow の auto と scroll の違いは何ですか?
scroll は内容が収まっていても常にスクロールバーの場所を確保します。auto は内容がボックスより大きいときだけスクロールバーを表示します。普通は auto を使います。
div をスクロールできるようにするには?
サイズを制限してスクロールを許可します: max-height: 300px; overflow-y: auto;。height や max-height の制限がなければ、div は内容に合わせて大きくなり、はみ出すことはありません。
overflow-x: hidden で縦のスクロールバーまで出るのはなぜですか?
片方の軸が hidden、scroll、auto のとき、もう片方の軸の visible は auto として計算されるからです。代わりに overflow-x: clip を使えば、スクロールコンテナを作らず、もう片方の軸は visible のままです。
はみ出した文字に省略記号 (...) を付けるには?
1 行なら、幅を制限した要素に white-space: nowrap; overflow: hidden; text-overflow: ellipsis; を指定します。複数行なら display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; を使います。