CSS グリッドレイアウトのボックス配置

CSS グリッドレイアウトは Box Alignment Level 3 仕様を実装します。これはそのフレックスコンテナの中でアイテム配置のために使う flexbox (ブレックスボックス)  と同じ仕様です。この仕様には、異なるレイアウトメソッドすべての配置方法の詳細があります。レイアウトメソッドは、可能なら仕様に準拠し、その違い(機能と制約)に基づいて個々の振る舞いを実装します。現在、仕様書にはすべてのレイアウトメソッドの詳細がありますが、ブラウザーの実装は完全ではありません。しかしながら、CSS グリッドレイアウトメソッドは広く実装されています。

このガイドでは、グリッドレイアウトにおけるボックス配置がどのように機能するのか説明します。フレックスボックスのプロパティと値の機能と多くの類似点があります。しかし、グリッドは二次元、フレックスボックスは一次元であるため、いくつか小さな違いがあることに気をつけてください。それではグリッド内のものを配置するときに使う 2 つの軸について見ていきましょう。

グリッドレイアウトの 2 つの軸

グリッドレイアウトでは、ブロック軸インライン軸という 2 つの軸を利用できます。ブロック軸は、ブロックレイアウトでブロックが配置される軸です。ページ内に 2 つのパラグラフがある場合、上から下に向かって並べられますので、この方向がブロック軸となります。

インライン軸はブロック軸に交差する軸です。通常、テキストはインライン方向に向かって並べられます。

中身はグリッドエリアの中に並べることができ、グリッドトラック自体が 2 つの軸の上にあります。

ブロック軸上でのアイテムの配置

align-selfalign-items プロパティは、ブロック軸上の配置をコントロールします。これらはグリッドエリアの中のアイテムの配置を変更します。

以下の例には、4 つのグリッドエリアがあります。グリッドコンテナ上で align-items プロパティと次の値の一つを使い、アイテムを配置しています。

  • auto
  • normal
  • start
  • end
  • center
  • stretch
  • baseline
  • first baseline
  • last baseline
.wrapper {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 10px;
  grid-auto-rows: 100px;
  grid-template-areas: 
    "a a a a b b b b"
    "a a a a b b b b"
    "c c c c d d d d"
    "c c c c d d d d";
  align-items: start;
}
.item1 {
  grid-area: a;
}
.item2 {
  grid-area: b;
}
.item3 {
  grid-area: c;
}
.item4 {
  grid-area: d;
}
<div class="wrapper">
  <div class="item1">Item 1</div>
  <div class="item2">Item 2</div>
  <div class="item3">Item 3</div>
  <div class="item4">Item 4</div>
</div>

align-self: start を設定すると、それぞれの子 <div> の高さは <div> の中身によって決定されることを覚えておいてください。対照的に、align-items を完全に省略すると、それぞれの子 <div> の高さはグリッドエリアを満たすように広がります。

align-items プロパティはすべての子グリッドアイテムに align-self プロパティを設定します。これは、グリッドアイテム上で align-self を使えばプロパティを個別に設定できるということです。

次の例では、align-self プロパティを使い、様々な配置の値を実験します。最初のエリアで見られるのは align-self のデフォルトの振る舞いで、引き伸ばされています。2 つ目のアイテムは align-selfstart 値を持っており、3 つ目は end 、4 つ目は center です。

.wrapper {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 10px;
  grid-auto-rows: 100px;
  grid-template-areas: 
    "a a a a b b b b"
    "a a a a b b b b"
    "c c c c d d d d"
    "c c c c d d d d";
}
.item1 {
  grid-area: a;
}
.item2 {
  grid-area: b;
  align-self: start;
}
.item3 {
  grid-area: c;
  align-self: end;
}
.item4 {
  grid-area: d;
  align-self: center;
}
<div class="wrapper">
  <div class="item1">Item 1</div>
  <div class="item2">Item 2</div>
  <div class="item3">Item 3</div>
  <div class="item4">Item 4</div>
</div>

固有のアスペクト比を持つアイテム

デフォルトでは、align-self の振る舞いはアイテムを広げます。しかし、固有のアスペクト比を持つアイテムの振る舞いは start になります。固有のアスペクト比を持つアイテムにデフォルトで stretch を設定するとアイテムを歪めるからです。

この振る舞いは現在、仕様で明確になっていますが、ブラウザーへの実装はまだ途上です。それまでの間、align-selfjustify-selfstart に設定することによって、グリッドの直接の子である画像などのアイテムが、デフォルトで広がらないことを保証できます。これは正しい動作を模倣します。

インライン軸上のアイテムの位置揃え

