サイトロゴ

Enjoy Creating
Web & Mobile Apps

MENU BOX
WEB
MOBILE
OPEN

ホーム

 > 

 > 

フレックスアイテムの伸び縮み(flex)

フレックスアイテムの伸び縮み(flex)

この記事にはプロモーションが含まれています。

今回はちょっと応用です!display: flex; で横並びにしたフレックスアイテムは何も設定していない場合、画面や親要素の幅に合わせて縮小はしますが、拡大はしません(フレックスアイテムのwidthを%で指定していたら別ですが)。そこで、今回はフレックスアイテムの伸び縮みなどを指定するCSSを紹介します。

動画内容:flexプロパティについて

フレックスアイテムの伸縮率などを指定できるCSSプロパティの「flex」ですが、伸縮率を指定できると言われてもちょっとピンと来ないですよね。一体、どのような場面で利用できるのでしょうか?

例えば、元々のサイズが決まっているラスター形式の画像など、拡大され過ぎると画質が劣化してしまう要素に対し、大きなPC画面から見ても拡大され過ぎないようにしたり、width を設定しなくてもフレックスアイテムの比率を簡単に設定できたりします。

「display: flex; で横並びにしたAとBの幅の比率を指定したい」と言う場合、width の%を使うとなると計算が少し面倒ですよね。例えば、Aの幅をBの幅の1.35倍にしたいとすると、AとBの width をそれぞれ何%にすれば良いか、少なくとも僕はパッと計算できません。
しかし、今回紹介する flexプロパティを使えば計算の必要はありません。

その他、min-width や max-width を設定しなくても一定の大きさを超えて縮小・拡大しないようにすることもできます。基準となる width を指定した上にさらに min-width・max-widt を指定すると若干コードがややこしくなってしまうので、そういった場合は一行でコードが書けるflexプロパティが便利かもしれません。
少し扱いの難しいCSSプロパティですが、できるだけ簡単に解説していきます!


◆ flex とは ◆

flex(フレックス)とは、display: flex; などで横並びにしたアイテムの「拡大率・縮小率・基準幅」を一括で指定できるプロパティです。

display: flex; などとは違って親要素に指定するのではなく、横並びにした要素そのもの(フレックスアイテム)に設定します。

flexは、次のCSSプロパティを一括設定できるプロパティです。

*flexプロパティに含まれるもの*

プロパティ効果
flex-grow拡大率を指定する
flex-shrink縮小率を指定する
flex-basis基準幅を指定する

flex-grow と flex-shrink に関しては、単位のない数値で指定します。
また、flex-basis は、ほぼ width と同じ値を取ります。(数値+単位・キーワード値)※widthに関する記事は→こちら

それぞれのCSSプロパティをまとめて簡単に説明すると、以下のようになります。

・flex-basisで定めた基準幅を超えるときは、flex-growで定めた拡大率で拡大していく
・flex-basisで定めた基準幅より狭くなるときは、flex-shrinkで定めた縮小率で縮小していく

ちなみに、flex-basisも含めて全ての値に「0(ゼロ)」を指定することができ、0を指定した場合は、

・flex-gorw → 拡大しなくなる(max-widthを指定するような感じ)※flex-basisをpxなどで設定している場合
・flex-shrink → 縮小しなくなる(min-widthを指定するような感じ)※flex-basisをpxなどで設定している場合
・flex-basis → 基準幅を定めない(flex-growの指定値に比率が調整される)※flex-growが設定されていないと表示されない

ということになります。

以上を踏まえて、記述例です。

* flex の構文例*
■ セレクタ { flex: 1 1 auto; }
左の数値から順に、flex-grow flex-shrink flex-basis となります。

上記の例の場合は、「フレックスアイテムの元の大きさを基準として、フレックスボックスの幅がフレックスアイテムの大きさより広い場合はアイテムが引き伸ばされ、狭い場合は縮小される」ということになります。

    POINT!
  1. ・flexプロパティは、フレックスアイテムに flex-grow flex-shrink flex-basis を一括指定できる!
  2. ・flex-growは拡大率、flex-shrinkは縮小率、flex-basis は基準となる幅の指定をする!

◆ flexの有効活用(1) ◆

