前回はシンプルな命令で簡単にフレキシブルなレイアウトを実現できるFlexboxの基本的な使い方を説明しました。今回は応用編としてFlexboxを使って、一般的な使い方とは少し違う面白い使い方をご紹介したいと思います。
皆さんがFlexboxを使ったレイアウトと聞いて、真っ先に思い浮かべるのは基本編でも作った横並びメニューやペイン等の分割レイアウトでしょうか?実際にFlexboxはとても使い勝手が良いので、かなり広いシーンで活躍させることができます。
01.Flexboxでアイコンを中央配置させてみる
まず最初は、Flexboxの強力な中央配置を使って、CSSで作るアイコン的な図形を作ってみたいと思います。
当サイトでもページの先頭に戻るために使っている、丸に上向き矢印のボタンや、丸にバッテンの閉じるボタンみたいな図形です。
手っ取り早くFont Awesomeを使ったり、SVG等のイメージを使っても良いのですが、私の場合はできるだけ読み込み時間を短縮したいので、ちゃちゃっとCSSで作ってしまいます。
従来の「position:absolute」と「margin:auto」を利用したブロック要素の上下左右中央寄せでも作ることができますが、Flexboxでも要素の上下左右中央寄せを簡単に出来てしまう例として載せておきます。
HTML
"#circle"がベースとなる形です。今回は当サイトでも使っている円形のものにしました。
"#close"はバッテンマークです。before擬似要素を使い、プラスの形状にした後に45度回転させたシンプルなものになります。
CSS
#circle{ display:flex; align-items:center; justify-content:center; width: 5vw; height: 5vw; border-radius: 50%; background-color: #60B99A; } #close{ display: block; position: relative; width: 2px; height: 2vw; background: #fff; transform: rotate(45deg); } #close:before{ content: ""; display: block; position: absolute; width: 2vw; height: 2px; top: 1vw; left: -1vw; background: #fff; }
"#circle"をコンテナ扱いにするため「display:flex;」プロパティでFlexboxを適用した後に「align-items:center;」「justify-content:center;」でアイテムを上下左右を中央揃えにします。
RESULT
ちなみに「position:absolute」と「margin:auto」を利用したブロック要素の上下左右中央寄せで作る場合は下記のようになります。Flexboxを使った方が若干スッキリしていますね。
CSS
#circle{ position: relative; width: 5vw; height: 5vw; border-radius: 50%; background-color: #60B99A; } #close{ position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; width: 2px; height: 2vw; background: #fff; transform: rotate(45deg); } #close:before{ content: ""; display: block; position: absolute; width: 2vw; height: 2px; top: 1vw; left: -1vw; background: #fff; }
RESULT
同じ結果ですね。
今度は丸に上向き矢印のトップへ戻るボタンを作ってみましょう。
HTML
DIVボックス"#arrow"の上部と右側にborderを付けた形をマイナス45度回転させて図形を作っております。
このようなシンプルなアイコンなら、Font AwesomeやSVGを使うよりもCSSで作った方が簡単です。
CSS
#circle{ display:flex; align-items:center; justify-content:center; width: 5vw; height: 5vw; border-radius: 50%; background-color: #60B99A; } #arrow{ width: 1vw; height: 1vw; border-top: 2px solid #fff; border-right: 2px solid #fff; transform: rotate(-45deg); }
RESULT
このようにFlexboxを使うと、中央配置を生かしたアイコンを手軽に作ることができます。
他にもFlexboxを使うと複数の要素を並べたり、均等配置も簡単にできるので、例えばハンバーガーメニュー(モバイル等でよく使われる三本線のメニュー)や田の字に四分割したアイコンなど、ブロック要素の上下左右中央寄せでは難しい複雑なアイコンを作ることも可能です。
02.Flexboxで手軽にタブを実装してみる
今度はちょっと複雑なタブをFlexboxで作ってみたいと思います。
Flexbox以前の横並びはfloatを使って回り込ませるか、部品をinlineで並べて行っておりました。
タブの場合は、それに加えてタブ部分とコンテンツの表示部分を別パーツで作ってJavaScriptで連動させたり、CSSのラジオボタンのみで作る場合も、複数の要素を跨ぐ複雑なセレクタを用いるなど、面倒な処理が必要でした。
HTML
Tab01の内容が入ります
Tab02の内容が入ります
Tab03の内容が入ります
Tab04の内容が入ります
基本は「display:flex;」を指定したコンテナ".tabs"の中にタブ部品を並べるだけ。
非常に簡単です。ちなみにタブの部分と、コンテンツの表示部分".tab_box"は同じFlexboxのコンテナの中に入れちゃいました。「flex-wrap:wrap;」で折り返し指定にして、コンテンツの表示部分の横幅を100%にする事で、タブの部分と切り離しております。
CSS
.tabs input[type="radio"] { display: none; } .tabs{ width:100%; display:flex; flex-wrap:wrap; overflow: hidden; } .tabs label { width: 15%; height:2vw; box-sizing:border-box; border-top: 0.5vw solid transparent; border-bottom: 2.5vw solid #7E8C85; border-left: 1vw solid transparent; border-right: 1vw solid transparent; text-align: center; } .tabs label:hover { border-bottom: 2.5vw solid #99A39F; } .tabs label h5{ color: #fff; } .tabs .tab_box { width: 100%; display: flex; overflow: hidden; position: relative; box-sizing: border-box; border: 1px solid #7E8C85; background-color: #99A39F; } .tabs .tab_box div{ width: 100%; text-align: center; background-color: #fff; } .tabs .tab_box p{ line-height:10em; } .tabs > .tab_box > div { border-width: 0px; border-style: none; position: absolute; left: 0%; top: -200%; opacity: 0; transition: top 0.3s ease-in-out,opacity 0.3s ease-in-out; } #tab01:checked + label, #tab02:checked + label, #tab03:checked + label, #tab04:checked + label { border-top: 0.0vw solid transparent; border-bottom: 3.0vw solid #A8B1AD; width: 20%; } #tab01:checked ~ .tab_box > #tab_view01, #tab02:checked ~ .tab_box > #tab_view02, #tab03:checked ~ .tab_box > #tab_view03, #tab04:checked ~ .tab_box > #tab_view04 { width: 100%; position: relative; top: 0%; opacity: 1; transition: top 0.5s ease-in-out,opacity 0.5s ease-in-out; }
RESULT
Tab01の内容が入ります
Tab02の内容が入ります
Tab03の内容が入ります
Tab04の内容が入ります
タブとコンテンツの表示部分を同列に置いたことで、ラジオボタンを利用したCSSのみで行うタブの実装がしやすくなりました。
03.グリッドデザイン風に項目を並べてみる
お次も従来はfloatで行っていたグリッドデザイン風の配置をFlexboxで作ってみます。
グリッドデザイン"風"と書いたのは、グリッドデザインには専用の「display: grid;」というプロパティがあり、こちらは大きさの違うグリッドアイテムをコンテナ内に奇麗に並べることができます。今回は同じ大きさのグリッドアイテムを並べるだけなので、お手軽なFlexboxを使って実装してみたいと思います。
HTML
Box01
Box02
Box03
Box04
Box05
Box06
CSS
#information { display: flex; flex-wrap: wrap; justify-content: space-between; list-style-type: none; padding: 0px; } #information li{ width: 30%; height: 20vh; position: relative; background-color: #60B99A; border-radius: 0.4vw; box-shadow: 0 0 5vw rgba(0, 0, 0, 0.05) inset; margin-bottom: 5%; overflow: hidden; border: 1px solid #60B99A; } #information span{ position: absolute; bottom: 0px; width: 100%; height: 40%; background-color: #fff; padding:0.5em 1.0em; }
RESULT
Box01
Box02
Box03
Box04
Box05
Box06
とりあえず単純に並べたものがこちら。「flex-wrap: wrap;」にしてアイテムが親要素(ここでは未指定ですが100%)を越えると、改行されるように指定します。
さらに「justify-content: space-between;」にして、左右のアイテムが端っこにぴったり合うように配置させます。このようにfloatで行うにはちょっと面倒な処理も簡単に実現できます。
しかもアイテムの間隔は自動で計算されますので、左右のmarginを気にする必要もありません。Flexboxのおかげで手軽に横並びが実装できますね。
ちなみに、メディアクエリーを設定してアイテム要素の横幅を変えれば、デバイスによって表示できる要素の数を変えることが出来ますので、レスポンシブデザインにも持ってこいです。
04.サイズの違う要素をFlexboxで自動的に並べる
今度は一部アイテムのサイズを「flex-grow」を使って伸ばしてみます。
「flex-grow」を指定したアイテムがあるコンテナでは、アイテムを並べてスペースが余っている場合に、余ったスペースが各アイテムに分配されるようになっています。
HTML
Box01
Box02
Box03
Box04
Box05
Box06
Box07
Box08
CSS
#information { display: flex; flex-wrap: wrap; justify-content: space-between; list-style-type: none; padding: 0px; } #information li{ width: 20%; height: 20vh; position: relative; background-color: #60B99A; border-radius: 0.4vw; box-shadow: 0 0 5vw rgba(0, 0, 0, 0.05) inset; margin-bottom: 5%; overflow: hidden; border: 1px solid #60B99A; margin-right: 5%; } #information span{ position: absolute; bottom: 0px; width: 100%; height: 40%; background-color: #fff; padding:0.5em 1.0em; } .wide{ flex-grow: 2; }
大きくしたいアイテムには「flex-grow」で割合を2にした".wide"クラスを付与してサイズが変わるようにしました。
RESULT
Box01
Box02
Box03
Box04
Box05
Box06
Box07
Box08
大きさの違うアイテムが入り混じる事によって、よりグリッドデザイン風に見えます。
".wide"指定した部分に注目情報を入れるなどして、サイトの新着情報や制作実績に使えますね。
ちなみに「flex-grow」の分配計算を簡単に説明すると、例えば420ピクセルの幅を持つコンテナに3つのアイテムが並んでいるとします。この3つのアイテムはそれぞれ基本の幅が100ピクセルで「flex-grow」が1,2,3の値を持っている場合です。
まず、コンテナの幅(420)からアイテムの幅(100×3=300)を引いた120ピクセルが分け合うことのできる余ったペースとなります。この余った100ピクセルを「flex-grow」の値の比率で分配し、個々のアイテムの幅に足したものが、最終的な幅になります。
(100 + 120 × 1/6) + (100 + 120 × 2/6) + (100 + 120 × 3/6) = 420
上例のように折り返しがある場合は、行(Row)ごとにこの計算がなされます。3行目の".wide"指定が他の物とサイズが異なるのはこのような理由からです。
「flex-grow」に指定した値が単純に基準値の倍になるわけではありません。あくまでも余ったスペースの分配になる訳です。意識して使うには、最終的な形を思い描いて設計する必要があると思いますが、慣れると複雑なグリッドデザイン風の表示が実現できます。
このようにFlexboxはfloatの代替のみならず、アイデア次第では様々な表現方法やユーザーインターフェイスを作る事に活用できます。
今では主要ブラウザでのサポートもほぼ完了(IEは10以上)しておりますし、これからは主流となるレイアウト方法だと思いますので、ぜひ皆さんも使ってみて下さい。