【Flexbox】第1回コーディングあるある
こんにちは、フロントエンドエンジニアのたいよーです。
突然ですが、日頃コーディングをしていると「うわっ、また同じ現象が起きたわぁ。。」みたいなことがコーダーさんにはよくあるのでないでしょうか。
そんなあるあるを「コーディングあるあるシリーズ」として私たいよーが定期的にお届けしていきたいと思います!!(シリーズがちゃんと続くかは分かりませんが。。笑)
記念すべきシリーズ第1回は、要素の横並びと言ったらこいつだ!でお馴染み「Flexbox」のあるあるをお届けします!
コーディングあるある早く言いたいぃ~♪
「Flexbox」ってなんどい?美味しいんか?
まずは「Flexbox」ってなんどい?という方の為に簡単におさらいしておきましょう。
記事冒頭でもちらっと出てきましたが「Flexbox」は要素を並列にするcssレイアウトです。
基本的な記述は以下の通りです。
HTML
<div class="flex_01">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
</div>
CSS
.flex_01 {
display: flex;
}
.flex_01 .item {
color: #fff;
background: #00bbdd;
padding: 10px;
margin: 0 10px;
}
並列にしたい要素の親要素に「display:flex;」を指定します。
そうすると要素が並列になるので、後は子要素に横幅を指定するなどして調整してあげましょう。
「Flexbox」にはその他様々なプロパティが用意されていますので、同じ並列レイアウト「float:left」や「display:inline-block」よりも自由度の高いレイアウトが可能です。
最後の行を左寄せにする
「Flexbox」を使用するうえでよく使うプロパティの一つに「justify-content:space-between;」があります。
これは親要素に指定すると子要素の最初と最後が端に、残りは等間隔に配置することができます。
このプロパティの利点は要素間の余白を指定しなくても自動的に等間隔配置してくれるので大変便利です!
ですが、これが3カラム、4カラムになると折り返した時の要素が2つになった場合、各子要素が左右端に配置させてしまいます。
そんな時「なんとかして左に寄せたい!」と思ったことは誰しもあるのではないでしょうか。(僕は何千回もあります。)
「justify-content:space-between;」をあきらめて、「justify-content:flex-start;」に変更してmarginで余白を調整するのも1つの手ですが、下記のように記述すれば実現可能です。
HTML
<div class="flex_02">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
</div>
CSS
.flex_02 {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.flex_02::before, .flex_02::after {
content: "";
display: block;
width: calc(25% - 10px);
}
.flex_02::before {
order: 1;
}
.flex_02 .item {
color: #fff;
background: #00bbdd;
padding: 10px;
width: calc(25% - 10px);
}
.flex_02 .item:nth-child(n + 5) {
margin-top: 15px;
}
ここでポイントなのが、親要素に擬似要素を追加して空要素を作ること。
これで空要素も含めて等間隔に配置してくれますし、折り返した空要素は高さがないので、全く問題なし!
※擬似要素:beforeは要素の前に追加されるので、後ろに配置されるようorder: 1;の設定を忘れずに。
4カラムまではcssで対応できますが、それ以上になると空要素が足りなくなるので、その場合はjsで空要素を自動生成するか、事前に空要素を記述しておく必要があります。
今回は後者のパターンで5カラムレイアウトサンプルを用意しました。
ご参考までに。
HTML
<div class="flex_03">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
<div class="item empty"></div>
<div class="item empty"></div>
<div class="item empty"></div>
</div>
CSS
.flex_03 {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.flex_03 .item {
color: #fff;
background: #00bbdd;
padding: 10px;
width: calc(20% - 10px);
}
.flex_03 .item.empty {
padding: 0;
height: 0;
width: calc(20% - 10px);
}
.flex_03 .item:nth-child(n + 6) {
margin-top: 15px;
}
.flex_03 .item.empty:nth-child(n + 6) {
margin-top: 0;
}
高さを揃える
続いて横並びのカードスタイルをコーディングしていると、カード内のテキストの高さがバラバラだから「カードの高さが揃わねぇよ、おい!」というパターンがほんとよくあります。(何千万回もありますよ、ほんと。。)
過去にサイドスリー人気ブログ「意外と知らない!?高さを揃えるコーディング方法」でも同じパターンが紹介されており、ボタン部分をポジション指定して解決していました。
ですが、今回はFlexboxで解決するテクニックを紹介したいと思います!
HTML
<div class="flex_04">
<div class="item">
<a href="#" class="img_link"> <img src="https://placehold.jp/750x500.png?text=Item 1" alt=""> </a>
<div class="text_box">
<h3>Item 1</h3>
<p>ダミーテキストダミーテキストダミーテキストダミーテキスト</p>
<a href="#" class="button">view more</a>
</div>
</div>
<div class="item">
<a href="#" class="img_link"> <img src="https://placehold.jp/750x500.png?text=Item 2" alt=""> </a>
<div class="text_box">
<h3>Item 2</h3>
<p>ダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキスト</p>
<a href="#" class="button">view more</a>
</div>
</div>
<div class="item">
<a href="#" class="img_link"> <img src="https://placehold.jp/750x500.png?text=Item 3" alt=""> </a>
<div class="text_box">
<h3>Item 3</h3>
<p>ダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキスト</p>
<a href="#" class="button">view more</a>
</div>
</div>
<div class="item">
<a href="#" class="img_link"> <img src="https://placehold.jp/750x500.png?text=Item 4" alt=""> </a>
<div class="text_box">
<h3>Item 4</h3>
<p>ダミーテキスト</p>
<a href="#" class="button">view more</a>
</div>
</div>
</div>
CSS
.flex_04 {
display: flex;
justify-content: space-between;
}
.flex_04 .item {
display: flex;
flex-direction: column;
width: calc(25% - 30px);
}
.flex_04 .img_link {
flex: 0 0 auto;
}
.flex_04 .text_box {
display: flex;
flex-direction: column;
flex: 1 0 auto;
padding: 20px;
background: #ddd;
}
.flex_04 .title {
text-align: center;
margin: 0 0 20px;
}
.flex_04 .text {
margin: 0 0 20px;
}
.flex_04 .button {
display: block;
color: #fff;
text-align: center;
text-decoration: none;
width: 120px;
padding: 10px;
margin: auto auto 0;
background: #00bbdd;
}
@media screen and (max-width: 768px) {
.flex_04 {
display: block;
}
.flex_04 .item {
width: 100%;
}
.flex_04 .item + .item {
margin-top: 15px;
}
}
ポイントはざっと3つ!
- item要素を「display:flex;」を指定し、「flex-direction: column;」で画像とtext_box要素を縦並びに。
- flexプロパティ「flex: 0 0 auto;」「flex: 1 0 auto;」で、画像とtext_box要素の伸び率を指定。
- text_box要素内のボタンを「margin: auto auto 0;」で下端中央に配置。
Flexboxは横だけではなく縦にも要素を並べることができますので、ぜひ覚えておいてほしいテクニックですね。
対応ブラウザ
「Flexbox」の対応ブラウザですが、IE以外の最新ブラウザは特に問題なく実装できます。
IEは最新IE11には対応していますが、いくつかバグが報告されているようですので、実装後は必ず確認した方が良いですね。
※IE10はベンダープレフィックス(-ms-)が必要となります。
まとめ
まだまだ「Flexbox」あるあるはありますが、今回はここまで。
今回紹介したテクニックを覚えておけば、いざという時には必ず役に立つと思います。
そして、何と言ってもコーディングスピードも格段に上がると思いますので、同じパターンに遭遇した際にはぜひ活用してみてください。
それでは皆さん、良いコーディングライフを!