フレックスアイテムの伸縮率などを指定できる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!
- ・flexプロパティは、フレックスアイテムに flex-grow flex-shrink flex-basis を一括指定できる!
- ・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!
- ・flexプロパティを使うことで、細かい幅の比率を計算せずに簡単に指定できる!
- ・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!
- ・flexプロパティだけで、min-width max-width を使うのと同じことができる!
- ・flex: 0 0 幅の指定値 ; とすると、フレックスアイテムの幅を固定できる!