この翻訳は不完全です。英語から この記事を翻訳 してください。

CSS グリッドレイアウトはレイアウトを行うための完全なシステムの一部として、CSSの他の機能と一緒に動作するよう設計されました。このガイドでは、既に使われている他の技術と、どうのようにグリッドが適合するかを説明します。

グリッドとフレックスボックス

CSS グリッドレイアウトとCSS フレックスボックスレイアウトの基本的な違いは、フレックスボックスは一次元 - 一列又は一行 - のレイアウトのために設計されたという点です。グリッドは二次元 - 行と列が同時 - のレイアウトのために設計されました。しかし、2つの仕様書はいくつかの共通の機能を共有しており、すでにフレックスボックスの使い方を学んでいるのであれば、類似性がグリッドの手がかりを助けるでしょう。

一次元 vs. ニ次元レイアウト

一次元と二次元のレイアウトの違いを示すことができる単純な例です。

最初の例では、一連のボックスを配置するためにフレックスボックスを使用しています。コンテナーの中には五つの子項目があり、 flex プロパティ値を与えて200ピクセルの flex-basis から伸縮できるようにしています。

flex-wrap プロパティを wrap に設定して、コンテナーの大きさが細くなりすぎて flex basis を維持することができなくなったら、項目が次の行へ折り返されるようにしています。

<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
.wrapper {
  display: flex;
  flex-wrap: wrap;
}
.wrapper > div {
  flex: 1 1 200px;
}

図では、2つの項目が新しい行へ折り返されているのがわかると思います。これらの項目は利用可能なスペースを共有していますが、上記の項目の下には整列してはいません。 flex アイテムが折り返しをした時、新しい行(もしくは列として機能している時は列)のそれぞれが flex コンテナーになるからです。スペースの配分は行をまたがって起こります。

よくある質問はそれらのアイテムをどのようにして並べるかです。2次元レイアウトメソッドが必要な場所では、行またはカラムによるアラインメントのコントロールが必要で、グリッドが得意な場面です。

CSS グリッドによる同様のレイアウト

次の例では、グリッドを使って同様のレイアウトを構築します。今回は3つの 1fr 列トラックを持ちます。項目自体には何もセットする必要はりません。構築されたグリッドのセルそれぞれに項目を一つずつ配置していきます。厳格なグリッドに項目が配置されているため、行と列は整列しています。5つの項目があるので、二つ目の行にある終わりには隙間があります。

<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

グリッドとフレックスボックスのどちらを使うかを決めるシンプルな質問です。

  • 又は列のみによってレイアウトを制御する必要がありますか。 – フレックスボックスを使いましょう
  • 及び列によりレイアウトを制御する必要がありますか。 - グリッドを使いましょう

コンテンツ外かレイアウト内か?

1次元 vs 2次元の区別に加えて、レイアウトのためにフレックスボックス又はグリッドを使わなければならないかどうかを決める別の方法があります。フレックスボックスはコンテンツ外から機能します。フレックスボックスの理想的な使用例は、コンテナー内で項目に等しくスペースを設定したいような場合です。コンテンツのサイズはそれぞれの項目がどのくらい個々のスペースを占めるかにより決定されます。もし項目が新しい行へ折り返されたら、行のサイズと利用可能なスペースをもとに項目の間隔が算出されます。

グリッドはレイアウトの外から機能します。 CSS グリッドレイアウトを使ってレイアウトを作った際、自動配置ルールでアイテムを厳格なグリッドによるセルへ配置させることができます。それらはコンテンツのサイズに応じたトラックを作ることができます。しかしながら、全体のトラックも変わるでしょう。

もしフレックスボックスを使っていていくつかの柔軟性が欠けていたら、おそらく CSS グリッドレイアウトを使う必要性を感じるでしょう。例えばフレックスアイテムの幅をパーセンテージで設定し、ある行へその他の項目とともに整列させていたら、その場合にはグリッドはより良い選択肢になるでしょう。

ボックスアラインメント

フレックスボックスの最も素晴らしい特徴は、我々に適切なアラインメント制御を与えてくれる最初のものということでした。これによりページの真ん中にボックスを置くことが簡単になりました。 flex 要素は flex コンテナの高さに引き伸ばすことができ、これはつまり、同じ高さの列が可能ということです。これらのものは我々が長い間求めていたもので、この視覚効果を生み出す多くのハックが考え出されてきました。

