バナー

この教材は「ギャクサン」というWeb制作学習カリキュラムの一部です。

はじめての方はこちらからご覧ください👉

更新日

#16  「display : flex」を使って横並び・中央揃えのレイアウトの基礎を身につけよう

web兄さん

【予告】本講座の最後で課題にチャレンジします!

【Before】このHTMLを→

課題の変更前

【After】flexを使ってレイアウトを変更

課題の変更後
課題の変更後

flexは最初は考え方が難しい内容ですが、最後の課題チャレンジで身につけられるようになるので頑張って取り組んでくださいね!

web兄さん
今回は「レイアウト」をコントロールするためのテクニックの基礎を身につけていきます。例えば以下のようなことをできるようになります!

デフォルトだと縦並びのものを…

横並びにしたり


高さの違う要素を…

中央で揃えたり


並んでいる要素の

順番を入れ替えたり

web兄さん
Webサイトはレイアウトの連続!基礎をしっかり押さえましょう。

display : flexとは?

displayと聞くと、前回の講座で学習した「ブロック要素←→インライン要素」に変換するためのdisplay : inlinedisplay : blockが思い浮かびますよね。

display : flexとはdisplayプロパティの値の一種で、レイアウトをコントロールしたい要素に使います。

たとえば、上記の例ではHTMLとCSSのコードは以下のようになっています。

<div class="parent">
    <div class="child">
        <img src="dog01.png">
    </div>
    <div class="child">
        <img src="dog02.png">
    </div>
</div>
.parent{
  display : flex;
}

画像を囲っている<div class="parent">に対してdisplay : flexを適用しています。

このようにdisplay : flexを適用すると、適用した要素の子要素はレイアウトをコントロールできる対象要素になります。

flexコンテナとflexアイテム
flexコンテナとflexアイテム

<div class="parent">が親のflexコンテナ、<div class="child">が子のflexアイテムとなります。

上記のコードを実際の見た目にしてみると以下のようになります。

このようにflexアイテムとなった子要素に対して、横並びや順番の入れ替え、要素の中央揃いなどを指示することでレイアウトをコントロールしていきます。


実際の仕事の例でいえば、以下のようなデザインでプランのパネルが横並びになっていますが、こういったところにdisplay : flexは使用されています。

web兄さん
「なんか難しい…」と思った人も大丈夫!ここからは実際のケースを元に概要を理解していきます。

縦並びの要素を横並びにする

まずは基本の横並びから!

みなさんもご存知の通り、HTMLはコードを書いた順で上から下に向けて縦に並んでいきます

なので以下のように画像を並べた場合は当然縦に並びます。

<div class="dogs">
    <div class="img">
        <img src="dog01.png">
    </div>
    <div class="img">
        <img src="dog02.png">
    </div>
</div>

これを横並びにするためには、レイアウトをコントロールしたい要素の親要素にdisplay : flexを適用する必要がありましたね。

つまり…

  • レイアウトを変えたい要素(横並びにしたい要素) = <div class="img">
  • 👆の親要素 = <div class="dogs">

となるので<div class="dogs">display : flexを適用するのが正解です!

.dogs{
  display : flex;
}

display : blockを適用することで、自動で子要素が横並びになります。

この時、今回の例のように、横並びになった子要素の横幅が親要素よりも小さい場合は子要素は広がらず、残りは余白として残ります。


.dogs{
  display : flex;
  background-color : red; /*背景赤*/
}

親要素の背景に赤色をつけるとわかりやすくなります。

横並びになった要素の右側が余白として残っているので赤色の背景色が見えていますよね。

縦並びの要素を横並びにする(3つ以上の場合)

横並びにしたい要素が3つ以上ある場合どうでしょうか?

