第3回 Flexboxで作る自由自在なレイアウト

この回の目標

  • 横並びのレイアウトを作れるようになる
  • Webサイトでよく見る構成を再現できる
  • 2カラム / 3カラム のレイアウトを作れる

Flexboxとは?

Flexboxは「要素のサイズや間隔を調整してきれいに並べるレイアウト」の仕組みのこと

Flexboxを使うとできること

HTMLの基本では、要素は縦に並ぶ(【第2回】ブロック要素とインライン要素

ブロック①

ブロック②

Flexboxを使うことで、ブロック要素を横並びに配置可能

ブロック①

ブロック②

FlexBoxを使うとブロック要素でも横並びにできる

Flexboxの使用例

アイコン+テキスト

アイコン+テキストの横並び

画像+説明文

富士山(ふじさん)は日本でいちばん高い山で、標高は3,776メートルです。静岡県と山梨県の境目にあり、日本の象徴として世界的にも有名です。

  • 種類:活火山
  • 標高:3,776m(日本一高い山)
  • 最後の噴火:1707年の 宝永大噴火
  • 世界遺産登録:2013年に UNESCO の世界文化遺産

ボタンの横並び

横並びの要素の作り方

Flexboxで横並びの要素を作るには、要素の親子の関係を理解していることが重要

親要素と子要素のおさらい

HTMLには親と子の関係がある(【第1回】HTMLの基本構造 - ネスト構造

<div class="flex">
  <div class="flex__child">ブロック①</div>
  <div class="flex__child">ブロック②</div>
</div>
  • .flex親要素
  • .flex__child子要素

HTML/CSS の書き方

横並びにしたい要素(子要素)を親要素で囲んで、親要素display: flex; を指定する

コード

<div class="flex">
  <div class="flex__child">ブロック①</div>
  <div class="flex__child">ブロック②</div>
</div>
.flex {
  display: flex;     /* displayに「flex」を指定 */
  border: 5px solid #666;
  padding: 20px;
  gap: 20px;
}

結果

ブロック①
ブロック②

ブロック要素であるdivが横並びで表示された

display: flex;で囲まれた子要素は、自動的に横並びになる

子要素の幅を調整する

子要素に幅を指定することで、より自由なレイアウトが可能になる

子要素のサイズ調整にはwidth(横幅)flex(比率)がよく用いられる

width(横幅)の場合

子要素の横幅を px% で指定できる

テキストエリア

flexの数値で割合を指定できます。

<div class="two-column">
  <!-- 子要素① -->
  <div class="two-column__image">
    <img src="./img/fujisan.jpg" alt="">
  </div>

  <!-- 子要素② -->
  <div class="two-column__text">
    <h3 class="title">テキストエリア</h3>
    <p>
      flexの数値で割合を指定できます。
    </p>
  </div>
</div>
.two-column__image {
  width: 40%;           /* 横幅を「40%」に指定 */
  border:1px solid ;
}

.two-column__text {
  width: 60%;           /* 横幅を「60%」に指定 */
  border:1px solid ;
}

flex(比率)の場合

子要素の横幅を 1:12:8 の比率で指定できる

テキストエリア

flexの数値で割合を指定できます。

<div class="two-column">
  <!-- 子要素① -->
  <div class="two-column__image">
    <img src="./img/fujisan.jpg" alt="">
  </div>

  <!-- 子要素② -->
  <div class="two-column__text">
    <h3 class="title">テキストエリア</h3>
    <p>
      flexの数値で割合を指定できます。
    </p>
  </div>
</div>
.two-column__image {
  flex: 2;    /* 比率 */
  border:1px solid ;
}

.two-column__text {
  flex: 8;    /* 比率 */
  border:1px solid ;
}

子要素の並び位置をコントロールする

子要素は「中央揃え」「垂直揃え」「水平揃え」など並び位置の調整ができる

親要素に対してjustify-content(横方向の調整)、align-items(縦方向の調整)プロパティを追加することで調整可能

横方向の調整(justify-content)

左寄せ / 初期値

justify-content: flex-start;

右寄せ

justify-content: flex-end;

中央揃え

justify-content: center;

両端揃え

最初と最後の要素を「左端」と「右端」にピッタリくっつけて、残りの要素をその間に等間隔で並べる

justify-content: space-between;

均等配置

各要素の「左右」に均等な余白を作る

justify-content: space-around;

縦方向の調整(align-items)

引き伸ばし / 初期値

親要素の高さに合わせて、子要素をめいっぱい上下に引き伸ばす

align-items: stretch;
テキスト1
テキスト2
テキスト2
テキスト3
テキスト3
テキスト3

上揃え

align-items: flex-start;
テキスト1
テキスト2
テキスト2
テキスト3
テキスト3
テキスト3

下揃え

align-items: flex-end;
テキスト1
テキスト2
テキスト2
テキスト3
テキスト3
テキスト3

上下中央揃え

align-items: center;
テキスト1
テキスト2
テキスト2
テキスト3
テキスト3
テキスト3

縦方向・横方向を合わせて指定

justify-contentalign-itemsは両方指定することも可能

justify-content: center;
align-items: center;
テキスト1
テキスト2
テキスト2
テキスト3
テキスト3
テキスト3

縦方向、横方向の指定は親要素に対して追加する

間隔を作る

要素同士のすき間はgapで作る

justify-content: center;
gap: 20px;

要素の折り返し

子要素がたくさんある場合に、入り切らなくなった要素を次の行に折り返すかどうかをflex-wrapプロパティで指定できる

折り返さない / 初期値

すべての子要素を無理やり1行に押し込めようとする

flex-wrap: nowrap;
テキスト1
テキスト2
テキスト3
テキスト4
テキスト5
テキスト6
テキスト7
テキスト8
テキスト9
テキスト10

子要素にwidth: 24%;を指定しているのに、1行に詰め込まれている

折り返す

親の幅に収まりきらなくなったら、自動的に次の行へ移動してくれる

flex-wrap: wrap;
テキスト1
テキスト2
テキスト3
テキスト4
テキスト5
テキスト6
テキスト7
テキスト8
テキスト9
テキスト10

子要素に指定したwidth: 24%;ずつの幅で折り返されている

よく見かけるパーツを作ってみよう

Flexboxで作られている、webサイトでよく見かけるパーツを作ってみよう

2カラムレイアウト(画像+テキスト)

富士山(ふじさん)は日本でいちばん高い山で、標高は3,776メートルです。静岡県と山梨県の境目にあり、日本の象徴として世界的にも有名です。

  • 種類:活火山
  • 標高:3,776m(日本一高い山)
  • 最後の噴火:1707年の 宝永大噴火
  • 世界遺産登録:2013年に UNESCO の世界文化遺産
<div class="two-column">
  <div class="two-column__item">
    <img src="./img/fujisan.jpg" alt="富士山">
  </div>
  <div class="two-column__item">
    <p>富士山(ふじさん)は日本でいちばん高い山で、標高は3,776メートルです。静岡県と山梨県の境目にあり、日本の象徴として世界的にも有名です。</p>
    <ul>
      <li>種類:活火山</li>
      <li>標高:3,776m(日本一高い山)</li>
      <li>最後の噴火:1707年の 宝永大噴火</li>
      <li>世界遺産登録:2013年に UNESCO の世界文化遺産</li>
    </ul>
  </div>
</div>
.two-column {
  display: flex;
  justify-content: space-between;
}

.two-column__item {
  width: 49%;
}
  • 親要素にflexを指定して、justify-content: space-betweenで子要素を両端揃えにする
  • 子要素は横幅を「50%」ではなく「49%」にすることで、要素同士の隙間ができる (gapを使って隙間を作る方法でもあり)

3カラムレイアウト(カード)

カード1

カードの説明文です。ここに文章が入ります。

カード2

カードの説明文です。ここに文章が入ります。

カード3

カードの説明文です。ここに文章が入ります。

<div class="three-column">
  <!-- カード1 -->
  <div class="card">
    <div class="card__img">
      <img src="./img/fujisan.jpg" alt="">
    </div>
    <div class="card__textarea">
      <h3 class="card__title">カード1</h3>
      <p>カードの説明文です。ここに文章が入ります。</p>
    </div>
  </div>
  <!-- カード2 -->
  <div class="card">
    <div class="card__img">
      <img src="./img/fujisan.jpg" alt="">
    </div>
    <div class="card__textarea">
      <h3 class="card__title">カード2</h3>
      <p>カードの説明文です。ここに文章が入ります。</p>
    </div>
  </div>
  <!-- カード3 -->
  <div class="card">
    <div class="card__img">
      <img src="./img/fujisan.jpg" alt="">
    </div>
    <div class="card__textarea">
      <h3 class="card__title">カード3</h3>
      <p>カードの説明文です。ここに文章が入ります。</p>
    </div>
  </div>
</div>
.three-column {
  display: flex;
  gap: 30px;
}

.three-column .card {
  flex: 1;
  background: #fff;
  box-shadow: 0 0 10px #ddd;  /* 左右の位置px  上下の位置px ぼかしpx 色 ;*/
}

.three-column .card__textarea {
  padding: 20px;
}

.three-column .card__title {
  font-size: 20px;
  margin-bottom: 8px;
}
  • 親要素にflexを指定して、gap :30px;で子要素同士の隙間を開ける
  • 子要素は横幅をflex: 1;にすることで「1:1:1」の割合になり同じ大きさで表示できる
  • box-shadowを使うと要素に影をつけることができる
  • .cardの中を.card__img.card__textareaに分けることで、テキスト部分のまとまりにのみ余白(padding)をつけることができる

グローバルナビゲーション

<div class="header">
  <div class="logo">LOGO</div>
  <nav class="nav">
    <ul class="nav__menu">
      <li>Home</li>
      <li>About</li>
      <li>Contact</li>
    </ul>
  </nav>
</div>
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 20px;
  border-radius: 10px;
  box-shadow: 0 0 10px #ddd;
}

.header .logo {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.1em;
}

.header .nav__menu {
  display: flex;
  gap: 20px;
}

.header .nav__menu li {
  list-style: none;
}
  • .headerjustify-content: space-between;を指定することでロゴとメニューを両端揃えにしている
    またalign-items: center;によってロゴとメニューを上下中央揃えにすることで見た目のガタ付きをなくせる
  • .nav__menuをさらにflexにすることでメニューを横並びにして、gapでメニュー間の隙間を作っている
  • list-style: none;で箇条書きの「・」をなくしている

ページの上に固定したい時

コーディングラボのサイトのように、グローバルメニューを常にページ上部に固定したい時にはposition: fixed;を使う

.header {
  position: fixed;  /* 画面上に固定させる */
  top: 0;           /* 画面topから0pxの位置 */
  z-index: 100;     /* 重なり順(大きいほど上に表示される) */
}

ミニ課題

  • 「アイコン+テキスト」の横並び要素を作ってみよう
  • 「ボタン」の横並び要素を作ってみよう
  • 3カラムレイアウトのカードを6枚に増やして、3枚ずつ折り返すようにしてみよう

まとめ

今回のまとめ

  • 親要素にFlexboxを指定することで、横並びの要素が作れる
  • justify-contentで横方向調整
  • align-itemsで縦方向調整
  • Flexboxを使って子要素の比率を調整することで、さまざまなレイアウトが作れる

次回の予定

スマホで見たときのレイアウト「レスポンシブデザイン」について学びます