align-itemsalign-self がブロック軸上でアイテムの配置を処理するように、justify-itemsjustify-self は、インライン軸上で同じ動作をします。選べる値は align-self と同じです。

  • auto
  • normal
  • start
  • end
  • center
  • stretch
  • baseline
  • first baseline
  • last baseline

以下では、align-items と同様の例を見ることができます。今回は justify-self を適用しています。

ここでもデフォルトは、固有のアスペクト比を持つアイテム以外、stretch です。配置の設定を変更しない場合、グリッドアイテムはグリッドエリアをカバーします。例の最初のアイテムはデフォルトの配置を表しています。

.wrapper {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 10px;
  grid-auto-rows: 100px;
  grid-template-areas: 
    "a a a a b b b b"
    "a a a a b b b b"
    "c c c c d d d d"
    "c c c c d d d d";
}
.item1 {
  grid-area: a;
}
.item2 {
  grid-area: b;
  justify-self: start;
}
.item3 {
  grid-area: c;
  justify-self: end;
}
.item4 {
  grid-area: d;
  justify-self: center;
}
<div class="wrapper">
  <div class="item1">Item 1</div>
  <div class="item2">Item 2</div>
  <div class="item3">Item 3</div>
  <div class="item4">Item 4</div>
</div>

align-selfalign-items と同様に、グリッドコンテナに justify-items を適用することで、すべてのアイテムに justify-self の値を設定できます。

justify-selfjustify-items プロパティはフレックスボックスに実装されていません。これはフレックスボックスが一次元であること、軸にそって複数のアイテムがあるかもしれず単一のアイテムを両端揃えすることができないことによります。フレックスボックスのメイン軸・インライン軸に沿って配置するには、justify-content プロパティを使用します。

ショートハンドプロパティ

place-items プロパティは align-itemsjustify-items のショートハンドであり、place-selfalign-selfjustify-self のショートハンドです。

エリア内のアイテムを中央に揃える

align プロパティと justify プロパティを組み合わせると、グリッドエリアの中でアイテムを簡単に中央揃えすることができます。

.wrapper {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  grid-auto-rows: 200px;
  grid-template-areas: 
    ". a a ."
    ". a a .";
}
.item1 {
  grid-area: a;
  align-self: center;
  justify-self: center;
}
<div class="wrapper">
 <div class="item1">Item 1</div>
</div>

ブロック軸上のグリッドトラックの配置

グリッドトラックが使うエリアがグリッドコンテナより小さければ、コンテナ内にグリッドトラック自体を配置できます。繰り返しますが、これはブロック軸とインライン軸上で行われます。align-content はブロック軸上のトラックを配置し、justify-content はインライン軸上の配置を行います。place-content プロパティは align-contentjustify-content のショートハンドです。align-contentjustify-contentplace-content の値は次の通りです。

  • normal
  • start
  • end
  • center
  • stretch
  • space-around
  • space-between
  • space-evenly
  • baseline
  • first baseline
  • last baseline

以下の例では 500 ピクセル × 500 ピクセルのグリッドコンテナがあります。3 つの行トラックと列トラックがあり、それぞれ、幅 100 ピクセル、溝 10 ピクセルです。これはグリッドコンテナ内でブロックとインラインどちらの方向にも空間があることを意味します。

align-content プロパティはグリッド全体のグリッドコンテナに適用されます。グリッドレイアウトでのデフォルトの振る舞いは start で、これにより、グリッドトラックはグリッドの左上隅にあり、グリッドラインの始まりに対して整列しています。

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  height: 500px;
  width: 500px;
  gap: 10px;
  grid-template-areas: 
    "a a b"
    "a a b"
    "c d d";
}
.item1 {
  grid-area: a;
}
.item2 {
  grid-area: b;
}
.item3 {
  grid-area: c;
}
.item4 {
  grid-area: d;
}
<div class="wrapper">
  <div class="item1">Item 1</div>
  <div class="item2">Item 2</div>
  <div class="item3">Item 3</div>
  <div class="item4">Item 4</div>
</div>

コンテナに align-content を追加し、値を end に設定すると、トラックは、すべてブロック方向の中でグリッドコンテナが終わるラインに移動します。

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  height: 500px;
  width: 500px;
  gap: 10px;
  grid-template-areas: 
    "a a b"
    "a a b"
    "c d d";
  align-content: end;
}
.item1 {
  grid-area: a;
}
.item2 {
  grid-area: b;
}
.item3 {
  grid-area: c;
}
.item4 {
  grid-area: d;
}
<div class="wrapper">
  <div class="item1">Item 1</div>
  <div class="item2">Item 2</div>
  <div class="item3">Item 3</div>
  <div class="item4">Item 4</div>
