本日の要点
横並びリストで要素の高さを揃える方法
- 行数を制限してしまう
text-overflow: ellipsis;
で、強制的に1行にしてしまう-webkit-line-clamp
で、任意の行数に制限してしまう
- 一部要素の伸縮を制御する
flex-grow
で、領域の広がる場所や比率を制御するmargin-top: auto;
で、任意の箇所の余白を自動調整する
- 1と2の組み合わせでどうにかする
本日の本題
お題にある通り、CSSだけ…… さらにいうとFlexboxを主に使ったリストというのはよく見かけると思います。例えば、こんな感じ。
(スマホで見ている方はレアだと思いますが、PC向けスタイルのみです。ごめんなさい。)
画像は固定サイズですが、見出し、概要文がそれぞれ可変長で、フッタはラベルやユーザー名、日付やラベルが入っているというものです。可変長のところは高さが揃わないので、どうしてもガタツキが目立ってしまい気になると思います。
これが画像+見出しのみの場合は、実はあまり気にならないと思います。
ただ、画像+見出し+概要文+フッタみたいな複雑な組み合わせになってくると、やっぱり横並びで高さが揃っていて欲しい…… と感じるようになってきそうな気がします。
これに対応するのが、横並びで固定の高さを確保して、そこに収まる最大の行を越した場合は「…」にするという方法です。
順当に行くと text-overflow: ellipsis;
が思いつくと思いますが、これは1行からはみ出した分を「…」にするというもの。古いブラウザにも対応していて、トリッキーなことはしていないので安心して使えますが、見た目としてはシンプル過ぎてしまい、正直厳しいところです。
複数行で溢れたときに「…」にするという方法もあります。
肝になるのは .body
等に書かれているここです。
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
height: 4.5em;
これはちょっと特殊で display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
の箇所は、このセットで使います。ただ実質的には overflow
height
まで必要なので、この全体がセットだと考えてもらっても構いません。
(このスタイルは非標準なのですが、他に代替できる方法良い方法がなく、多くのブラウザでサポートされている状況なので使用しています。ブラウザのサポート状況は https://caniuse.com/?search=-webkit-line-clamp )
height: 4.5em;
となっているのは、行の高さを含めて、1行1.5emだという前提で指定しています。
これで、高さが揃いました。大成功! 🙌🏻🙌🏻🙌🏻
……でも良いのですが、せっかくなので、もうひと手間入れましょう。概要文のところを3行と言わずに、概要文をすべて表示した上で、横並びの3つのアイテムの一番長い要素に合わせて広げるというのを作ってみます。
肝は
a {
display: flex;
flex-direction: column;
【略】
}
で a
をFlexbox化し、中身を縦並びにしているのと
.body {
flex-grow: 1;
}
.body
に flex-grow
を指定しているところです。
ちなみに .body
に加えて .header
も、最大3行をやめて可変にしようというのは実は難しいです。 flex-grow
は、Flexboxに含まれる要素の伸び方を制御しますが、両方に指定すると両方ともに伸びが発生してしまい、これらを制御しようとするのは難易度が高かったりします。
余談ですが flex-grow
を使わずに .footer
に margin-top: auto;
を指定しても同じことができます。今回は .footer
には margin-top: 0.75em;
を指定して、概要文が最大の要素の場合に .body
にはくっつかないようにしていますが、こちらも .body
に padding-bottom: 0.75em;
とかを指定すれば解決できるものなので、好みという感じもします。最後にこちらのサンプルも置いておきますね。
(flex-grow方式のほうが、使用できるブラウザシェアはわずかに狭いです。)
近況報告
筆不精で、すみません。
また2週間経過してしまいました。
今回は、CSSに慣れている人ならば言われなくても知ってるよ!みたいなネタなんですが、この筆不精の2週間の間に複数のそれなりにちゃんとしたサービスで見かけたポイントだったので解説してみました。
Twitterもやっているので、よかったらフォローしてください。🙏🏻
https://twitter.com/Kaitou1192