flex-grow,flex-shrinkについて〜flexプロパティ前編。

〽️ 「比率」を指定するということ。





挙動不信なflexプロパティ。

こんにちは、「ふ」です。
CSSのflexbox、とても便利ですね!出逢えてから自分のページにおいても使いまくっています。そんな中・・


理解に苦しむプロパテーがある。


それはflexプロパティなるものです。子要素の伸び縮みを指定するもののようですが、何を基準に算出されているのかがまったくわかりませんでした。

今回はこのflexプロパティを散々いじり倒して判明したことを書きたいと思います。長〜くなりそうなので、前後編に渡ってお送りします。




初期状態。


子要素が2つあるflexboxで考えて行きましょう。

HTML

親要素を「parent」、その中に「ao」と「daidai」の2つの子要素を配置しました。
ここで

.parent { display:flex }

としたときに、内部的に3つのflexプロパティが適用されます。



flexプロパティ
flex-grow 初期値:0
flex-shrink 初期値:1
flex-basis 初期値:auto

ブラウザ


プレビューがこちら。色などのCSSは省略しています。
この3つのflexプロパティのうち、前編ではflex-grow、flex-shrinkについて説明していきたいと思います。



flex-grow。

子要素を配置した際に余白ができた場合を考えます。

.ao { width:20%; } .daidai { width:20%; }

ブラウザ

親要素に60%の余白ができました。
ここは青と橙の幅を広げて、余白を埋めたい。そのときの比率、

「青を広げる割合」:「橙を広げる割合」

を設定するのが、flex-growプロパティです。



プロパティを指定してみます。

.ao { width:20%; 「「1flex-grow:2;」」 } .daidai { width:20%; 「「5flex-grow:1;」」 }

こうすると、

青のgrow : 橙のgrow = 2:1

ということになります。結果は下の通り。

ブラウザ

余白60%のうち、青が40%の広がりを負担し、橙が20%の広がりを負担しました。「余白を埋めるための負担の割合」が2:1ですね。




今度は1:1の場合。

.ao { width:20%; 「「1flex-grow:1;」」 } .daidai { width:20%; 「「5flex-grow:1;」」 }
青のgrow : 橙のgrow = 1:1


ブラウザ

余白60%を1:1、すなはち30%ずつを仲良く分け合って広がりました。これは5:5としても3:3としても結果は同じものとなります。




今度は、青にだけ1未満の値を設定をしてみます。

.ao { width:20%; 「「1flex-grow:0.5;」」 } .daidai { width:20%; 「「5//指定なし。初期値の0が適用される;」」 }
青のgrow : 橙のgrow = 0.5:0


ブラウザ

余白60%のうちの半分の30%を青が負担して広がりましたが、橙のgrowは「0」なので一切広がりません。
flex-growに1未満の値を指定すると、余白を「1」としたときの比率で縮んでいます。今回の場合は

余白(1):青のgrow(0.5)

となるので、余白60%のうち半分の30%を青が負担して広がることになります。これは不思議な挙動ですね。






flex-shrink。


flexboxは子要素が親要素からはみ出す場合、子要素を縮めてbox内に収めようとします。はみ出した部分を青と橙が縮むことによって親要素内に収まりたい。そのときの

「青が負担する縮み」 : 「橙が負担する縮み」

の比率を決めるのが、flex-shrinkです。




親要素から100%分はみ出すように、子要素の幅を設定してみます。

.ao { width:100%; } .daidai { width:100%; }

もし仮に、親要素にflexboxが適用されていないと、上のようになるはずです。

でもflexboxの立場しては(←?)、はみ出した100%のぶんを縮めなくてはならない。
青と橙がどれくらいずつ負担して縮むのかを設定します。


.ao { width:100%; 「「1flex-shrink:2;」」 } .daidai { width:100%; 「「5flex-shrink:3;」」 }

「青の負担する縮み」 : 「橙の負担する縮み」 = 2:3



ブラウザ

はみ出し100%のうち、青は40%の縮みを負担したため、もとのwidthの60%になりました。 一方橙は60%の縮みを負担したため、元のwidthの40%になりました。




扨(さて)、flex-shrinkのデフォルト値は「1」です。

.ao { width:100%; 「「1//shrink指定なし;」」 } .daidai { width:100%; 「「5//shrink指定なし;」」 }

そうするとCSSに値を指定しない場合、

「青の負担する縮み」:「橙の負担する縮み」 = 1:1

となります。プレビューをみてみましょう。



ブラウザ

はみ出し100%を仲良く50%ずつ負担して縮みます。




青を1未満、橙を0としてみます。

.ao { width:100%; 「「1flex-shrink:0.5;」」 } .daidai { width:100%; 「「5flex-shrink:0;」」 }
「青の負担する縮み」:「橙の負担する縮み」 = 0.5:0


ブラウザ

はみ出し100%分を1とした時の0.5、すなはち50%のはみ出しは青が負担してちゃんと縮みました。
一方橙の負担は0なので、一切縮む気をおこしてくれません。
これはflex-growの時と同じ挙動ですね。






ややこしかったね。

flex-growにしろflex-shrinkにしろ、とてもややこしやなプロパティでした。拙い説明でしたが、ご理解いただけたでしょうか?
「ふ」なりの言葉でまとめてみます。

flex-grow
flexboxに余白ができたとき、子要素たちの幅を広げることによって埋めてあげたい。
その「余白分」を各子要素がどれくらいずつ負担して広がるのか。その「比率」を指定します。



flex-shrink
flexboxから子要素がはみ出してしまったとき、子要素たちの幅を縮めることによってbox内にちゃんと収まるようにしたい。
その「はみ出し分」を各子要素がどれくらいずつ負担して縮まるのか。その「比率」を指定します。

そしてその「値」は、普段CSSで使っているような「絶対値(pxなど)」や「相対値(%など)」ではなく、子要素同士が負担する「比率」を指定することになります。←ここがややこしくなる原因の1つでした。




flexプロパティ、現在執筆中の後半に続きます。











「ふ」です。

swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。

🐧 twitter 🐧