例えば横並びのメニューを作りたいとします。(※わかりやすくするために背景に色をつけました

<ul>
  <li class="one">1つ目のメニュー</li>
  <li class="two">2つ目のメニュー</li>
  <li class="three">3つ目のメニュー</li>
  <li class="four">4つ目のメニュー</li>
</ul>
  • 1つ目のメニュー
  • 2つ目のメニュー
  • 3つ目のメニュー
  • 4つ目のメニュー

3つ以上要素がある場合も同様にdisplay : flexを親要素につけるだけで横並びにできます。

ul{
  display : flex;
}
  • 1つ目のメニュー
  • 2つ目のメニュー
  • 3つ目のメニュー
  • 4つ目のメニュー

しかし先ほどまで違い、全てのメニュー(子要素)を横に並べると親要素の幅を上回ってしまうためテキストが途中で折り返されていますよね。

このように親要素の幅を上回る場合は横並びの子要素の幅が自動で縮小されます。

縮小の原理については別の記事で紹介

display : flexは初学者の方にとっては複雑な概念なので、細かな理屈について解説すると奥が深いので今回は省きます。まずは慣れることが大事なので「横並びはdisplay : flexを親要素に適用」とだけまずは覚えましょう!

flex-basis|アイテムの横幅をコントロールする

デフォルトの横並びから→

左側のテキスト

右側のテキスト

子要素の幅を「30%:70%」にしたい

左側のテキスト

右側のテキスト

通常、display:flexを親要素に指定しただけでは、子要素がただ横並びになるだけです。

子要素の横幅をコントロールしたい場合は子要素(flexアイテム)にflex-basisというプロパティを適用します。

<div class="parent">
    <div class="child-left">
        <p>左側のテキスト</p>
    </div>
    <div class="child-right">
        <p>右側のテキスト</p>
    </div>
</div>
.parent{
  display : flex;
}

.child-left{
  /*親要素の30%の幅にする*/
  flex-basis : 30%
}

.child-right{
  /*親要素の70%の幅にする*/
  flex-basis : 70%
}

親要素の幅を100%として、

  • 左側のブロックに.child-leftflex-basis : 30%
  • 右側のブロックに.child-rightflex-basis : 70%

とCSSを適用させます。以下の図解でイメージを確認しましょう。

flex-basisを利用して「3:7」の比率で並べる

このように任意の横幅をflexアイテムに指定することで、レイアウトを自由にコントロールできます。

pxで指定することも可能

150pxの幅

40pxの幅

.parent{
  display : flex;
}

.child-left{
  flex-basis : 150px;
}

.child-right{
  flex-basis : 40px;
}

flex-direction|要素の並ぶ方向の指定

「要素の並ぶ方向の指定?display: flexで並べるのは横並びだけじゃない?」と思ってしまいがちですが、flexboxは縦に並べて要素の配置をコントロールすることもあります。

実は、display: flexを指定すると、flex-direction: row(横並びにする)というプロパティが自動で適用されています。

これをflex-direction: column(縦並びにする)にすると以下のようになります。

150pxの幅

40pxの幅

.parent{
  display : flex;
  flex-direction: column;
  /* デフォルトだとflex-direction: rowが適用されている */
}

.child-left{
  flex-basis : 150px;
}

.child-right{
  flex-basis : 40px;
}

flex-basisで横幅の指定をしたつもりが高さがそれぞれ150px40pxになっていますね!

これが横並びと縦並びの重要なポイントである「主軸」と「交差軸」です。

並んでいる方向に沿った軸を「主軸」それにクロスするものが「交差軸」となり、flex-directionによってこれが決定されます。

主軸と交差実の違い
主軸と交差実の違い

flex-basisの交差軸のつき方

これによって、flex-basisもどのように適用されるかが変わってきます。

横幅と説明しましたが、flex-basisは厳密に言えば主軸方向に沿ったアイテムの幅の指定です。

つまり、横のときは横幅、縦のときは高さの幅が変更されます。

flex-basisの場合の主軸と交差軸の違い
flex-basisの場合の主軸と交差軸の違い
web兄さん
この「主軸」と「交差軸」によってプロパティの効果に違いがでるのでこの概念はしっかり押さえましょう。

align-items|交差軸の揃え方を指定

display : flexで横並びをした場合、上を基準に並びが、デザインによっては高さの異なる要素を中央で揃えたい時があります。

そんな時にalign-itemsというプロパティを使用します。

横並びの要素を中央に揃えたい (2)

ちなみにデフォルトで上に揃っているのは、デフォルトでalign-items: flex-start(上揃い)が適用されているからです。

align-itemの使い方

以下のようなコードで、親要素にdisplay : flexを指定した場合、横並びになりますが、高さが違うため、上を基準に揃ってしまいますよね。

<div class="dogs">
    <div class="img">
        <img src="dog01.png">
    </div>
    <div class="img">
        <img src="dog02.png">
    </div>
</div>
.dogs{
 /*これだけではただ横並びになるだけ*/
 display : flex;
}

この時にdisplay : flexは書いたまま、加えてalign-items : centerと書くことで、横並びにした子要素(flexアイテム)を上下中央揃いにすることができます。

.dogs{
 display : flex;
 align-items : center;
}

他にもalign-items : flex-endとすることで下端揃えにすることができます。

.dogs{
 display : flex;
 align-items : flex-end;
}

align-itemの主軸と交差軸の違い

flex-basisと同様に、横並びと縦並びの軸の方向によって揃い方が変化します。

align-itemsの場合の主軸と交差軸の違い
align-itemsの場合の主軸と交差軸の違い

横並び(flex-direction: row)のときは水平方向、縦並び(flex-direction: column)のときは垂直方向のアイテムの揃え方が変わります。

このようにalign-itemsは「交差軸に沿った」アイテムの揃え方を指定することができます。

justify-content|主軸の並び方を指定

align-itemsに対して、主軸方向の揃え方を指定できるのがjustify-contentです。

ちなみにデフォルトで左に揃っているのは、デフォルトでjustify-content: start(先頭に寄せる)が適用されているからです。

justify-contentの使い方

以下のようなコードで、親要素にdisplay : flexを指定して、親要素の両端に配置したいとします。

<div class="dogs">
    <div class="img">
        <img src="dog01.png">
    </div>
    <div class="img">
        <img src="dog02.png">
    </div>
</div>
.dogs{
 /*これだけではただ左詰めになるだけ*/
 display : flex;
}

この時にdisplay : flexは書いたまま、加えてjustify-content : space-betweenと書くことで、横並びにした子要素(flexアイテム)を親要素の端から均等間隔で並べることができます。

.dogs{
 display : flex;
 justify-content : space-between;
}

justify-content : endとすることで逆側に寄せることもできます。

.dogs{
 display : flex;
 justify-content : end;
}

justify-contentの主軸と交差軸の違い

align-itemsと同様に、横並びと縦並びの軸の方向によって揃い方が変化します。

justify-contentの主軸と交差軸の違い
justify-contentの主軸と交差軸の違い

横並び(flex-direction: row)のときは水平方向、縦並び(flex-direction: column)のときは垂直方向のアイテムの並び方が変わります。

このようにjustify-contentは「主軸方向に沿った」アイテムの並び方を指定することができます。

flexのおさらいをしよう

Q.横並びにしたい時は横並びにしたい要素の〇〇に対してdisplay:flexを適用する
親要素
Q.display : flexを適用した要素を「flex〇〇」、横並びになる要素を「flex〇〇」と呼ぶ
「flexコンテナ(親)」「flexアイテム(子)」
Q.横並びにしたい要素の幅を親要素の50%の幅に指定したい時は、その要素に対して〇〇を適用する
flex-basis : 50%
Q.3分割で均等に表示したい時は要素に対して〇〇を適用する
flex-basis : 33%
Q.高さの違う要素の上下の位置を中央に揃えたい時は子要素に対して、〇〇を適用する
align-items : center
Q.親要素の中で子要素を均等に配置したいときは〇〇を親要素に適用する
justify-content: space-between

flexboxを使った課題にチャレンジ

flexboxの考え方は実際に手を動かさないと理解できないので、課題にチャレンジしていく中で身に着けていきましょう。

以下のようにBeforeでは縦に並んでいる要素を今回習ったプロパティを使用して横並びのレイアウトにしていきます。

【Before】このHTMLを→

課題の変更前

【After】flexを使ってレイアウトを変更

課題の変更後
課題の変更後

課題の手順

❶環境の準備

以下に手順が記載してありますが、不安な方は「#09 CSSの課題|シンプルなWEBページを作ろう」の環境準備の動画を参考にしてみてください。

手順01

デスクトップに「webliker」>「kadai-flex」という課題用のフォルダを作成する

デスクトップに課題用のフォルダを作成する

HTMLの課題の時と同様にweblikerというフォルダの中にkadai-flexというフォルダを作りましょう。

手順02

VS Codeで「index.html」を作成し「kadai-flex」の中へ保存する

作成したフォルダの中にindex.htmlを保存する

※必ず以下のHTMLをコピーしてください

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    
    <!-- Q1 -->
    <h2>1問目</h2>
    <div class="q1-parent">
        <p class="q1-child-a">display : flexとはdisplayプロパティの値の一種で、レイアウトをコントロールしたい要素に使います。</p>
        <p class="q1-child-b">flexアイテムとなった子要素に対して、横並びや順番の入れ替え、要素の中央揃いなどを指示することでレイアウトをコントロールしていきます。</p>
    </div>

    <!-- Q2 -->
    <h2>2問目</h2>
    <div class="q2-parent">
        <p class="q2-child-a">これはAです</p>
        <p class="q2-child-b">これはBです</p>
        <p class="q2-child-c">これはCです</p>
        <p class="q2-child-d">これはDです</p>
    </div>

    <!-- Q3 -->
    <h2>3問目</h2>
    <div class="q3-parent">
        <p>
            <img src="img/dog-blue.png" alt="犬">
        </p>
        <p>
            <img src="img/dog-green.png" alt="犬">
        </p>
        <p>
            <img src="img/dog-red.png" alt="犬">
        </p>
    </div>

    <!-- Q4 -->
    <h2>4問目</h2>
    <div class="q4-parent">
        <p>
            <img src="img/dog-blue.png" alt="犬">
        </p>
        <p>
            <img src="img/dog-green.png" alt="犬">
        </p>
        <p>
            <img src="img/dog-red.png" alt="犬">
        </p>
    </div>

    <!-- Q5 -->
    <h2>5問目</h2>
    <div class="q5-parent">
        <p class="q5-child-a">display : flexとはdisplayプロパティの値の一種で、レイアウトをコントロールしたい要素に使います。</p>
        <p class="q5-child-b">flexアイテムとなった子要素に対して、横並びや順番の入れ替え、要素の中央揃いなどを指示することでレイアウトをコントロールしていきます。</p>
    </div>

</body>
</html>

手順03

VS Codeで「style.css」を作成し「kadai-flex」の中へ保存する

@charset "UTF-8";

/* 装飾用のコード(触らない) */
body{
    padding: 0px 100px 50px;
}
h2{
    margin-top: 4em;
    padding-top: 2em;
    border-top: solid 5px #eee;
}
  1. VS Codeで新規ファイルを作成し「左のコード」をコピペ
  2. style.cssというCSSファイルを作成
  3. デスクトップ > webliekr > kadai-flexへ保存

※装飾用のCSSが記載されているので消さないようにしてください。


作成したフォルダの中にstyle.cssを保存する

手順04

画像をダウンロードして読み込み

画像をダウンロードしてimgフォルダに追加

課題で使う画像をダウンロードし、

kadai-flex > imgの中に移動させます。

手順05

index.htmlを開いて表示をチェック

課題の変更前

HTMLだけの表示では左のようになります。

この状態になっていればOKです。

❷実践|課題に取り組もう

flexの課題の指示書
flexの課題の指示書

今回の課題も以前と同様に、上記のように指示を加えているので、それに従ってレイアウトを変更しましょう。


1問目・2問目・5問目の<p>は以下のスタイルを適用しよう

課題のp要素は以下のようになっていますよね。

  1. 背景に色がついている(background-color)
  2. 文字が白色(color)
  3. ↓↓↓テキストと背景色の間に余白が10pxついている(padding:10px)

HTMLのコードから考えて自身で以下のCSSを追加してみましょう。

5問目に関しては横幅と高さが指定してあるのでflex以外のプロパティも必要です。

画像は背景色を追加する必要がありません

画像の背景色はCSSでつける必要がありません。すでに画像自体に色がついています。


コピー用のカラーコード

#0B78D7

#FF6658

#F4AE32

#02C898

課題の解答

正解のCSSのコードを確認する

@charset "UTF-8";

body{
    padding: 0px 100px 50px;
}

h2{
    margin-top: 4em;
    padding-top: 2em;
    border-top: solid 5px #eee;
}


/*

    Q1のCSS

*/

.q1-parent{
    display: flex; /*子要素を横並びにする*/
}

.q1-parent p{
    color: #fff;
    padding: 10px;
}

.q1-child-a{
    background: #FF6658;
}

.q1-child-b{
    background: #0B78D7;
}


/*

    Q2のCSS

*/

.q2-parent{
    display: flex;  /*子要素を横並びにする*/
}

.q2-parent p{
    color: #fff;
    padding: 10px;
    flex-basis: 25%;  /*子要素を25%の大きさにする*/
}

.q2-child-a{
    background: #FF6658;
}
.q2-child-b{
    background: #0B78D7;
}
.q2-child-c{
    background: #F4AE32;
}
.q2-child-d{
    background: #02C898;
}


/*

    Q3のCSS

*/

.q3-parent{
    display: flex;  /*子要素を横並びにする*/
    align-items: center;
}


/*

    Q4のCSS

*/

.q4-parent{
    display: flex;  /*子要素を横並びにする*/
    align-items: flex-end;
    justify-content: space-between;
}


/*

    Q5のCSS

*/

.q5-parent{
    display: flex; /*子要素を横並びにする*/
    flex-direction: column;
    align-items: center;
}

.q5-parent p{
    color: #fff;
    padding: 10px;
}

.q5-child-a{
    background: #FF6658;
    width: 600px;
    flex-basis: 100px;
}

.q5-child-b{
    background: #0B78D7;
    width: 300px;
    flex-basis: 200px;
}