
CSSの基礎について勉強を始めたばかりの方にとって最初の難関になる『要素の横並び』。これまではfloatプロパティを使って配置することが基本だったと思いますが、今はfloat以上に便利なプロパティが用意されています。
CSS3で追加された『flex』をご存知でしょうか。
displayプロパティにflexと設定することで、要素がFlexboxとなり、子要素の配置を縦並び、横並び問わず簡単にコントロールできるようになります。Flexboxとは、正式には『Flexible Box Layout Module』といい、名前の通りフレキシブルにレイアウトを組むためのプロパティです。
各主要ブラウザもそれぞれ対応してきていること、また、2017年4月にIE10以下が正式にサポート終了したことなどの理由で、使用を解禁したWeb制作会社も少なくないと思います。
2017年6月現在、モダンブラウザなら、ベンダープリフィックスを付ける必要もなくなり、今後の主流になることは間違いありません。『floatプロパティを使ったレイアウト』も徐々に廃れていく可能性も…。完全になくなってしまう前に、flexboxについて、おさらいしておきましょう。
CSS、横並びの新定番『Flexbox』の基本
CSSで横並びをする場合、floatプロパティの使用。要素のinline-block化など様々な方法がありましたが、今後はFlexboxが主流になると思われます。
たとえば、次のようなHTMLを横並びのレイアウトにするのも容易になります。
例:HTML
<div class="flex">
<p>0</p>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
<p>6</p>
<p>7</p>
<p>8</p>
<p>9</p>
</div>
flexレイアウト例
上記例は次のCSSを設定することで実現しています。
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: row;
justify-content: space-evenly;
);
}
.flex > *{
width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
flexを使うことで、少ない記述で様々なレイアウトを実現できるようになるため、効率的に制作を進められるようになること間違いありません。
しかし、何事も基本が大切ですね!Flexboxも例外ではありません。まずは、名称から紹介します。
Flexコンテナ (Flex container)
『Flexコンテナ』とはflexが設定される枠となる要素のことです。子要素をフレキシブルに配置可能になります。『display: flex』、または『display: inline-flex』を指定された要素がFlexコンテナになります。
次の画像のオレンジ色の範囲がFlexコンテナにあたります
Flexコンテナの範囲
Flexアイテム (Flex item)
『Flexアイテム』とは、Flexコンテナ内でフレキシブルに配置可能な要素で、Flexコンテナの子要素のことを指します。
子要素のみ対象になるので、孫要素以降には影響しません。
次の画像のオレンジ色の範囲がFlexアイテムにあたります
Flexアイテムの範囲
Flexレイアウトの要!Flexコンテナで使用するプロパティについて
Flexコンテナは、『軸』と『方向』の概念を持っています。縦と横、どちらを主軸にするかを決めて、どの方向に向けて並べるかを設定することで要素を配置します。
それぞれ、CSSプロパティで設定することが可能です。
Flexコンテナで使用する主なプロパティは次の5つです。
- flex-direction
- flex-wrap
- justify-content
- align-items
- align-content
以下で、実際の変更例を掲載いたします。上記のHTMLソースコードはそのまま使い、CSSだけを変更してレイアウトを組んでいます。
flex-direction
Flexコンテナの主軸、Flexアイテムを並べる方向を決めるプロパティ。
縦か横か。横なら左から右に向かわせるのか、それとも逆方向か、などなど。
flex-direction: row;
主軸を横に設定し、Flexアイテムを横に並べます。
flex-direction: rowのイメージ
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: row;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
flex-direction: row-reverse;
主軸を横に設定し、Flexアイテムを横に並べます。さらに右から左に向かって並ぶよう設定します。
flex-direction: row-reverseのイメージ
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: row-reverse;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
flex-direction: column;
主軸を縦に設定し、Flexアイテムを縦に並べます。
flex-direction: columnのイメージ
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: column;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
flex-direction: column-reverse;
主軸を縦に設定し、Flexアイテムを縦に並べます。さらに下から上に向かって並ぶよう設定します。
flex-direction: column-reverseのイメージ
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: column-reverse;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
flex-wrap
Flexアイテムがコンテナの端についたとき、折り返すかを決めるプロパティです。折り返す方向は、flex-directionの値によって変化します。
以下の例では、flex-direction: rowが設定されている場合を想定しています。
flex-wrap: wrap;
Flexアイテムがコンテナの端に達したとき、折り返します。例は、flex-direction: rowが設定されているので、下に折り返されます。
flex-wrap: wrapのイメージ
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.flex > *{
min-width: 8%;
flex-basis: 25%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
flex-wrap: nowrap;
基本折り返しません。Flexアイテムはコンテナの幅に収まるように縮小されます。
flex-wrap: nowrapのイメージ
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
.flex > *{
min-width: 8%;
flex-basis: 25%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
flex-wrap: wrap-reverse;
Flexアイテムがコンテナの端に達したとき、通常とは逆方向に折り返します。
例は、flex-wrap: rowが設定されているので、通常は下に折り返されますが、wrap-reverseの場合は上に折り返されます。
flex-wrap: wrap-reverseのイメージ
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: row;
flex-wrap: wrap-reverse;
}
.flex > *{
min-width: 8%;
flex-basis: 25%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
justify-content
主軸の始点側に詰めるか、終点側に詰めるか、それとも中央に寄せるかなど、整列方法を設定するプロパティです。
flex-wrap: nowrapが設定されていると、整列させるためのスペースが残らないことがあるため、一緒に使えない場合も少なくありません。
主軸の始点の位置は、flex-directionの値によって変化します。
以下の例では、flex-direction: rowが設定されている場合を想定しています。
justify-content: flex-start;
主軸の始点側に詰めて揃えます。
例はflex-direction: rowが設定されているので、左詰めになります。
justify-content: flex-startのイメージ
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
justify-content: flex-end;
主軸の終点側に詰めて揃えます。
例はflex-direction: rowが設定されているので、右詰めになります。
justify-content: flex-endのイメージ
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-end;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
justify-content: center;
主軸の中央に寄せるように揃えます。
例はflex-direction: rowが設定されているので、左右中央寄せになります。
justify-content: centerのイメージ
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
justify-content: space-between;
主軸の向きに沿って、最初のFlexアイテムが主軸の始点、最後のFlexアイテムが終点に接するように配置され、他のFlexアイテムを等間隔で並べます。
justify-content: space-betweenのイメージ
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
justify-content: space-around;
主軸の向きに沿ってFlexアイテムに同じ大きさのスペースを入れて並べます。
例はflex-direction: rowが設定されているので、Flexアイテムの左右にスペースが設定されます。
justify-content: space-aroundのイメージ
例:CSS
.flex{
padding: 2.5% 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-around;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
align-items
Flexアイテムを交差軸の始点側に詰めてに揃えるか、終点側に揃えるか、中央に寄せるか、など、交差軸をもとに主軸と垂直の方向の整列方法を設定するプロパティです。
交差軸の始点の位置は、flex-directionの値によって変化します。
以下の例では、flex-direction: rowが設定されている場合を想定していますので、縦方向の配置を設定します。
また、わかりやすくするため、Flexコンテナの高さを固定値にしておきます。
align-items: stretch;
全てのFlexアイテムは、Flexコンテナの交差軸いっぱいに広がります。ただし、flex-wrap: wrapを指定していて、複数段にまたがる場合は、その段にある交差軸が最も長いFlexアイテムに揃えられます。
例はflex-direction: rowが設定されているため、縦いっぱいまで広がります。
align-items: stretchのイメージ
例:CSS
.flex{
height: 250px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: stretch;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
※補足
今回、Flexアイテムの表示の変化をわかりやすくするために、Flexコンテナの高さを固定値にして表示していますが、固定値でなくてもalign-itemsにstretchが設定されている場合は、最もサイズの大きなFlexアイテムに合わせて変化します。
例のように、一つだけサイズが大きいFlexアイテムがあり、Flexコンテナにalign-items: flex-start;が設定されている場合、Flexアイテムの下部にスペースができてしまいます。しかし、align-items: stretch;に変更すると、スペースを埋めるようにFlexアイテムの大きさが変わります。
例:aligin-itemsをflex-startからstretchに変更
align-items: flex-start;
Flexコンテナの交差軸の始点に詰められるように配置されます。
例はflex-direction: rowが設定されているため、Flexコンテナの上部に詰められます。
align-items: flex-startのイメージ
例:CSS
.flex{
height: 250px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-start;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
align-items: flex-end;
Flexコンテナの交差軸の終点に詰められるように配置されます。
例はflex-direction: rowが設定されているため、Flexコンテナの下部に詰められます。
align-items: flex-endのイメージ
例:CSS
.flex{
height: 250px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-end;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
align-items: center;
Flexコンテナの交差軸の中央に寄せられるように配置されます。
例はflex-direction: rowが設定されているため、Flexコンテナの上下中央に詰められます。
align-items: centerのイメージ
例:CSS
.flex{
height: 250px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
align-items: baseline;
Flexアイテムのベースラインがそろうように配置されます。
例はflex-direction: rowが設定されているため、Flexコンテナの上下中央に詰められます。
また、それぞれのFlexアイテムの高さが違うほうがわかりやすいので、奇数番のFlexアイテムのみ、高さを変えています。
align-items: baselineのイメージ
例:CSS
.flex{
height: 250px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: baseline;
}
.flex > *:nth-child(2n){
padding-top: 10px;
height: 150px;
}
.flex > *{
min-width: 8%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
align-content
Flexアイテムが複数段にまたがった際、それぞれの段の軸をどのように配置するか設定するプロパティです。例ではわかりやすいように、高さを固定値にしております。
align-itemsと似ているプロパティですが、align-items主軸にあるFlexアイテムの配置を指定するのに対し、align-contentは軸自体の配置を指定する違いがあります。
align-content: flex-start;
主軸に属するFlexアイテムを交差軸の始点に詰めるように配置します。
align-content: flex-startのイメージ
例:CSS
.flex{
height: 250px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: baseline;
align-content: flex-start;
}
.flex > *{
min-width: 8%;
flex-basis: 15%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex > *:nth-child(2n){
padding-top: 10px;
height: 100px;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
align-content: flex-end;
主軸に属するFlexアイテムを交差軸の終点に詰めるように配置します。
align-content: flex-endのイメージ
例:CSS
.flex{
height: 250px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: baseline;
align-content: flex-end;
}
.flex > *{
min-width: 8%;
flex-basis: 15%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex > *:nth-child(2n){
padding-top: 10px;
height: 100px;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
align-content: center;
主軸に属するFlexアイテムを、交差軸の中央に寄せるように配置します。
align-content: centerのイメージ
例:CSS
.flex{
height: 250px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: baseline;
align-content: center;
}
.flex > *{
min-width: 8%;
flex-basis: 15%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex > *:nth-child(2n){
padding-top: 10px;
height: 100px;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
align-content: space-between;
最初と最後の主軸に属するFlexアイテムがコンテナに接するようにし、等間隔で配置する。
align-content: space-betweenのイメージ
例:CSS
.flex{
height: 250px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: baseline;
align-content: space-between;
}
.flex > *{
min-width: 8%;
flex-basis: 15%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex > *:nth-child(2n){
padding-top: 10px;
height: 100px;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
align-content: space-around;
交差軸を基準にして、等間隔で配置されます。
align-content: space-aroundのイメージ
例:CSS
.flex{
height: 250px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: baseline;
align-content: space-around;
}
.flex > *{
min-width: 8%;
flex-basis: 15%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex > *:nth-child(2n){
padding-top: 10px;
height: 100px;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
align-content: stretch;
行間にスペースがあれば、それを埋めるようにFlexアイテムを広げます。
align-content: stretchのイメージ
例:CSS
.flex{
height: 250px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-content: stretch;
}
.flex > *{
min-width: 8%;
flex-basis: 15%;
background: #fff;
font-size: 64px;
text-align: center;
}
.flex > *:nth-child(2n){
padding-top: 10px;
height: 100px;
}
.flex,
.flex > *{
border: 3px solid #aaa;
}
Flexレイアウトをさらに詳細に設定する!Flexアイテムプロパティ
Flexアイテムに使用できるプロパティです。一つ一つ個別に設定することが可能で、これを使うことで、さらにフレキシブルに配置できるようになります。使用頻度の高い『flex-basis』『align-self』『order』の3つを紹介します。
flex-basis
主軸に対するFlexアイテムの幅を指定するプロパティです。flex-directionの値よって設定する幅の方向が変わります。rowやrow-reverseの場合は横幅、columnやcolumn-reverseの場合は縦幅を設定します。
例は1つ目のFlexアイテムにflex-basis: 200px;を設定しています。
flex-basisのイメージ
align-self
交差軸に対する配置方法を設定するプロパティです。align-itemsプロパティは全てのFlexアイテムの配置を設定しますが、こちらは個別に変更する際に使用します。設定内容はalign-itemsと同じなので、詳細は割愛いたします。
例は、1つめのFlexアイテムにflex-start、2つめにcenter、3つめにflex-endを設定します。
align-selfのイメージ
order
Flexアイテムの順番を入れ替えるプロパティです。Orderプロパティの初期値は0になので、値を明記していないFlexアイテムはすべてFlexコンテナの始点側に詰められて配置されます。
例では1つめのアイテムにorder: 5、2つめにorder: 4、3つめにorder: 3、4つめにorder: 2、5つめにorder: 1を設定しています。
orderのイメージ
flexの注意点 - 少しわかりづらいポイント
flexは挙動をつかむのが難しく、仕様を把握していないと想定のレイアウトを組めなくなってしまいがちです。私がハマってしまった例を一つを紹介します。
『justify-content: space-between』を使っているのに謎のスペース
space-betweenだけど端にスペースが出来てしまう例
『justify-content: space-between』はFlexアイテムを等間隔で並べるプロパティで、最初と最後のアイテムはコンテナの端に接した状態になるはずですが、最後に謎のスペースが…。
別のプロパティかと思っていろいろ試したものの上手くいかず、数時間解決できずに作業が止まってしまいました。
幅が0pxのため目視できないのですが、最後のスペースには、after疑似要素が配置されている状態でした。display: flex;はすべての子要素をFlexアイテムとして定義します。疑似要素も例外ではないようです。
justify-content: space-between;を設定しているにもかかわらず、主軸の始点側、終点側、どちらかに謎のスペースが空いてしまう場合、犯人はだいたい疑似要素(: : before、: : after)だと思います。
まとめ
flexで大事なことは次の点です。
- display: flex、あるいはdisplay: inline-flexを設定した要素は、Flexコンテナとして扱われる。
- Flexコンテナには軸と方向の概念を持っている
- Flexコンテナの子要素はFlexアイテムとなり、フレキシブルに配置可能となる。疑似要素も例外ではない。
ショートハンドの記載方法などもありますが、もとのプロパティを把握していないと、flexを扱うのが難しいと考えているため、ここではあえて明記しません。慣れてきたころにはショートハンドも使いこなせるようになると存じます。
非常に便利なflexですが、今でもブラウザごとの表示の差異がある印象です。体感ですが、Safariやモバイル端末などでの対応で難航する場面が多々あり、実務で積極的に使えない場合もありますのでご注意ください。とはいえ、今後の主流になるのは間違いありません。
使える場面で積極的に使っておき、いつでも使いこなせるように準備しておきましょう!