フレックスボックス - ウェブ開発を学ぶ | MDNフレックスボックス (Flexbox) は、アイテムを行または列に並べるための 1 次元のレイアウト方法です。アイテムがたわんで(伸びて)追加の空間を埋めたり、縮んで小さい空間に収まったりします。この記事では、すべての基本事項について説明し...
フレックスボックス (Flexbox) は、アイテムを行または列に並べるための 1 次元のレイアウト方法です。アイテムがたわんで(伸びて)追加の空間を埋めたり、縮んで小さい空間に収まったりします。この記事では、すべての基本事項について説明します。
前提知識: | HTML の基本(HTML 入門で学んでください)、および CSS の動作の仕組みの考え方(CSS 入門で学んでください)。 |
---|---|
目標: | フレックスボックスレイアウトシステムを使用して、ウェブのレイアウトを作成する方法を習得する。 |
なぜフレックスボックスなのか
長い間、CSS レイアウトを作成するために利用可能な唯一の信頼できるブラウザー間で互換性のあるツールは浮動要素と位置指定などでした。 これらは問題なく機能しますが、いくつかの点ではかなり限定的でイライラするものです。
次のような単純なレイアウト要件は、このようなツールを使用しても、便利で柔軟な方法で実現するのが困難または不可能です。
- コンテンツのブロックをその親内で垂直方向に中央揃えにする。
- コンテナーのすべての子が、使用可能な幅や高さに関係なく、使用可能な幅や高さについて等しい量を占めるようにする。
- 複数列レイアウトのそれぞれの列に含まれているコンテンツの量が異なっても、高さが同じになるようにする。
以降のセクションで見るように、フレックスボックスは多くのレイアウト作業をずっと簡単にします。 さあ始めましょう!
簡単な例の紹介
この記事では、フレックスボックスがどのように機能するのかを理解するのに役立つ一連の演習を進めていくようにします。 まず始めに、github リポジトリーから最初のスターターファイル flexbox0.html のローカルコピーを作成し、最新のブラウザー(Firefox や Chrome など)にロードして、コードエディターでコードを確認してください。 ここでもライブで見ることができます。
内部に最上位の見出しを持つ <header>
要素と、 <section>
要素があり、その中に 3 つの <article>
を含むます。 これらを使用して、かなり標準的な 3 列のレイアウトを作成しましょう。
柔軟な箱としてレイアウトする要素を指定
まず最初に、どの要素を柔軟な箱 (flexible box) としてレイアウトするかを選択する必要があります。 これを行うために、影響を与えたい要素の親要素に display
の特別な値を設定します。 この場合、 <article>
要素をレイアウトしたいので、これを <section>
に設定します。
CSSCopy to Clipboard
section {
display: flex;
}
これによって、 <section> 要素がフレックスコンテナーとなり、その子はフレックスアイテムになります。その結果、以下のような感じになるでしょう。
それで、このたった一つの宣言が必要なものすべてを与えてくれます。信じられないでしょう? 同じ幅の列を持つ複数列のレイアウトがあり、列の高さはすべて同じです。 これは、フレックスアイテム(フレックスコンテナーの子)に与えられる既定値が、このような一般的な問題を解決するために設定されているためです。 それらについての詳細は後で。
はっきりさせるために、ここで何が起こっているのかをもう一度説明しましょう。display
の値として flex
を指定された要素は、ページの他の部分とやり取りする方法についてはブロックレベル要素のように動作しますが、その子要素はフレックスアイテムとしてレイアウトされます。次の節では、この意味をより詳しく説明します。なお、ある要素の子要素をフレックスアイテムとしてレイアウトしたいが、その要素はインライン要素のように取り扱いたい場合は、 display
値として inline-flex
を使用することができます。
フレックスモデル
要素が柔軟な箱として配置されるとき、それらは次のように 2 つの軸に沿って配置されます。
- 主軸 (main axis) は、フレックスアイテムが配置されている方向に走る軸です(例えば、ページを横切る行、またはページ下の列として)。 この軸の始点と終点は、主始点 (main start) と主終点 (main end) と呼ばれます。
- 交差軸 (cross axis) は、フレックスアイテムが配置されている方向に対して垂直に走る軸です。 この軸の始点と終点は、交差始点 (cross start) と交差終点 (cross end) と呼ばれます。
display: flex
が設定されている親要素(この例では<section>
)は、フレックスコンテナー (flex container) と呼ばれます。- フレックスコンテナー内の柔軟な箱としてレイアウトされているアイテムは、フレックスアイテム (flex item) と呼ばれます(この例では
<article>
要素)。
この後の節を読むときに、この用語を覚えておいてください。使用する用語に迷ったときは、常にこの用語を参照してください。
列か行か
フレックスボックスは flex-direction
というプロパティを提供します。 これは主軸が走る方向(フレックスボックスの子がどの方向にレイアウトされるか)を指定します。既定では row
に設定されていて、ブラウザーの既定の言語が動作する方向(英語のブラウザーの場合は左から右に)にそれらが横一列にレイアウトされます。
次の宣言を <section>
のルールに追加してみてください。
CSSCopy to Clipboard
flex-direction: column;
これにより、 CSS を追加する前と同じように、アイテムが縦一列のレイアウトに戻されます。 先に進む前に、この宣言を例から削除してください。
メモ: row-reverse
と column-reverse
の値を使用して、フレックスアイテムを逆方向にレイアウトすることもできます。 これらの値も試してみてください。
折り返し
レイアウトの幅や高さが決まっているときに発生する問題の 1 つは、最終的にはフレックスボックスの子がコンテナーをはみ出してレイアウトが壊れることです。 flexbox-wrap0.html の例を見て、それをライブで見てみてください(この例に沿って進めたい場合は、このファイルのローカルコピーを取ってください)。
ここでは、子要素が実際にコンテナーからはみ出してることがわかります。これを修正させる一つの方法は、 <section>
ルールに以下のような宣言を追加することです。
CSSCopy to Clipboard
flex-wrap: wrap;
また、 <article>
のルールに次の宣言を追加してください。
CSSCopy to Clipboard
flex: 200px;
試してみてください。 これが含まれていると次のようにレイアウトがはるかに良く見えることがわかります。
現在、複数の行があります — 多くのフレックスボックスの子が各行に納められているので、オーバーフローは次のラインに移動します。 article
に設定した flex: 200px
の宣言は、それぞれが少なくとも 200px 幅になることを意味します。 このプロパティについては後で詳しく説明します。 また、最後の行の最後の数個の子がそれぞれ幅広になっているので、依然として行全体がいっぱいになっていることに気付くかもしれません。
しかし、ここでできることは他にもあります。 まず最初に、 flex-direction
プロパティの値を row-reverse
に変更してみてください。 これで、まだ複数行のレイアウトがあることがわかりますが、ブラウザーウィンドウの反対側の隅から開始して逆方向に流れます。
flex-flow 一括指定
ここで、 flex-direction
と flex-wrap
には flex-flow
という一括指定が存在することに注目する価値があります。 例えば、次のように置き換えることができます。
CSSCopy to Clipboard
flex-direction: row;
flex-wrap: wrap;
を
CSSCopy to Clipboard
flex-flow: row wrap;
フレックスアイテムの柔軟なサイズ変更
それでは、最初の例に戻って、フレックスアイテムの占めるスペースの割合を制御する方法を見てみましょう。 ローカルコピーの flexbox0.html を起動するか、新しい出発点として flexbox1.html のコピーを入手してください(ライブで見る)。
まず、CSS の一番下に次のルールを追加します。
CSSCopy to Clipboard
article {
flex: 1;
}
これは、各フレックスアイテムが主軸に沿って使用可能なスペースのうちどれだけを占めるかを決定する、無単位の割合値です。 この場合、各 <article>
要素に 1 の値を与えています。 つまり、パディングやマージンなどを設定した後の残りの予備スペースのうちから、すべてが同じ量を占めます。 これは割合であり、各フレックスアイテムに 400000 の値を指定してもまったく同じ効果があることを意味します。
それでは、前のルールの下に次のルールを追加します。
CSSCopy to Clipboard
article:nth-of-type(3) {
flex: 2;
}
リフレッシュすると、3 番目の <article>
が他の 2 つの幅の 2 倍の幅を占めます。 合計で 4 割合単位が使用可能です。 最初の 2 つのフレックスアイテムはそれぞれ 1 単位ずつ持つため、それぞれ使用可能なスペースの 1/4 を占めます。 3 つ目は 2 単位を持っているので、それは使用可能なスペースの 2/4(または 1/2)を占めます。
flex
の値内に最小サイズ値を指定することもできます。 既存の article
のルールを次のように更新してみてください。
CSSCopy to Clipboard
article {
flex: 1 200px;
}
article:nth-of-type(3) {
flex: 2 200px;
}
これは基本的に「各フレックスアイテムには最初に 200px の使用可能なスペースが与えられます。 その後、残りの使用可能なスペースは割合単位に従って共有されます。」と述べています。 リフレッシュしてみると、スペースの共有方法に違いが見られます。
フレックスボックスの真の価値は、その柔軟性/応答性に見ることができます。ブラウザーウィンドウのサイズを変更したり、別の <article>
要素を追加したりしても、レイアウトは問題なく機能します。
flex: 一括指定対個別指定
flex
は、最大 3 つの異なる値を指定できる一括指定プロパティです。
- 上記で説明した無単位の割合値。 これは
flex-grow
個別指定プロパティを使用して個別に指定できます。 flex-shrink
というフレックスアイテムがコンテナーをオーバーフローしているときに有効になる、2 番目の無単位の割合値。 これは、各フレックスアイテムのサイズからオーバーフローする量を取り除き、それらがコンテナーからオーバーフローするのを防ぐために指定します。 これはかなり高度なフレックスボックスの機能で、この記事ではこれ以上説明しません。- 上記で説明した最小サイズ値。 これは、
flex-basis
の個別指定値を使用して個別に指定できます。
本当に必要な場合以外は、個別指定の flex プロパティを使用しないことをお勧めします(例えば、以前に設定したものを上書きする場合など)。 それらは多くの余分なコードが書かれることにつながり、多少混乱するかもしれません。
水平方向と垂直方向の配置
フレックスボックスの機能を使用して、主軸または交差軸に沿ってフレックスアイテムを整列させることもできます。 新しい例である flex-align0.html を見て(ライブも見る)、これを調べてみましょう。 これは、きちんとした柔軟なボタン/ツールバーに変わります。 現時点では、いくつかのボタンが左上隅に詰まった水平のメニューバーが表示されます。
まず、この例のローカルコピーを取ります。
それでは、例の CSS の最後に次のものを追加してください。
CSSCopy to Clipboard
div {
display: flex;
align-items: center;
justify-content: space-around;
}
ページをリフレッシュすると、ボタンが横方向と縦方向に中央揃えになっていることがわかります。 これを 2 つの新しいプロパティを介して行いました。
align-items
は、フレックスアイテムが交差軸上のどこに配置されるかを制御します。
- 既定では、この値は
stretch
です。 これは、すべてのフレックスアイテムを交差軸の方向に親を埋めるように引き伸ばします。 親が交差軸方向に固定幅を持っていない場合、すべてのフレックスアイテムは最長のフレックスアイテムと同じ長さになります。 これが最初の例が既定で同じ高さの列を得た方法です。 - 上記のコードで使用した
center
の値により、アイテムは固有の寸法を維持しますが、交差軸の中心に配置されます。 これが、この例のボタンが縦方向に中央揃えされている理由です。 flex-start
やflex-end
のような値を持つこともできます。 これは、すべてのアイテムをそれぞれ交差軸の始点や終点に揃えます。 詳細についてはalign-items
を参照してください。
align-self
プロパティを適用することで、個々のフレックスアイテムの align-items
のふるまいを上書きできます。 例えば、CSS に次のコードを追加してみてください。
CSSCopy to Clipboard
button:first-child {
align-self: flex-end;
}
これがどのような影響を与えるのかを見て、終了したらもう一度削除します。
justify-content
は、フレックスアイテムが主軸上のどこに配置されるかを制御します。
- 既定値は
flex-start
です。 これにより、すべてのアイテムが主軸の始点に配置されます。 - それらを終点に配置させるために
flex-end
を使うことができます。 center
はjustify-content
のための値でもあり、フレックスアイテムを主軸の中心に配置します。- 上記で使用した値、
space-around
は便利です。 両端に少しのスペースを残して、すべてのアイテムを主軸に沿って均等に配置します。 - もう 1 つの値、
space-between
があります。 これは、両端にスペースを残さないという点を除けば、space-around
にってもよく似ています。
justify-items
プロパティはフレックスボックスレイアウトでは無視されます。
続ける前に、これらの値を使用してそれらがどのように機能するかを確認することをお勧めします。
フレックスアイテムの順序付け
フレックスボックスには、ソース順に影響を与えずにフレックスアイテムのレイアウトの順序を変更する機能もあります。 これも従来のレイアウト方法では不可能なことです。
このコードは簡単です。 ボタンバーのサンプルコードに次の CSS を追加してみてください。
CSSCopy to Clipboard
button:first-child {
order: 1;
}
リフレッシュすると、 “Smile” ボタンが主軸の終点に移動したことがわかります。 これがどのように機能するかについてもう少し詳しく説明しましょう。
- 既定では、すべてのフレックスアイテムの
order
の値は 0 です。 - 大きな
order
の値が設定されているフレックスアイテムは、小さなorder
の値を持つアイテムよりも表示順序の後半に表示されます。 - 同じ
order
の値を持つフレックスアイテムは、ソース順で表示されます。 そのため、2、1、1、0 のorder
の値がそれぞれ設定された 4 つのアイテムがある場合、それらの表示順序は 4、2、3、1 となります。 - 3 番目のアイテムは 2 番目の後に表示されます。 これは、同じ
order
の値を持ち、ソース順でそれより後にあるためです。
負の order
の値を設定して、0 が設定されているアイテムよりも早くアイテムを表示することができます。 例えば、次のルールを使用して、[Blush] ボタンを主軸の始点に表示させることができます。
CSSCopy to Clipboard
button:last-child {
order: -1;
}
ネストしたフレックスボックス
フレックスボックスを使ってかなり複雑なレイアウトを作成することは可能です。 フレックスアイテムをフレックスコンテナーとしても設定して、その子も柔軟な箱のようにレイアウトできるようにしてもまったく問題ありません。 complex-flexbox.html を見てください(ライブも見る)。
このための HTML はかなり単純です。 3 つの <article>
を含む <section>
要素があります。 3 番目の <article>
には 3 つの <div>
が含まれています。section – article article article – div – button div button div button button button
レイアウトに使用したコードを見てみましょう。
まず、<section>
の子を柔軟な箱として配置するように設定します。
CSSCopy to Clipboard
section {
display: flex;
}
次に、<article>
自体にいくつかの flex
の値を設定します。 ここで 2 番目のルールに特に注意してください — 3 番目の <article>
は、その子もフレックスアイテムのようにレイアウトするように設定していますが、今回はそれらを column
のようにレイアウトしています。
CSSCopy to Clipboard
article {
flex: 1 200px;
}
article:nth-of-type(3) {
flex: 3 200px;
display: flex;
flex-flow: column;
}
次に、最初の <div>
を選択します。 最初に flex: 1 100px;
を使用して効果的にそれの最小の高さを 100px にしてから、その子(<button>
要素)もフレックスアイテムのように配置されるように設定します。 ここでそれらをラッピングする行にレイアウトし、先ほど見た個々のボタンの例で行ったように、それらを使用可能なスペースの中央に配置します。
CSSCopy to Clipboard
article:nth-of-type(3) div:first-child {
flex: 1 100px;
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: space-around;
}
最後に、ボタンにサイズを設定します。今回は、 flex 値として 1 auto を指定しました。これはとても興味深い効果があり、ブラウザーのウィンドウ幅を変更してみるとわかります。ボタンはできるだけ多くの空間を占有しようとします。できる限り同じ行に配置しようとしますが、それを超えると新しい行に移動します。
CSSCopy to Clipboard
button {
flex: 1 auto;
margin: 5px;
font-size: 18px;
line-height: 1.5;
}
ブラウザー間の互換性
フレックスボックスは、Firefox、Chrome、Opera、Microsoft Edge、IE 11、Android / iOS の新しいバージョンなど、ほとんどの新しいブラウザーで利用できます。 ただし、フレックスボックスに対応していない古いブラウザー(または、対応しているものの、本当に古い、時代遅れのバージョンに対応しているもの)もあります。
学習や実験をしている間は、これはあまり重要ではありません。しかし、実際のウェブサイトでフレックスボックスを使用することを検討している場合は、テストを行い、できるだけ多くのブラウザーで使い勝手が許容範囲内になることを確認する必要があります。
フレックスボックスはいくつかの CSS 機能よりも少しトリッキーです。 例えば、ブラウザーに CSS ドロップシャドウがない場合でも、サイトを利用することはできます。しかし、フレックスボックス機能をサポートしていないと、レイアウトが完全に壊れて利用できなくなる可能性があります。
クロスブラウザーのテストのモジュールでは、ブラウザー間の対応の問題を解決するための戦略について説明します。
スキルテスト
この記事の最後まで達しましたが、最も大事な情報を覚えていますか?次に移動する前に、この情報を保持しているか検証するテストがあります — Test your skills: Flexbox: フレックスボックス (en-US) を見てください。
まとめ
これで、フレックスボックスの基本についてのツアーは終了です。 私たちはあなたが楽しみを持って、学習と共に前進するにつれてそれと一緒に良い遊びがあることを願っています。 次に、CSS レイアウトのもう 1 つの重要な側面、CSS グリッドについて見ていきます。
関連情報
- CSS-Tricks Guide to Flexbox — フレックスボックスのすべてを視覚的にわかりやすく説明した記事です。
- Flexbox Froggy — フレックスボックスの基本を学び、理解を深めるための教育ゲームです。