2021.09.30 [木] display:contentsを使ってみたい。
トライデントコンピュータ専門学校では、夏休みも終わり、各学科ごとに集中授業で作品制作、資格対策などが行われています。そして来週からはいよいよ後期通常授業が始まります。
学園祭などの学校イベントはもちろん、就職活動も始まる後期ですので、充実した学生生活を送ってもらいたいです。
さて、久しぶりにCSSについてわからないことがあったので、調べてみました。
先日、コリスの「モダンCSSによる絶対配置(position: absolute;)の削減 」という記事内にdisplay:contents;の便利な使い方が紹介されていました。

displayプロパティに関しては、過去に、flexについて「そろそろFlexboxを勉強し始めてもいいんじゃないだろうか - ウェブDeBLOG」だったり、gridについては「 CSS Grid Layoutの時代がやってくる。」に記述しましたが、以前よりも、頻繁に使っている気がします。
とうことで、今回はdisplay:contents;です。
display:contents
いつもどおり、W3Cの仕様書を見てみると、
- contents
- The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes and text runs as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced in the element tree by its contents (including both its source-document children and its pseudo-elements, such as ::before and ::after pseudo-elements, which are generated before/after the element’s children as normal).
- 要素自体はボックスを生成しませんが、その子や疑似要素は通常通りボックスやテキストランを生成します。ボックスの生成とレイアウトの目的のためには、要素は要素ツリー内でそのコンテンツ(ソース・ドキュメントの子要素と、 ::before と ::after 疑似要素のようなその疑似要素の両方を含み、これらは通常通り子要素の前後に生成される)によって置き換えられたかのように扱われなければならない。
あいかわらず、よくわかりませんので実際にコードを書いて確認したいと思います
CSSのボックスモデル
まずは、要素自体のボックスを理解するために、CSSのボックスモデルを復習したいと思います。
HTMLの要素はどの要素も、下図のような「ボックス」と呼ばれる四角形の領域を生成します。

CSSのdisplayプロパティの値によって、ボックスと子要素の描画を設定することができます。
displayプロパティ
displayプロパティには、block
やinline
などの表示タイプを設定するものや、flex
やgrid
など、要素内部の表示タイプを設定するものなど、種類が分かれています。
その中で要素がボックスを生成するかどうかを設定する値が、none
とcontents
となります。
none
は、表示・非表示の切り替え時にこれまでもよく利用してきましたが、contents
は、余り馴染みがありませんので、使い方を探ってみましょう。
ブラウザの対応状況
ブラウザの対応状況をcaniuseで調べたところ、Safariで多少バグがあるようですが、IE11以外のモダンブラウザでは、概ね利用できる状態です。
試しに設定してみる
実際にdisplay:contents;
を設定するとどうなるのでしょうか。
div1のコンテンツpのコンテンツ
div2のコンテンツpのコンテンツ
2つの<div>
を用意して、コンテンツ1は、そのままdisplay:block;
コンテンツ2は、display:contents;
を設定してみました。
div { border: 3px solid #006ab6; padding: 1em; background-color: #82c1ea; color: blue; } div p { background-color: #fff; padding: 1em; border: 1px solid #000; margin:0; /*上下のmarginを0に*/ } .content1 { display: block; /*デフォルトだけどblockを設定*/ } .content2 { display: contents; /* contenstsを設定 */ }
pのコンテンツ
上図↑のdisplay:block;
が設定されたコンテンツ1には、borderやbackground-color、paddingが効いていますが、下図↓のdisplay:contents;
のコンテンツ2は、描画されていません。
しかし、文字の色colorは設定されています。
pのコンテンツ
DevToolsでも文字「div2のコンテンツ」は選択できますが、<div class="content2"></div>
は選択できません。
このように、要素自体はボックスを生成しませんが、その子や疑似要素は通常通りボックスやテキストランを生成します。(W3C仕様)
display:contents;
を設定した要素の属性、form要素やform要素内のパーツ、a要素、JavaScriptのイベントなどに関して詳細な解説は、「 [CSS]「display: contents;」がすごい便利!ラッパーを使った実装が大きく変わるこれからのテクニック | コリス」にて解説されています。こちらのコリスの記事では、gridレイアウトのマークアップをセマンティックにするために利用されています。
最新の記事「モダンCSSによる絶対配置(position: absolute;)の削減 | コリス」では、親要素をcontents;に設定することで、position: absolute;
を使わずにflexのみで要素の位置の入れ替える方法が紹介されています。
flexの中のflexが必要なくなる
実際に、学生の制作物などでよく見かけるのが、display:felx;
でレイアウトした中に、<ul>
がある場合(別にul要素でなくても構わない)、<li>
を横に並べられているレイアウトでは、子要素であるul要素にdisplay:felx;
を設定することがあります。
ウェブDeBLOG
display:contents
display:contents;に関して、調べてみました。

例えば、上記のhtmlを図のように配置したい時には
main { display: flex; flex-wrap: wrap; } h1 { width: 30%; } .contents { width: 45%; } aside { width: 25%; } .banner { list-style: none; display: flex; width: 100%; } .banner li { width: 50%; text-align: center; }
というように、 main要素でdisplay:felx;
を設定し、追い出した.bannerのul要素にもdisplay:felx;
を設定する必要があります。
もう少し複雑になると、display:felx;
だらけになってしまいます。
ul.bannerにdisplay:contents;
そこで、.bannerのul要素にflexの代わりにcontentsを設定してみると同じ表示になりました。
.banner { list-style: none; display: contents; width: 100%; }
個人的には、display:felx;
が重なるよりは、見やすくなるかな程度ですが、今後、display:grid;
など、使えそうな場面がありそうなので、意識して使っていきたいと思います。
See the Pen display:contents; by tridentwebdesign (@tridentwebdesign) on CodePen.
コリスの記事以外にも、色々と参考にさせていただきました。
まだ、それほどdisplay:contents;
の使い方については記事が多くなかったので、まだ一般的ではないのかもしれません。
- 参考:リンクを押せなくする「display: contents」を使ったカバー / CSSの工具箱 | PersonWriter's Room
- 参考:【CSS】displayの使い方と種類一覧|実務での注意点なども解説 | JAJAAAN
- 参考:More accessible markup with display: contents | hiddedevries.nl
- 関連記事
-
- JavaScriptで要素を挿入する。 (2023/09/30)
- map()?new Map? (2023/08/10)
- ポートフォリオサイトを印刷用CSSでプリントする。 (2022/03/05)
- @useの使い方がわからない…ので (2022/02/12)
- display:contentsを使ってみたい。 (2021/09/30)
- jQueryだっていいじゃない。 (2021/03/09)
- TypeScriptってなんだ?! (2021/03/01)
- CSSの単位 (2020/09/03)
- JavaScriptのclassについて、書いてみた。 (2019/12/30)
- picture要素と、source要素と、srcset属性と (2018/10/02)