flexプロパティでフレックスアイテムの拡大・縮小率を変更できますが、それを変更するということは「デバイスの画面幅によって同じページでも見え方が変わってしまう」ということになります。
それが狙いであれば良いのですが、普通はどのようなデバイスから見てもデザインが崩れないようにしたいことが多いので、flexプロパティを調整する機会はそんなに多くはありません。
しかし冒頭でも軽く紹介したように、使い方によっては他のCSSで調整するよりも便利な場合もあるので、そういったテクニックをご紹介していきます。

まず最初に紹介するのが、 フレックスアイテムの幅の比率を指定する際、計算せずに簡単に指定する方法です!

例として、「AとBを横並びにして、AはBの幅の1.75倍になるようにしたい」という場合を想定してみます。

この時、width で調整しようと思ったら、
1)Bのwidth × 1.75 = Aのwidth
2)Bのwidth + Aのwidth = 100(%)
という方程式を解かなければなりません。答えは、A = 約63.6% B = 約36.4% となるかと思いますが、なんだかややこしいですよね。これを flexプロパティでバシッと解決してみようと思います。

まず、AとB、特に基準となる幅があるわけではありません。指定したいのは比率だけです。ということは、flex-basis はどちらも0でOKですね。
次に、縮小率も同じで良いです。flex-basisを定めていないので、指定しても意味がありません。つまり、flex-shrink も、どちらも0でOKです。
そして最後に拡大率です。flex-basis を定めてはいませんが、flex-shrink と違って flex-grow は幅を埋めるために有効なプロパティとなります。そしてこの値はそのままフレックスアイテムの比率となるため、次のように指定するだけで計算する必要がありません。

*Aの幅はBの幅の1.75倍になる*
A { flex: 1.75 0 0 ; }
B { flex: 1 0 0 ; }


それではサンプルコードの紹介です!

    <div class="flexbox">
      <div class="flex1">
        <p>今日のニュース</p>
      </div>
      <div class="flex2">
        <p>お天気情報</p>
      </div>
    </div>


      .flexbox {
        display: flex;
        width: 80%;
        margin: 0 auto;
      }
      .flex1 {
        background-color: lightblue;
        flex: 1.75 0 0;
        text-align: center;
      }
      .flex2 {
        background-color: yellowgreen;
        flex: 1 0 0;
        text-align: center;
      }

今日のニュース

お天気情報

薄い青色の部分(今日のニュース)の幅が、黄緑色の部分(お天気情報)の幅の1.75倍になってます。
サンプルコードを見て頂くと、widthを設定することなく、1.75倍という細かい比率を簡単に設定することができているのが分かりますね!

    POINT!
  1. ・flexプロパティを使うことで、細かい幅の比率を計算せずに簡単に指定できる!
  2. ・flex-shrink と flex-basis の値を0にし、flex-grow の値を指定したい比率にすればOK!

◆ flexの有効活用(2) ◆

次に紹介するテクニックは、max-width、min-widthを使わないでフレックスアイテムの最大幅・最小幅を指定するという方法です。

*min-widthを設定せずに、最小幅を指定する*

min-widthを指定せずに最小幅を指定するには、flexプロパティを以下のように記述します。

セレクタ { flex: 1 0 最小値にしたいpx値 }

上記を踏まえた上で、サンプルコードです。親要素の幅を変えられるボタンも用意したので、ぜひ実験してみて下さいね!

    <div id="webasbparent" class="webasbparent">
      <p>親要素の幅によって伸長するけど、200px以下には縮みません。</p>
    </div>


      .webasbparent {
        width: 80%;
        margin: 0 auto;
        padding: 2rem 0;
        display: flex;
        background-color: darkblue;
      }
      .webasbparent p {
        flex: 1 0 200px;
        background-color: lightgreen;
        text-align: center;
      }

親要素の幅によって伸長するけど、200px以下には縮みません。

…普通に min-width を指定すれば良いと言われたら、まぁその通りなんですが、「基準値を超える場合は伸長させつつ、同時に最小幅を指定したい」という場合は、この方法が便利かと思います。
※デフォルトだと、flex-growの値は0なので、%でwidthを指定するか、flex-growを指定しない限り、引き伸ばされはしません。