フレックスボックスの仕様によるアラインメントプロパティは Box Alignment Level 3 と呼ばれる新しい仕様に追加されました。これはつまり、グリッドレイアウトを含む他の仕様でも使用できるということです。将来的には、他のレイアウト手法にも適用できるようになるでしょう。

この一連のガイドの後、ボックスアラインメントと、それがグリッドレイアウトの中でどのように動作するのかを見ていきます。今回の場合、フレックスボックスと grid の簡単な比較例を挙げます。

一つ目のフレックスボックスを利用する例では、3つの要素を持つコンテナがあります。コンテナであるwrapperにはmin-heightが設定され、これはflexコンテナの高さを決めています。コンテナには align-itemsflex-end に設定してコンテナの終端に要素が並ぶようにしました。また、box1align-selfプロパティをcontainerの高さに合わせるようstreachへ上書きし、box2もコンテナの始まりから整列するにように上書きしています。

<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
</div>
.wrapper {
  display: flex;
  align-items: flex-end;
  min-height: 200px; 
}
.box1 {
  align-self: stretch;
}
.box2 {
  align-self: flex-start;
}

CSSグリッド上でのアラインメント

二つ目の例ではグリッドを使って同じレイアウトを作りましょう。今回はグリッドレイアウトを使うため、ボックスアラインメントプロパティを使います。従って、flex-startflex-endではなくstartendを使ってアラインメントします。グリッドレイアウトのケースでは、グリッド領域の中にアイテムをアラインメントしていきます。今回のケースでは単一のグリッドセルを作成していますが、これは複数のグリッドセルで構成された領域にもなることが可能です。

<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: repeat(3,1fr);
  align-items: end;
  grid-auto-rows: 200px;
}
.box1 {
  align-self: stretch;
}
.box2 {
  align-self: start;
}

fr単位とflex-basis

すでにfr単位がグリッドコンテナ内の利用可能な領域の比率を、グリッドのトラックへどのように割り当てるかを見てきました。minmax()関数と合わさったとき fr単位はフレックスボックスのflexプロパティと非常に似た振る舞いをしながら、2次元のレイアウトを作ることができます。

If we look back at the example where I demonstrated the difference between one and two-dimensional layouts, you can see there is a difference between the way of the two layouts work responsively. With the flex layout, if we drag our window wider and smaller, the flexbox does a nice job of adjusting the number of items in each row according to the available space. If we have a lot of space all five items can fit on one row. If we have a very narrow container we may only have space for one.

In comparison, the grid version always has three column tracks. The tracks themselves will grow and shrink, but there are always three since we asked for three when defining our grid.

Auto-filling grid tracks

We can create a similar effect to flexbox, while still keeping the content arranged in strict rows and columns, by creating our track listing using repeat notation and the auto-fill and auto-fit properties.

In this next example, I have used the auto-fill keyword in place of an integer in the repeat notation and set the track listing to 200 pixels. This means that grid will create as many 200 pixels column tracks as will fit in the container.

<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fill, 200px);
}

柔軟なトラック数

This isn’t quite the same as flexbox. In the flexbox example, the items are larger than the 200 pixel basis before wrapping. We can achieve the same in grid by combining auto-fill and the minmax() function. In this next example, I create auto filled tracks with minmax. I want my tracks to be a minimum of 200 pixels, so I set the maximum to be 1fr. Once the browser has worked out how many times 200 pixels will fit into the container–also taking account of grid gaps–it will treat the 1fr maximum as an instruction to share out the remaining space between the items.

<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

We now have the ability to create a grid with a flexible number of flexible tracks, but see items laid out on the grid aligned by rows and columns at the same time.

グリッドと絶対位置指定された要素

Grid interacts with absolutely positioned elements, which can be useful if you want to position an item inside a grid or grid area. The specification defines the behavior when a grid container is a containing block and a parent of the absolutely positioned item.

含有ブロックとしてのグリッドコンテナ

To make the grid container a containing block you need to add the position property to the container with a value of relative, just as you would make a containing block for any other absolutely positioned items. Once you have done this, if you give a grid item position: absolute it will take as its containing block the grid container or, if the item also has a grid position, the area of the grid it is placed into.

