みなさんこんにちは。先日、widthの基本について徹底的に解説しました。
そちらが大変好評でしたので、今回はさらに範囲を広げてFlexboxやCSS gridなどと組み合わさった場合について解説していこうと思います。もし上記の記事をまだ読んでない方はぜひそちらを読んでから本記事をご覧ください。
基本編
Flexboxの場合
ある要素にdisplay: flex; を指定すると、その要素はFlexboxとなります。親要素はFlexコンテナ、子要素はFlexアイテムと呼ばれます。
<div style="display: flex;"> <!-- Flexコンテナ -->
<div></div> <!-- Flexアイテム -->
<div></div> <!-- Flexアイテム -->
<div></div> <!-- Flexアイテム -->
</div>
Flexbox、特にFlexアイテムは特定の条件でwidthの値と異なる横幅になります。
一番起きやすいのは「子要素の横幅の合計が親要素をはみ出す場合、各子要素がはみ出さないように強制的に縮められる」です。言葉だけではよく分からないと思うのでデモを見せます。
コードは以下。
<div class="FlexContainer">
<div class="FlexItem"></div>
<div class="FlexItem"></div>
<div class="FlexItem"></div>
</div>
.FlexContainer {
width: 100%; /* 横幅いっぱいと指定しているのに実際の幅は違う */
display: flex;
gap: 20px;
padding: 20px;
background-color: skyblue;
}
.FlexItem {
width: 100%;
height: 200px;
background-color: pink;
}
このように、Flexアイテムの横幅は100%なのに実際は全てのアイテムがはみ出さずコンテナに収まっていますね。Flexboxはこういう仕様になっています。
また、それぞれの子要素のwidthが違う場合もコンテナに収まるように縮められます。
左から、300px、50%、200pxと指定した場合が次のデモです。
特に指定をしていなければ、要素のサイズの比率に合わせて各要素が縮小されるようです。
例えば300px、500px、200pxと並んでいれば常に3:5:2の比率は維持されます。
%やvwが絡んでいる場合は、最終的に何pxになっているかを元に計算されるようです。コンテナが1000pxなら50%と指定しているなら500pxとして扱うというわけですね。
このようにFlexboxが絡むとwidthの値と実際の横幅が異なる場合があるので注意しましょう。
また、autoの場合は要素の内容に合わせたサイズになります。fit-contentに似た挙動ですね。
Gridの場合
ある要素にdisplay: grid; を指定するとGridレイアウトになります。親要素はGridコンテナ、子要素はGirdアイテムと呼ばれます。Gridアイテムはセルと呼ばれることもありますね。
<div style="display: gird;"> <!-- Gridコンテナ-->
<div></div> <!-- Gridアイテム -->
<div></div> <!-- Gridアイテム -->
<div></div> <!-- Gridアイテム -->
</div>
Gridの場合は各セルの横幅が基準になります。デモを見てください。PC版では2列、SP版では1列にしています。
コードは以下。
<div class="GridContainer">
<div class="GridItem" style="width: 100%">100%</div>
<div class="GridItem" style="width: 50%">50%</div>
<div class="GridItem" style="width: 120px">120px</div>
<div class="GridItem">auto</div>
</div>
.GridContainer {
width: 100%;
display: grid;
justify-content: center;
grid-template-columns: 200px 200px;
grid-auto-rows: 200px;
gap: 20px;
background-color: skyblue;
}
@media (max-width: 768px) {
.GridContainer {
grid-template-columns: 200px;
}
}
.GridItem {
height: 100%;
padding: 20px;
background-color: pink;
}
セルのサイズは横幅、高さともに200pxです。これが基準になりますから、Gridアイテムをwidth: 100%; とすると200pxになりますし50%とすると100pxになります。そんなに難しくありませんね。
autoも通常の挙動と同じです。
使い方編
ではFlexboxもしくはGridの時にwidthはどう扱うと良いでしょうか。デモを使いながら説明します。ブラウザの横幅を変えながら挙動の違いを確認してください。
例えば画像とテキストが横並べになるレイアウトを考えます。画像は画像分のサイズを、残りの部分をテキストの領域で埋める形です。
Flexboxの場合
基本的には画像に横幅を指定し、テキスト側はflex: 1という指定するパターンになると思います。少しwidthの話とは離れますが、flex: 1; という指定を行うと余った領域を埋めるように広がります。
画像側のサイズは割と自由に決めて問題ないです。
width: 30%;
width: 200px;
ちなみにテキスト側がwidth: auto; だと横幅がコンテンツ分だけになってしまいます。
Gridの場合
Gridの時は列を決める段階で横幅を指定する形になるので、実はwidthはあまり重要ではありません。Gridアイテムのwidthはとりあえず100%にしておけば列と同じ幅になります。
また、Flexboxにおけるflex: 1; と同様の効果を持つものに1frという指定があります。grid-template-columnsで列の横幅を決める時に1frとすると余った領域を埋めるように広がります。
<div class="GridSample">
<img
class="GridSample-Image"
width="400"
height="244"
src="https://itokoba.com//asset-files/close-up-of-businesspeople-working-with-documents.png"
/>
<div class="GridSample-Text">
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</div>
</div>
.GridSample {
width: 100%;
display: grid;
grid-template-columns: 30% 1fr; /* 親の横幅に対して、30%分の列と残りの横幅全部の列ができる */
}
.GridSample-Image {
width: 100%; /* Gridの場合はとりあえずwidth: 100%; にしておけば列と同じ幅になる */
height: 100%;
object-fit: cover;
}
.GridSample-Text {
width: 100%; /* Gridの場合はとりあえずwidth: 100%; にしておけば列と同じ幅になる */
padding: 20px;
background-color: #eee;
}
上記のコードで次の見た目になります。
意外とFlexboxよりシンプルですね。実は高さ指定の方がクセがあったりするのですが、それはまた別の記事で。
まとめ
というわけでFlexboxやGridが絡んだ時のwidthについてでした。それぞれ近年出てきたレイアウト方式で、widthの扱い方も微妙に異なってきます。
細かい違いを知らないことでレイアウト崩れの原因にならないようしっかり覚えておきましょう。
コメント