【プログラミング独学21日目】flex-grow・flex-shrink
こんにちは、歯科衛生士・ママライターのミホです。以前から独学でWordPressを使ったサイト制作は行なってきたのですが、改めてプログラミングをしっかり学ぼうと思い学習を始めました。その記録や学習してわからなかったことなどをアウトプットしていきます。毎日インプット・アウトプットを続けて21日目を迎えました。
私の今までの経歴は、以下で簡単に説明しています。元々医療従事者なのでわりと特殊な経歴かと思います。
今後の目標は以下の通りで、忘れないためにも毎日書き留めておきます。
- プログラミング案件も受注できるようになりたい
- 歯科衛生士エンジニアを目指したい
- コーディングもライティングもできる歯科衛生士
【プログラミング独学21日目】学んだこと
今日もCSSの続きをやりました。引き続きflexboxの学習で、flex-itemに付けられるプロパティについてです。
①flex-itemに付けられるプロパティ/flex-grow
復習になりますが、flex-containerに付けられるプロパティとflex-itemに付けられるプロパティは以下の通りです。
flex containerに付けられるプロパティ
- flex-direction
- justify-content
- align-items
- flex-wrap
- align-content
flex itemに付けられるプロパティ
- align-self
- order
- flex-basis
- flex-grew
- flex-shrink
flex-containerに付けられるプロパティは以下で詳しくまとめています。
flex-itemに付けられるプロパティは以下の2つとこの記事でまとめていきます。
flex-growは主軸方向に余白があるときに、それぞれの要素をどれだけ伸ばすか指定するためのプロパティです。例えば以下のような記述があったとします。
<body>
<div class="container">
<div class="box box1">ボックス1</div>
<div class="box box2">ボックス2</div>
<div class="box box3">ボックス3</div>
</div>
</body>
.container{
width:360px;
display:flex;
}
.box{
width:100px;
}
コンテナ幅360pxの中に、横幅100pxのボックスが3つ横並びで並んでいます。つまりボックス1〜3の3つを合わせた横幅は300pxで、コンテナ幅は60px余白があるということになります。
.box {
flex-grow:1;
}
このとき上のように記述すると、セレクターが「. box」なのでボックス1〜3すべてに「flex-grow:1」が適用されます。これは余白である60pxをボックス1:ボックス2:ボックス3に1:1:1で分配するという意味になります。つまり20pxずつ分け合うことになり、ボックス1〜3はそれぞれ20pxずつ伸び、120pxずつになるということです。
.box1 {
flex-grow:0;
}
.box2 {
flex-grow:1;
}
.box3 {
flex-grow:2;
}
つまり上のように記述すると、余白である60pxをボックス1:ボックス2:ボックス3に0:1:2で分配するという意味になります。このとき「0」は分配されない=元の大きさのままということになり、実質60pxをボックス2とボックス3のみで1:2で分け合うということになります。したがってボックス1の横幅は100pxのまま、ボックス2の横幅は120px、ボックス3の横幅は140pxとなります。
なお以下のように各ボックスではなく、1つのボックスだけに指定することもよくあります。
.box1{
flex-grow:1;
}
これは「余白ができたら全てbox1にあげて」という意味なので、間接的にbox2とbox3はflex^grow:0という意味になります。
②flex-itemに付けられるプロパティ/flex-growの初期値
flex-growの初期値は0で、この場合余白があっても要素を伸ばさない(=余白を埋めようとしなくて良い)という意味になります。
③flex-itemに付けられるプロパティ/flex-shrink
flex-shrinkはflex-growと逆で、コンテナ幅に対してボックスの横幅が大きく収まりきらない(スペースが足りない)ときに、どの要素をどれだけ縮めるかという指定に使うプロパティです。例えば以下のような記述があったとします。
<body>
<div class="container">
<div class="box box1">ボックス1</div>
<div class="box box2">ボックス2</div>
<div class="box box3">ボックス3</div>
</div>
</body>
.container {
width:240px;
display:flex;
}
.box {
width:100px;
}
コンテナ幅240pxの中に、横幅100pxのボックスが3つ横並びで並んでいます。つまりボックス1〜3の3つを合わせた横幅は300pxで、コンテナ幅より60pxオーバーしていることになります。
.box{
flex-shrink:0;
}
上のように記述すると要素は縮めない(オーバーしていてもそのままでOK)という意味になり、ボックスの横幅は変わりません。なおCSSの記述によりスペースが足りており、余白がある場合はflex-shrinkを記述しても無効となりました。
独学に限界を感じたらプログラミングスクールに通っても良いかなと思っています。「programmer college」は完全無料のプログラミングスクールで、レッスンだけでなく就活支援まで手厚くサポートしてくれるのが嬉しい点です。なぜ完全無料?怪しくない?と思いましたが、企業から協賛金を募ることで無料スクールが実現しているそうです。どの学習ソフトも有料なので、無料で学べてしかも就活直結ってありがたいですよね。
▼完全無料のプログラミングスクール
④flex-itemに付けられるプロパティ/flex-shrinkの初期値
flex-shrinkの初期値は1で、この場合スペースが足りなかったら均等に調節してコンテナ幅に収まって(=なんとかして今あるスペースに収まって)という意味になります。このように書くとややこしいですが、「1」や「0」の考え方はflex-growと同じです。
.box{
flex-shrink:1;
}
例えば上の記述では、足りていない60px分をボックス1:ボックス2:ボックス3が1:1:1の割合で縮むことでコンテナ幅に収めようという意味になります。
⑤flex-itemに付けられるプロパティを一括指定
昨日学んだflex-basis、今日学んだflex-grow、flex-shrinkは一括指定プロパティでまとめて書くことができます。
.box{
flex:1 1 100px;
}
上のように記述すると、以下の記述と同じ意味になります。
.box{
flex-grow:1;
flex-shrink:1;
flex-basis:100px;
}
なお復習になりますが、flex-containerの一括指定プロパティは「flex-flow」で、flex-directionとflex-wrapを一括して指定することができます。詳しくは以下でまとめています。
⑥flex-itemに付けられるプロパティ/flex-initial
一括指定プロパティflexを使う方法以外にも、以下のように指定する方法があります。
.box1{
flex:initial;
}
上のように記述するとそれぞれの初期値が設定され、以下と同じ意味になります。
.box1{
flex-grow:0;
flex-shrink:1;
flex-basis:auto;
}
つまり「余白ができても幅を変えないで、ただスペースが足りなかった場合は縮めてコンテナ幅に収めて」という意味になります。
⑦flex-itemに付けられるプロパティ/flex-auto
.box1{
flex:auto;
}
上のように記述すると、以下と同じ意味になります。
.box1{
flex-grow:1;
flex-shrink:1;
flex-basis:auto;
}
つまり「余白ができたら幅を広げて、スペースが足りなかったら縮めてコンテナ幅に収めて」という意味になります。
⑧flex-itemに付けられるプロパティ/flex-none
.box1{
flex:none;
}
上のように記述すると、以下と同じ意味になります。
.box1{
flex-grow:0;
flex-shrink:0;
flex-basis:auto;
}
つまり「余白ができてもスペースが足りなくても、幅を変えないで」という意味になります。勝手にサイズ変更しないで!という意味ですね。
⑨実践でよく見られるのはflex:1
今までいくつも解説してきましたが、実践や現場でよく見られるのは以下のような記述です。
.box1{
flex:1;
}
このときの「flex」は「flex-grow」を意味しており、書き換えると以下と同じ意味になります。
.box{
flex-grow:1;
flex-shrink:1;
flex-basis:0%;
}
flex-shrinkは初期値ですが、注意すべきはflex-basisの値で、初期値のautoではなく「0%」です。flex-basis:0%は、ボックスモデル内に要素幅が無い=全てが余白である状態を指します。
.box1{
flex-grow:1;
}
.box2{
flex-grow:1;
}
.box3{
flex-grow:2;
}
つまり上のような記述があった場合、ボックス1〜3が割り当てられた数字通りに1:1:2の幅で並ぶことになります。今まで見てきたflex-growでは余白を1:1:2で分けていたので幅がよくわかりませんでしたが、flex-grow:1とすることで全ての余白を3つのボックスで分けてねという意味になり、その割合がそのまま幅に反映されます。ややこしいですが理解しておくと便利です。
独学に限界を感じたらプログラミングスクールに通っても良いかなと思っています。「programmer college」は完全無料のプログラミングスクールで、レッスンだけでなく就活支援まで手厚くサポートしてくれるのが嬉しい点です。なぜ完全無料?怪しくない?と思いましたが、企業から協賛金を募ることで無料スクールが実現しているそうです。どの学習ソフトも有料なので、無料で学べてしかも就活直結ってありがたいですよね。
▼完全無料のプログラミングスクール
【プログラミング独学21日目】わからなかったこと・調べてわかったこと
今日学んで疑問が残った部分は以下です。
- flex-grow・flex-shrinkの「初期値」の定義
- 要素がコンテナ幅をオーバーするってどういう状況?
- flex-grow・flex-shrinkが共存するってどういう状況?
flex-grow・flex-shrinkの「初期値」の定義
「初期値」や「デフォルト」という状態は、「そのプロパティ名を記述して内容は何も指定しないこと」なのか「そのプロパティについて何も記述しなくても適用される」という意味なのかよくわかりませんでした。そのためこんがらがっていたのですが、前者の「そのプロパティ名を記述して何も指定しないこと」は以下のような状態のことを言うので、起こり得ないというかそのような記述方法は無い・不可能という理解で合っているのか疑問です(現実的に考えて合っていると思いますが)。
.box1 {
flex-grow
}
理解が合っていれば「そのプロパティ名を記述して何も指定しないこと」は起こり得ないので、「初期値」や「デフォルト」という状態=「そのプロパティについて何も記述しなくても適用される」なんだと思います。
- flex-growの初期値=0=「余白ができても幅変えないで」
- flex-shrinkの初期値=1=「スペース足りなかったらなんとか収めて」
flex-growの初期値=0=「余白ができても幅変えないで」を先に習ったこと、また「flex-shrinkはflex-growの逆で〜」という説明もあったため、flex-shrinkの初期値=「スペースが足りなくても幅変えないで」だと思っていたんですよね。だから「なぜ初期値1なのに幅変わらないの?とどツボにはまっていました。
ただ今書きながら思い返しても、このような発想は自然では?と思います。ただコンテナ幅をオーバーしているのに幅を変えないまま表示する・・・という方が無理がある(と思うようにしておく)ので、flex-shrinkの初期値=1=「スペース足りなかったらなんとか収めて」で覚えておきます。flex-shrinkの初期値=1なので、0である「幅変えないで」にはならないこともアウトプットしながら気付けました。
ひとまず1=幅を変える、0=幅を変えないという理解は合っていると思うので、そこだけ注意しておきたいと思います。
要素がコンテナ幅をオーバーするってどういう状況?
flex-growの余白がある状態は想像できるのですが、flex-shrinkの要素がコンテナ幅をオーバーするってどういう状況・・・?と思いました。他の部分においても状況が想像できないことが何ヵ所かあったのですが、ひとまず以下のことが言えるようです。
ユーザーによってブラウザ幅は変わる。パソコンの画面の大きさや、パソコンから見ているかスマホから見ているかなどによっても変わる。それによってコンテナ幅も変わる。コンテナ幅が変わることで要素が収まるか収まらないか、余白ができるか逆にスペースが足りなくなるかも変わってくる。
参考ドットインストール
flex-grow・flex-shrinkが共存するってどういう状況?
一括指定プロパティのflexのところで、flex-growとflex-shrinkが共存しており、flex-growの「余白ができている状態」と、flex-shrinkの「スペースが足りない状態(余白が無い状態)」が共存しているってどういう状況・・・?と思いました。同じように思った方もいて、先生の回答はやはり以下のようなものでした。
ユーザーによってブラウザ幅は変わるので、コンテナ幅もユーザーによって変わります。コンテナ幅が変わることで余白ができたり逆にスペースが足りなかったり両方起こり得るので、両方指定します。
参考ドットインストール
ここでやっと気付いたのですが、コンテナ幅などの「width」「height」プロパティの単位は「px」だけではありません。「%」や「em」もあり、「%」の場合その親要素のサイズに対する割合となります。数日前に習ったことですね、毎日学びが多すぎて記憶が薄れがちです。プログラミング独学10日目で習った内容でした。以下でまとめています。
ただ疑問が残ってしまったのは、今回widthと一緒にheightも100%にしてみたところ上手く反映されなかったという点です。%は親要素に対する割合で、<container>の親要素は<body>。そのためブラウザの高さいっぱいにcontainerが設定されると思ったのですが、なぜか要素(ボックス)の高さとなっていました。MDNを見ても解決できなかったので、ひとまず保留として次へ進んでいこうと思います。