グリッドレイアウト

グリッドレイアウトを極める 12

2022年1月15日

スクリーン幅によってカラムが変動するレイアウト

flex コンテナの横幅に合わせてカラム数が切り替わるレイアウト

<div class="flex-wrapper">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
</div>
   

flex: 1 0 300px を指定することで、横幅が300px以下にならず、Flexコンテナに合わせて幅が伸びるFlexアイテムを設定する。

flex: 1 0 300px を指定した検証

.flex-wrapper {
  display: flex;
  flex-wrap: wrap;
}
.flex-wrapper .item {
  flex: 1 0 300px;
}

flex-wrap: wrap;

Flexboxで作成したレイアウトでは、Flexアイテムの横幅の合計がFlexコンテナの幅を超えても横並びのまま連なる。そのため、Flexコンテナに flex-wrap: wrap; を指定して、幅がオーバーした分のFlexアイテムを改行させることができる。

flex-wrap: wrap; を指定した検証

このように幅が広くなりすぎたら折り返すようにしたい場合は、flex-wrap プロパティを追加して wrap の値を設定するか、一括指定の flex-flow を使用して row wrap または column wrap の値を設定する必要がある。

flex: [flex-grow] [flex-shrink] [flex-basis];

1つ目の値で、flex-grow に1を指定することで、Flexコンテナの横幅に合わせFlexアイテムの幅が均等に伸びるようになる。2つ目の値では、flex-shrink に0を指定して、flexアイテムが基準値(flex-basisで設定した値)より縮まないように設定している。3つ目の値では、flex-basis でFlexアイテムの基準となる幅を300pxに指定している。

flex-grow

flex-grow のプロパティは、フレックスコンテナー内の残りの空間のうち、どれだけがそのアイテムに割り当てられるか (フレックス伸長係数) を設定する。既定値は 0 。

flex-shrink

flex-shrink のプロパティは、フレックスアイテムの縮小係数を設定する。すべてのフレックスアイテムの寸法がフレックスコンテナーよりも大きい場合、アイテムは flex-shrink の数値に従って縮小して収まる。プロパティの値に0を指定すると、そのアイテムは縮まなくなる。

flex-basis

flex-basis プロパティは、自動拡大縮小設定を行うための content キーワードまたは <'width'> で幅を指定する。例えば flex-basis が 200px の場合、最初は 200px で表示されるが、他のアイテムが最低でも min-content の大きさであることを考慮して、利用可能な空間に合わせて縮小される。基本的に幅を指定する際には、widthを指定するが、flex-basisを指定した際には、 flex-basisプロパティが優先される。

さて、ここで一次元と二次元の確認。

フレックスボックスは一次元のレイアウトとして設計されており、つまりアイテムを行または列として扱う。しかし、同時ではない。フレックスアイテムを新しい行に折り返し、 flex-direction が row の場合は新しい行を、 flex-direction が column の場合は新しい列を生成する。

2 次元でのレイアウトが必要な場合は、おそらくグリッドレイアウトを使用する。上記の折り返し行の例を CSS グリッド版のレイアウトと比較すると、違いが分かり易い。次のサンプルでは、CSS グリッドレイアウトを使用して、160 ピクセル以上の列が収まるだけのレイアウトを作成し、余分な空間をすべての列に分配している。ただし、この場合、アイテムはグリッド内に留まり、最終行のアイテム数が少なくなっても伸びることはない。

グリッドレイアウトを使用した場合の検証

イメージの個々の比率を保持して縦へ、横へ、一列に並べる。幅に因ってカラムを変える

(1).複数のイメージを個々の比率を保持しながら縦一列に並べる。つまり幅20%のイメージを積み重ねる。

<div class="row">
  <div class="column">
    <img src="images/www.jpg" style="width:100%">
    <img src="images/xxx.png" style="width:100%">
    <img src="images/yyy.jpg" style="width:100%">
    <img src="images/zzz.jpg" style="width:100%">
  </div>
</div>
.row {
  display: flex;
  flex-wrap: wrap;
}
.column {
  flex-basis: 20%;
  padding: 0 4px;
}
.column img {
  margin-top: 8px;
  vertical-align: middle;
  border: 2px solid; 
}

(2).複数のイメージを個々の比率を保持しながら横一列に並べる。つまり幅20%のイメージをfloat: left; を使うように横へ並べる。

<div class="row">
  <div class="column">
    <img src="images/www.jpg" style="width:100%">
  </div>
  <div class="column">
    <img src="images/xxx.png" style="width:100%">
  </div>
  <div class="column">
    <img src="images/yyy.jpg" style="width:100%">
  </div>
  <div class="column">
    <img src="images/zzz.jpg" style="width:100%">
  </div>
</div>

(3).一つ目の(1)で縦一列に並べた一塊 <div class="column"> を丸ごとコピーして一つ目の下へ三回ペーストして追加するとで縦に四つ並ぶことになる。そしてイメージを再指定する。

(4).メディアクエリで画面幅に応じてカラム数を指定すると以下のようなレイアウトが完成する。

@media (orientation: portrait) and (min-width:320px) {
  .column {
    flex-basis: 100%;
    max-width: 100%;
  }
}
  @media (orientation: landscape) and (min-width:568px) {
  .column {
    flex-basis: 50%;
    max-width: 50%;
  }
}
@media (orientation: portrait) and (min-width:720px) {
  .column {
    flex-basis: 50%;
    max-width: 50%;
  }
}
@media (orientation: landscape) and (min-width:1024px) {
  .column {
    flex-basis: 25%;
    max-width: 25%;
  }
}