display: contents; とは一体何なのか
tailwindcssを途中から導入しはじめたプロジェクトで、contents
クラスを使用している箇所がデザイン崩れを起こしていたので、tailwindcssにおけるcontents
クラスが持っているプロパティdisplay: contents;
について調べた。
まとめ記事あるけど、長いのでみんなきっと理解できてない
coliss が[CSS]「display: contents;」がすごい便利!ラッパーを使った実装が大きく変わるこれからのテクニックと「すごい便利!」まで言って2018年に解説した記事作ってくれているけど、なかなかボリューミーな記事。
会社の同僚たちが「わからん」言ってたのと、Twitterみても「あとぜ読むぜ」くらいのリアクションしかわかんなかったので、「結局いつ使うねん」だけは、わかるようにまとめてみる。
display: contents; is 何
結論「display: gridと併用して、DOMの構造化のために使用する」
display: contents;が他の要素に与える影響はいろいろある様なんですが、結論は「display: gridと併用して、DOMの構造化のために使用する」です。終わりです。
今のところdisplay: grid
の子要素としてしか基本的に使い道はない!との結論に個人的に落ち着いています。
サンプルと共に解説
どういうことかというと、CSS Grid Layout を使用すると、 grid の子要素(grid-item)が全て並列になってしまい、子要素同士をグループ化する事はできないんですが、こんな時に便利らしいです。
例えばこんな感じの、レイアウト作りたい時はこんなマークアップになります。
<div class="grid">
<div class="item side-navi">side-nav</div>
<div class="item content">content</div>
<div class="item content-footer">content-footer</div>
<div class="item footer-navi">footer-navi</div>
<div class="item footer">footer</div>
</div>
例だと、きっと content と content-footer を main要素でくくったり、footer-navi と footer をfooter要素でくくったりしたくなるはず...(きっと...)
そこで、display: contents;
の出番です。
display: contents;
が指定された要素はgrid-itemにならず、その子要素がgrid-itemとしてレイアウトされるので、こんな感じで書けるようになります。
<div class="grid-with-contents">
<div class="item side-navi">side-nav2</div>
<main class="contents">
<article class="contents">
<div class="item content">content2</div>
<footer class="item content-footer">content-footer2</footer>
</article>
</main>
<footer class="contents">
<navi class="item" id="footer-navi-2">footer-navi2</navi>
<div class="item" id="footer-2">footer2</div>
</footer>
</div>
https://codepen.io/eeonk/pen/VwKPbZM sample書いてみたので、display:contents;
あると崩れないけど、トルと崩れる様子を確認できると思います。
ちなみに、colisではこんな感じのレイアウトを、参考に説明されてらっしゃいました。
個人的には、CSS Grid Layout がっつり使った事そんなに多くないので、どちらの例に関しても、果たして活躍することがあるのか?と思ってしまっているんですが、きっとその時がくれば、便利さに涙を流すことを期待しています。
Can I use CSS display:contents ?
ちなみに、サポート状況(2020/12)はこんな感じで、IEは死亡、モダンブラウザに関してもまだまだパーシャルサポートみたいです。
果たして、がっつり使ってる人どれくらいいるんだろうか気になる。
詳しく
もうすこしだけ、詳しくdisplay:contents
について書いてみます(本当に少しだけ)
冒頭で、display:contents
が効いている部分が崩れてる話をしていたんですが、何で崩れたのを書きます。
ざっくり説明すると、contents の要素は、contentブロックに対するstyle以外が無効になるからみたいんです。
margin が効かなくなったことで崩れてました。
contentブロックてのは、chrome devツールで言うこの真ん中の青い部分ですね。
MDNの参考も貼っておく
効かなくなるCSSと影響ないCSSはざっくりですが、こんな感じでした。
.contents {
display: contents;
/* OK */
font-weight: bold;
color: red;
text-decoration: underline;
cursor: pointer;
&::before{
content: 'before'
}
&::after{
content: 'after'
}
/* NG */
background: #000;
padding: 10px;
margin: 10px;
border: solid 1px #000;
box-shadow: 2px 2px 10px #000;
width: 10px;
}
まあ、contentsつけた要素に対して他のstyle当てることないはずなので、気にしなくても良さそうな気はするけどね。
ちなみに、詳しくは、colisの記事の[CSS]「display: contents;」がすごい便利!ラッパーを使った実装が大きく変わるこれからのテクニックの『「display: contents;」について詳しく解説』のところで詳しく書いてあるので、そっち読み込んでもいいかもです。
Discussion