CSS Display モードを理解する
CSS でレイアウトを決定する際、すべては一つのプロパティに帰結します。それが display です。しかし、多くの解説では、これを暗記すべき値の羅列として扱っています。そのアプローチでは本質を見逃してしまいます。display プロパティは実際には二つの異なる要素を制御しています。一つは要素が親のレイアウトにどう参加するか、もう一つは要素が自身の子要素をどう配置するかです。この二重性を理解することで、モダン CSS レイアウトの基礎に対する考え方が一変します。
重要なポイント
- CSS の
displayプロパティは二つの動作を制御します:外側の表示タイプ(要素が兄弟要素とどう関係するか)と内側の表示タイプ(子要素をどうレイアウトするか)。 - Block と inline は通常フローにおける基本的な外側の表示タイプです。block 要素は垂直に積み重なり利用可能な幅を埋めますが、inline 要素はテキストと共に流れます。
- Flex は単一軸に沿った一次元レイアウトに最適です。Grid は行と列を同時に制御する二次元レイアウト用に構築されています。
display: noneは要素をレイアウトとアクセシビリティツリーの両方から削除します。これは視覚的にのみ隠すvisibility: hiddenとは異なります。display: contentsはラッパー要素を平坦化できますが、アクセシビリティのリスクを伴います。使用前に十分なテストを行ってください。
モダンなメンタルモデル:外側と内側の表示タイプ
CSS の display プロパティは二つの別々の動作を定義します:
外側の表示タイプは、要素のボックスが兄弟要素に対してどう振る舞うかを決定します。全幅を取り新しい行から始まるのか?それとも周囲のコンテンツとインラインで並ぶのか?
内側の表示タイプは、要素の子要素がどうレイアウトされるかを制御します。通常のドキュメントフローに従うのか?それとも flex や grid のコンテキストに参加するのか?
display: flex と記述する時、実際には「この要素は外側では block として振る舞い、その子要素は内側で flex レイアウトを使用する」と言っているのです。CSS Display Level 3 仕様では、これを複数キーワード構文 display: block flex で明示的にしました。ただし、単一キーワードも有効で広く使用されています。
この外側と内側のモデルは、なぜ特定の組み合わせが存在するのかを明確にし、暗記なしで動作を予測できるようにします。
Block vs Inline:基礎
Block と inline は、通常フローにおける二つの基本的な外側の表示タイプを表します。
Block 要素は以下のようなボックスを生成します:
- 新しい行から始まる
- 利用可能な幅を埋めるように拡張する
- すべての辺で width、height、margin、padding を尊重する
Inline 要素は以下のようなボックスを生成します:
- テキストコンテンツと共に流れる
- コンテンツが必要とするスペースのみを取る
- width と height プロパティを無視する(画像などの置換要素を除く)
- 水平方向の margin と padding のみに反応する(垂直方向の margin は無視され、垂直方向の padding は周囲のレイアウトに影響しない)
/* Block: コンテナの幅を埋め、垂直に積み重なる */
.card { display: block }
/* Inline: テキストと共に流れ、コンテンツによってサイズが決まる */
.label { display: inline }
block vs inline vs flex vs grid の理解はここから始まります。Block と inline は通常フロー(他に何も適用しない場合にブラウザが使用するデフォルトのレイアウトアルゴリズム)への参加方法を記述します。
Discover how at OpenReplay.com.
Flex と Grid:モダンな内側の表示タイプ
子要素の配置をより細かく制御する必要がある場合、内側の表示タイプを変更します。
Flex を使用するタイミング
Flexbox は一次元レイアウト、つまり単一軸に沿ってアイテムを配分することに優れています:
.nav-list {
display: flex;
gap: 1rem
}
コンテンツサイズがレイアウトに影響を与えるべき場合、アイテムを自然に折り返す必要がある場合、または単一軸に沿った配置が主な関心事である場合に flex を使用します。
Grid を使用するタイミング
Grid は二次元レイアウト、つまり行と列の両方を同時に制御することを扱います:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr))
}
正確な配置、要素の重なり、またはコンテンツサイズよりも構造が重要なレイアウトが必要な場合に grid を選択します。
flex と grid はどちらも子要素に対して新しいフォーマットコンテキストを作成し、これが内部での margin、float、その他のプロパティの動作に影響します。
Display None:要素を完全に削除
display: none を設定すると、要素がレイアウトから完全に削除されます。ドキュメントは要素が存在しないかのようにレンダリングされます。これは、要素を隠しながらそのスペースを保持する visibility: hidden とは異なります。
display: none は要素をアクセシビリティツリーからも削除することに注意してください。スクリーンリーダーはそれらをアナウンスしません。
Display Contents に関する注意
display: contents の値は、要素のボックスを消失させながら、その子要素をレイアウトに保持します。これは flex や grid コンテキストでラッパー要素を平坦化するのに便利に聞こえますが、重大なアクセシビリティリスクを伴います。ブラウザの実装は歴史的に要素をアクセシビリティツリーから削除し、テーブル、リスト、インタラクティブ要素のセマンティクスを破壊してきました。ブラウザのサポートは改善されていますが、慎重にアプローチし、十分にテストしてください。
適切な CSS Display モードの選択
まずこの質問から始めましょう:どんな問題を解決しようとしていますか?
- 通常のドキュメントフロー?
blockまたはinlineを使用 - 一次元の配分?
flexを使用 - 二次元の配置?
gridを使用 - レイアウトから削除?
noneを使用
まとめ
CSS の display プロパティは値を暗記することではなく、すべての要素が外側の役割と内側のレイアウト戦略を持つことを理解することです。外側のタイプは要素が兄弟要素の中でどう位置するかを支配し、内側のタイプはその子要素がどう配置されるかを決定します。この二重性が理解できれば、適切な display モードの選択は簡単になり、レイアウトの決定は解決しようとしている問題から自然に導かれます。
よくある質問
display none は要素をドキュメントレイアウトから完全に削除します。スペースを取らず、アクセシビリティツリーからも削除されます。visibility hidden は要素を視覚的に隠しますが、レイアウト内で占めるスペースは保持されます。実装によっては、スクリーンリーダーが visibility hidden の要素を検出する場合があります。
同じ要素に同時には使用できません。両方とも内側の表示タイプであり、一度に一つしか適用できないためです。ただし、自由にネストすることは可能です。grid アイテム自体が flex コンテナになることができ、flex アイテムが grid コンテナになることもできます。これにより、親子関係全体で両方のレイアウトモデルを組み合わせることができます。
inline-block は、要素をテキストとインラインで流しながら、width、height、垂直方向の margin と padding を尊重させたい場合に便利です。テキスト行内のボタンやバッジなどの小さな UI 要素に適しています。軸に沿って複数のアイテムを間隔と配置制御で配分する場合は、flex がより良い選択です。
はい。歴史的に、ブラウザは display contents を持つ要素をアクセシビリティツリーから削除し、テーブル、リスト、ボタンなどの要素のセマンティクスを破壊していました。ブラウザベンダーはこれらの問題を修正していますが、不整合は残っています。セマンティックまたはインタラクティブな要素に display contents を使用する場合は、常にスクリーンリーダーでテストしてください。
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.