In the below example I have a wrapper containing four child items. Item three is absolutely positioned and also placed on the grid using line-based placement. The grid container has position: relative and so becomes the positioning context of this item.

<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">
   This block is absolutely positioned. In this example the grid container is the containing block and so the absolute positioning offset values are calculated in from the outer edges of the area it has been placed into.
  </div>
  <div class="box4">Four</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: repeat(4,1fr);
  grid-auto-rows: 200px;
  grid-gap: 20px;
  position: relative;
}
.box3 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
  position: absolute;
  top: 40px;
  left: 40px;
}

You can see that the item is taking the area from grid row line 2 to 4, and starting after line 1. Then it is offset in that area using the top and left properties. However, it has been taken out of flow as is usually for absolutely positioned items and so the auto-placement rules now place items into the same space. The item also doesn’t cause the additional row to be created to span to row line 3.

If we remove position: absolute from the rules for .box3 you can see how it would display without the positioning.

親としてのグリッドコンテナ

If the absolutely positioned child has a grid container as a parent but that container does not create a new positioning context, then it is taken out of flow as in the previous example. The positioning context will be whatever element creates a positioning context as is common to other layout methods. In our case, if we remove position: relative from the wrapper above, positioning context is from the viewport, as shown in this image.

Image of grid container as parent

Once again the item no longer participates in the grid layout in terms of sizing or when other items are auto-placed.

With a grid area as the parent

If the absolutely positioned item is nested inside a grid area then you can create a positioning context on that area. In the below example we have our grid as before but this time I have nested an item inside .box3 of the grid.

I have given .box3 position relative and then positioned the sub-item with the offset properties. In this case, the positioning context is the grid area.

<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three
    <div class="abspos">
     This block is absolutely positioned. In this example the grid area is the containing block and so the absolute positioning offset values are calculated in from the outer edges of the grid area.
    </div>
  </div>
  <div class="box4">Four</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: repeat(4,1fr);
  grid-auto-rows: 200px;
  grid-gap: 20px;
}
.box3 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
  position: relative;
}
.abspos {
  position: absolute;
  top: 40px;
  left: 40px;
  background-color: rgba(255,255,255,.5);
  border: 1px solid rgba(0,0,0,0.5);
  color: #000;
  padding: 10px;
}

グリッドと display: contents

A final interaction with another layout specification that is worth noting is the interaction between CSS Grid Layout and display: contents. The contents value of the display property is a new value that is described in the Display specification as follows:

“The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children and pseudo-elements in the document tree.”

If you set an item to display: contents the box it would normally create disappears, and the boxes of the child elements appear as if they have risen up a level. This means that children of a grid item can become grid items. Sound odd? Here is a simple example. In the following markup, I have a grid and the first item on the grid is set to span all three column tracks. It contains three nested items. As these items are not direct children, they don’t become part of the grid layout and so display using regular block layout.

<div class="wrapper">
  <div class="box box1">
    <div class="nested">a</div>
    <div class="nested">b</div>
    <div class="nested">c</div>
  </div>
  <div class="box box2">Two</div>
  <div class="box box3">Three</div>
  <div class="box box4">Four</div>
  <div class="box box5">Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
}
.box1 {
  grid-column-start: 1;
  grid-column-end: 4;
}

If I now add display: contents to the rules for box1, the box for that item vanishes and the sub-items now become grid items and lay themselves out using the auto-placement rules.

<div class="wrapper">
  <div class="box box1">
    <div class="nested">a</div>
    <div class="nested">b</div>
    <div class="nested">c</div>
  </div>
  <div class="box box2">Two</div>
  <div class="box box3">Three</div>
  <div class="box box4">Four</div>
  <div class="box box5">Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
}
.box1 {
  grid-column-start: 1;
  grid-column-end: 4;
  display: contents;
}

This can be a way to get items nested into the grid to act as if they are part of the grid, and is a way around some of the issues that would be solved by subgrids once they are implemented. You can also use display: contents in a similar way with flexbox to enable nested items to become flex items.

As you can see from this guide, CSS Grid Layout is just one part of your toolkit. Don’t be afraid to mix it with other methods of doing layout, to get the different effects you need.

ドキュメントのタグと貢献者

タグ: 
このページの貢献者: 8845musign, mfuji09, nekobato
最終更新者: 8845musign,