6歳娘「パパ、flexにしたら幅が余っちゃったよ・・・」


flex-growflex-shrinkのお話です。

ある日の我が家

娘(6歳)「ねぇ、パパ?」

ワイ「なんや、娘ちゃん?」

娘「パパはいつも、お仕事でどれくらいコードを書いてるの?」

ワイ「どれくらいって、沢山やで」
ワイ「それはもう山のように書いてるで」

娘「へー、山のようにかぁ」
娘「動かざること山の如しって感じ?」

ワイ「そうそう、ワイのコードはたいがい動かへん・・・コラッ!」
ワイ「誰がバグ製造機やねん」

娘「ところで、そんなパパに聞きたいことがあるの」

ワイ「なんや?」

お買い物サイト製作中

娘「実は今ね」
娘「お友だちから受注したショッピングサイトを制作してるの」

ワイ「受注て」
ワイ「最近の6歳児は受発注すんのかい」
ワイ「まあええわ、そんでどうしたんや」

娘「えっとね」
娘「今、デザインデータを見ながらコーディングをしてるんだけど」

娘「↑このデザインが、CSSで上手く再現できないの」

ワイ「そうなんか」
ワイ「ちなみに、今どこまでできてるん?」

娘「えっと、説明するね」
娘「まずは最初にね」

娘「↑こんな感じになっちゃったの」

ワイ「ほうほう」

娘「ちなみにHTMLはこんな感じ」

  <figure class="box">
    <div class="img">
      <img src="images/candy.png" alt="アメ玉">
    </div>
    <figcaption class="caption">
      <div class="item-info">
        <div>アメ玉(1個)</div>
        <div>¥1,000(税別)</div>
      </div>
      <p>甘くて美味しいアメ玉です</p>
    </figcaption>
  </figure>

ワイ「なるほどな」
ワイ「boxっていうクラス名がついた親要素があって」
ワイ「その中に画像ゾーン商品説明ゾーンが入っとるわけやな」

娘「そんな感じ」
娘「それで、画像ゾーンと商品説明ゾーンを横並びにしたかったから」
娘「親要素をdisplay: flex;にしてみたの」

css
    .box {
      width: 500px;
      border: 3px solid;
      border-radius: 6px;
      overflow: hidden;
++    display: flex;
    }

娘「↑こんな感じ」

ワイ「なるほどな」

娘「でも、そしたらね」
娘「横並びにはなったんだけど───」

娘「↑こう、右側が160pxくらい余っちゃったの」
娘「ほんとは、商品説明ゾーンが伸びてくれるといいんだけど・・・」

そんな時はflex-grow

ワイ「なるほどな」
ワイ「そんな時はこうや」

css
    .img {
      width: 120px;
      height: 120px;
      background-color: paleturquoise;
++    flex-grow: 0;
    }

    .caption {
      background-color: bisque;
      padding: 10px;
++    flex-grow: 1;
    }

娘「へー」
娘「画像ゾーンをflex-grow: 0;にして」
娘「商品説明ゾーンをflex-grow: 1;にしてやるんだね」

ワイ「せや」
ワイ「そうすると───」

ワイ「↑こうや」

娘「ほんとだ」
娘「ちゃんと商品説明ゾーンが伸びてくれたね」

ワイ「せや」

flex-growとは

ワイ「つまり、flex-growいうのは───」

ワイ「余った空間を埋めるために、子要素を伸ばしたい!」
ワイ「160pxくらい余ってるから、その160pxを」
ワイ「画像ゾーンと商品説明ゾーンに0:1の割合で分けてあげたいんや!」

ワイ「ってときに使う感じやな」
ワイ「ちなみにgrow伸びるって意味やで」

娘「なるほどね」
娘「0:1の割合にしたから」
娘「商品説明ゾーンだけが伸びてくれたんだね」

ワイ「せや」

娘「じゃあ、1:1の割合にしたら」
娘「画像ゾーンと商品説明ゾーンが、両方とも80pxずつ伸びるってこと?」
娘「ちょっとやってみよ」

css
    .img {
      width: 120px;
      height: 120px;
      background-color: paleturquoise;
++    flex-grow: 1;
    }

    .caption {
      background-color: bisque;
      padding: 10px;
++    flex-grow: 1;
    }

娘「↑こうすると───」

