widthの正体を暴く(Flexbox, Grid編)

HTML/CSSを学ぶ

みなさんこんにちは。先日、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の比率は維持されます。

300
500
200

%やvwが絡んでいる場合は、最終的に何pxになっているかを元に計算されるようです。コンテナが1000pxなら50%と指定しているなら500pxとして扱うというわけですね。

このようにFlexboxが絡むとwidthの値と実際の横幅が異なる場合があるので注意しましょう。

また、autoの場合は要素の内容に合わせたサイズになります。fit-contentに似た挙動ですね。

auto

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列にしています。

100%
50%
120px
auto

コードは以下。

<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はどう扱うと良いでしょうか。デモを使いながら説明します。ブラウザの横幅を変えながら挙動の違いを確認してください。

例えば画像とテキストが横並べになるレイアウトを考えます。画像は画像分のサイズを、残りの部分をテキストの領域で埋める形です。

Lorem ipsum dolor sit amet consectetur adipisicing elit.

Flexboxの場合

基本的には画像に横幅を指定し、テキスト側はflex: 1という指定するパターンになると思います。少しwidthの話とは離れますが、flex: 1; という指定を行うと余った領域を埋めるように広がります。

画像側のサイズは割と自由に決めて問題ないです。

width: 30%;

Lorem ipsum dolor sit amet consectetur adipisicing elit.

width: 200px;

Lorem ipsum dolor sit amet consectetur adipisicing elit.

ちなみにテキスト側がwidth: auto; だと横幅がコンテンツ分だけになってしまいます。

Lorem ipsum dolor sit amet consectetur adipisicing elit.

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;
}

上記のコードで次の見た目になります。

Lorem ipsum dolor sit amet consectetur adipisicing elit.

意外とFlexboxよりシンプルですね。実は高さ指定の方がクセがあったりするのですが、それはまた別の記事で。

まとめ

というわけでFlexboxやGridが絡んだ時のwidthについてでした。それぞれ近年出てきたレイアウト方式で、widthの扱い方も微妙に異なってきます。

細かい違いを知らないことでレイアウト崩れの原因にならないようしっかり覚えておきましょう。

参考

フレックスボックス - ウェブ開発を学ぶ | MDN
フレックスボックス (Flexbox) は、アイテムを行または列に並べるための 1 次元のレイアウト方法です。アイテムがたわんで(伸びて)追加の空間を埋めたり、縮んで小さい空間に収まったりします。この記事では、すべての基本事項について説明します。
CSS グリッドレイアウト - CSS: カスケーディングスタイルシート | MDN
CSS グリッドレイアウトは、ページを大きな領域に分割することや、 HTML のプリミティブから構成されたコントロールの部品間の、寸法、位置、レイヤーに関する関係を定義することに優れています。

コメント

タイトルとURLをコピーしました