</div>

フレックスボックスのようにスペース配分する値、space-betweenspace-aroundspace-evenly を使うこともできます。align-contentspace-between に更新すると、グリッド上の要素がどう配置されるかを確認できます。

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  height: 500px;
  width: 500px;
  gap: 10px;
  grid-template-areas: 
    "a a b"
    "a a b"
    "c d d";
  align-content: space-between;
}
.item1 {
  grid-area: a;
}
.item2 {
  grid-area: b;
}
.item3 {
  grid-area: c;
}
.item4 {
  grid-area: d;
}
<div class="wrapper">
  <div class="item1">Item 1</div>
  <div class="item2">Item 2</div>
  <div class="item3">Item 3</div>
  <div class="item4">Item 4</div>
</div>

スペース配分の値を使用すると、グリッド上のアイテムが大きくなる可能性があることに注意してください。アイテムが複数のグリッドトラックにまたがる場合、トラック間にさらにスペースを追加すると、アイテムはその分大きくなる必要があります。グリッドは常に厳密です。したがって、これらの値を使用する場合は、トラックの内容が追加のスペースに対応できるようにするか、整列プロパティを使用して引き伸ばさず始点に置くようにします。

下の図では、align-contentstart で配置したグリッドの隣に、align-contentspace-between に設定して配置したグリッドがあります。2 つのトラックの間にスペースを取るとき、2 つの行トラックにまたがる Item 1 と 2 が どのように余分な高さを確保しているか見てください。

space-between を使用したときアイテムがどのように大きくなるかのデモ。

インライン軸上のグリッドトラックの位置揃え

ブロック軸で align-content を使うのと同様に、インライン軸では justify-content を使うことができます。

同じ例を使って、justify-contentspace-around を設定してみましょう。やはり、1 つ以上の列トラックにまたがるトラックが余分なスペースを得ることになります。

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  height: 500px;
  width: 500px;
  gap: 10px;
  grid-template-areas: 
    "a a b"
    "a a b"
    "c d d";
  align-content: space-between;
  justify-content: space-around;
}
.item1 {
  grid-area: a;
}
.item2 {
  grid-area: b;
}
.item3 {
  grid-area: c;
}
.item4 {
  grid-area: d;
}
<div class="wrapper">
  <div class="item1">Item 1</div>
  <div class="item2">Item 2</div>
  <div class="item3">Item 3</div>
  <div class="item4">Item 4</div>
</div>

配置と自動マージン

エリアの中でアイテムを配置する別の方法は、自動マージンを使用することです。コンテナブロックの左右のマージンを auto に設定すると、ビューポート内でレイアウトを中央に配置できます。既に知っているように、自動マージンは空きスペースのすべてを吸収します。両側のマージンを auto に設定すると、両マージンはスペースのすべてを取るよう試みるため、ブロックは中央に押し込まれます。

次の例では、Item 1 に auto の左マージンを与えます。自動マージンは、そのアイテムのコンテンツ用の空間が割り当てられた後に残りのスペースを取るため、コンテンツがエリアの右側に押し出されます。どのように押し出されるか見てみましょう。

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  height: 500px;
  width: 500px;
  gap: 10px;
  grid-template-areas: 
    "a a b"
    "a a b"
    "c d d";
}
.item1 {
  grid-area: a;
  margin-left: auto;
}
.item2 {
  grid-area: b;
}
.item3 {
  grid-area: c;
}
.item4 {
  grid-area: d;
}
<div class="wrapper">
  <div class="item1">Item 1</div>
  <div class="item2">Item 2</div>
  <div class="item3">Item 3</div>
  <div class="item4">Item 4</div>
</div>

Firefox Grid Highlighter を使って、どのようにアイテムが整列されるか見てみましょう。

Grid Highlighter を使って自動マージンを見ている画像。

整列と書字方向

ここまでのすべての例は英語を使ったものであり、これは左から右へ書く言語です。物理方向で考えるとき、行の始点はグリッドの左上になります。

CSS グリッドレイアウトとボックス配置の仕様は、CSS の書字方向と共に機能するようデザインされています。アラビア語などの右から左へ書く言語で作業する場合、グリッドの始点は右上になり、justify-content: start のデフォルトはグリッドトラックがグリッドの右手側から始まるようになるでしょう。

margin-right または margin-left で自動マージンを使用した場合、および toprightbottomleft を使って位置を絶対指定した場合、書字方向が尊重されません。次のガイドでは、CSS グリッドレイアウト・ボックス配置と書字方向の間における相互作用を見ていきます。複数の言語で表示するサイトを開発したり、言語や書字方向を混ぜたサイトをデザインするなら、非常に役立つでしょう。