ちなみに、逆の場合(max-widthを指定しなくても、最大幅以上に広がらないようにする)は、flex-grow と flex-shrink の値を逆にするだけです。

そしてさらにちなみにですが、flex: 0 0 300px ; というふうにすると、フレックスボックスの幅に関わらずフレックスアイテムの幅が flex-basis の値で固定されます。min-width と max-width を同時に設定するのと同じ結果になります。

    POINT!
  1. ・flexプロパティだけで、min-width max-width を使うのと同じことができる!
  2. ・flex: 0 0 幅の指定値 ; とすると、フレックスアイテムの幅を固定できる!

ワンポイントチェック

flexプロパティは、flex-grow、flex-shrink、flex-basisの3つのCSSプロパティを一括で指定できるものですが、値の未定義を防ぐ意味でもこの一括指定が推奨されています。(2021年5月現在)
flex-growだけとか、flex-shrinkだけとか、一部の値しか定義されていない場合、想定しない表示になってしまう可能性を否定できないからです。※値を定義していない場合の規定値(デフォルト値)は存在します

また、imgタグで挿入した画像のように、そのままでは幅と高さが固定されてしまう要素の場合、flexプロパティで拡大率・縮小率・基準幅を設定しても、フレックスボックスに合わせて伸び縮みしてくれません。

これはもちろん、画像の幅が固定されてしまっているからです。画像をフレックスボックスに合わせて伸び縮みさせるには、imgタグをdivタグなどで挟んで親子関係にし、親要素に対するimgタグの幅(width)を100%とするなど、一手間必要です。

また、画像の場合は「元画像の大きさ以上に拡大される場合、あまり大きくなり過ぎないようにしたい」ということもあります。(ベクター形式の画像でない限り、元の大きさの画像以上に拡大したら画質が低下します)
そういった場合、max-width を設定して一定の大きさ以上にはならないようにするという方法もありますが、それだと max-width 以上には広がらないので、画像のサイズによっては大きなモニター画面からだとやたら小さく見えてしまうということもあり得ます。

「あまり大きく拡大され過ぎないで欲しいけど、ある程度画面の大きさに合わせて拡大はして欲しい」という場合、flexプロパティが活躍してくれます。

例えば、
セレクタ { flex: 0.5 1 auto; }
とすると、画像の元のサイズまでは画面サイズに合わせて普通に拡大していきますが、元のサイズを超えると拡大率が0.5になるため、あまり拡大していかなくなります。
結果として、画面サイズに合わせて拡大はされていきますが、大きくなり過ぎるのをある程度防ぐことができます。

今回の動画で紹介したコード!

今回の解説動画で使用したコードを掲載しています。学習用としてご自由にコピペしてお使い下さい。(※スクロールできます)

<!DOCTYPE html>
<html lang="ja" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <style>
    .flexbox {
      display: flex;
    }
    .flexbox p:first-child {
      background-color: lightgrey;
    }
    .flexbox p:last-child {
      background-color: lightblue;
    }
  </style>
  <body>
    <div class="flexbox">
      <p style="flex: 1 1 300px;">flex: 1 1 300px</p>
      <p style="flex: 2 1 300px;">flex: 2 1 300px</p>
    </div>
    <div class="flexbox">
      <p style="flex: 1 0 300px;">flex: 1 0 300px</p>
      <p style="flex: 1 1 300px;">flex: 1 1 300px</p>
    </div>
    <div class="flexbox">
      <p style="flex: 1.75 0 0;">flex: 1.75 0 0</p>
      <p style="flex: 1 0 0;">flex: 1 0 0</p>
    </div>
  </body>
</html>

« »

カテゴリーリンク

著者について- author profile -

ROYDOプロフィール写真
Michihiro

モバイルアプリ(iOS・Android)ディベロッパー&デザイナー

これまでに、可読性の高いカラーパターンを自動で生成するアプリや、『第3火曜日』といった形式で通知をスケジュールできるアプリなどを制作。

サブでWebデザイン・フロントエンドエンジニアとしても活動しています。

📝ツール・言語:JavaScript/React Native/Kotlin/Android Studio/Swift/SwiftUI

🎓資格:基本情報技術者/ウェブデザイン技能検定3級

Twitterアイコン Instagramアイコン