娘「あ、ほんとだ」
娘「画像ゾーンも商品説明ゾーンも、両方80pxくらい伸びた」

ワイ「そういうことやな」
ワイ「ちなみにflex-growのデフォルト値は0やから」

css
    .img {
      width: 120px;
      height: 120px;
      background-color: paleturquoise;
      /* flex-grow: 0; */
    }

ワイ「↑こんな感じで、flex-grow: 0;は書かんくてもええで」

娘「なるほどね」
娘「商品説明ゾーンの方だけを伸ばしたい場合は」
娘「商品説明ゾーンをflex-grow: 1;にして」
娘「画像ゾーンはflex-grow指定なしでいいんだね」

ワイ「そういうことやな」

娘「ありがとう、パパ!」

ワイ「ゲヘヘ、かまへん!かまへん!」

しかし、またまた問題が

娘「パパ、大変!」

娘「試しに、商品説明ゾーンのwidth1000pxにしてみたら」
娘「アメちゃんの横幅が小さくなっちゃったの!」

ワイ「(なぜそんな無駄なことをした・・・?)」
ワイ「ああ、スペースが足りんと子要素たちは縮んでしまうからな」

娘「どうすればいいの・・・?」

そんな時はflex-shrink

ワイ「そんな時は、縮めたくない子要素にflex-shrink: 0;を指定してやるんや」

css
    .img {
      width: 120px;
      height: 120px;
      background-color: paleturquoise;
++    flex-shrink: 0;
    }

ワイ「↑こうやな」

娘「あ、直った!」

ワイ「shrink縮むって意味やから」

ワイ「縮みを0にしてくれや!」

ワイ「って感じやな」

娘「なるほどね」

ワイ「flex-shrinkは、初期値が1になっててな」
ワイ「スペースが足りない場合、子要素たちはデフォルトで縮んでしまうんや」

娘「そっか」
娘「縮めたくない子要素にはflex-shrink: 0;を指定すればいいんだね」

ワイ「そういうことやな」

ちなみに

娘「パパ、例えばスペースが200px足りない場合には」
娘「2つの子要素が100pxずつ縮むの?」

ワイ「いや、2つの子要素にflex-shrink: 1;を指定したとしても」
ワイ「1:1の割合で100pxずつ縮むわけではないんや」
ワイ「大きい要素と小さい要素があるのに、両方とも100pxずつ縮むと」
ワイ「小さい方の要素が0pxになってしまうこともあるからな」
ワイ「そこは、大きい方の要素が多めに縮んでくれたりするんや」

娘「そっか」

大きい要素「ワイは元々の図体がデカイから、多めに縮んどくわ・・・」

娘「↑こんな感じなんだね」

ワイ「せやな」

まとめ

  • flex-grow
    • 空間が余った場合の、子要素達の伸び具合を調整する
    • 親要素ではなく、子要素に指定する
    • 0だと伸びない
    • 大きい数値を指定するとよく伸びる
    • 初期値は0
  • flex-shrink
    • 空間が足りない場合の、子要素達の縮み具合を調整する
    • 親要素ではなく、子要素に指定する
    • 0だと縮まない
    • 大きい数値を指定するとよく縮む
    • 初期値は1

ワイ「って感じやな」
ワイ「floatで横並びにしてた時代に比べると、だいぶ便利になったもんや」

娘「ふろうと・・・?」
娘「将来のパパのこと?」

ワイ「いやそれは浮浪者・・・コラッ!」
ワイ「誰が浮浪者見習いやねん」
ワイ「floatや、float
ワイ「昔はfloatで横並びにしてたんや」

娘「へ〜」

それにしても

ワイ「それにしても、アメ玉が1個1,000円ってどうなん?」
ワイ「売れへんのとちゃう?」

娘「えっとね、たぶん大丈夫だよ」
娘「近所の駄菓子屋のアメ玉をぜんぶ買い占めて
娘「このショッピングサイトで売るの」
娘「だから近所の子たちは、このサイトで買うしかないの」
娘「だから大丈夫なの」

ワイ「いやそれ転売ヤーやないかい」
ワイ「なんも大丈夫とちゃうわ」

娘「パパ、おまわりさんには内緒だよ?」

ワイ「ええ加減にせぇ」
ワイ「やめさせてもらうわ」

〜ありがとうございました〜

参考サイト