CSS グリッド レイアウト (「グリッド」とも呼ばれる) は、2 次元のグリッド レイアウトに基づくシステムであり、その主な目的は、グリッドに基づいてユーザー インターフェイスを設計する方法を変更することです。ご存知のとおり、CSS は Web ページのスタイルを設定するために常に使用されますが、あまりうまく機能しません。最初はテーブルを使用し、次にフロート、位置、およびインラインブロックを使用しましたが、これらのメソッドはすべて本質的にハックであり、機能上多くの重要な問題 (垂直方向のセンタリングなど) が残されています。 Flexbox は一定の救済的な役割を果たすことができますが、実装できるのは単純な 1 次元レイアウトのみであり、複雑な 2 次元レイアウトには適していません (実際、Flexbox と Grid を併用すると最良の結果が得られます)。 Grid は、Web サイトを作成するときにハックを使用して使用していたレイアウトの問題を解決するために特別に作成された CSS の最初のモジュールです。
このガイドを作成するきっかけとなったものが 2 つあります。 1 冊目は、Rachel Andrew の素晴らしい本、 Getting Ready for CSS Grid Layout です。この本は Grid を詳しくわかりやすく紹介しています。Grid の基礎知識を習得したい場合は、ぜひ購入することをお勧めします。もう 1 つの大きなインスピレーションは、Chris Coyier の『The Complete Guide to Flexbox』から得ました。この本は、Flexbox について学ぶための優れたリソースです。また、ここで付け加えておきたいのは、Google で「フレックスボックス」を検索すると、同様のリソースがたくさん表示されますが、最適なものを利用してみてはいかがでしょうか。
このガイドを書く目的は、最新バージョンに基づいてグリッドの概念を標準化することです。したがって、古い IE 構文については再度言及しません。仕様が成熟するにつれて、このガイドを定期的に更新するように努めます。
Grid を始めるのは簡単です。必要なのは、コンテナー要素を定義して表示を設定することだけです。grid、grid-template-columns プロパティと Grid-template-rows プロパティを使用してグリッドの列と行のサイズを設定し、次に Grid-column と Grid- row プロパティを使用して、子要素のサイズをグリッドに設定します。フレックスボックスと同様に、グリッド項目のソース順序は重要ではありません。グリッドとメディア クエリをより適切に統合するには、メディア クエリを CSS 内の任意の場所に配置できます。ページ全体のレイアウトを定義し、それを別の画面幅に合わせて完全に再配置したいとすると、これはわずか数行の CSS コードで実行できます。 Grid は、これまでに導入された中で最も強力な CSS モジュールの 1 つです。
Grid について注意すべき重要な点は、まだプロジェクトでの使用には適していないということです。これは現在 W3C で草案段階にあり、すべてのブラウザでデフォルトでサポートされているわけではありません。サポートは Internet Explorer 10 および 11 ですでに利用可能ですが、古い構文を使用しています。ここで、デモンストレーションのために、特別なフラグを有効にして Chrome、Opera、または Firefox を使用することをお勧めします。 Chrome で、chrome://flags に移動し、「Web 実験プラットフォーム機能」を有効にします。このメソッドは Opera ( opera://flags ) でも機能します。 Firefox では、layout.css.grid.enabled フラグを有効にします。
ブラウザのサポート表は次のとおりです (後で更新し続けます):
Microsoft に加えて、ブラウザのメーカーも、Grid 仕様が成熟するまでそれを宣伝するのを待ちたいと考えているようです。これは、複数の構文を学習することを心配する必要がないことを意味するため、良いことです。
グリッドの使用を待つのは時間の問題です。しかし今、あなたはそれを学び始める必要があります。
グリッドについて詳しく説明する前に、関連する用語の概念を理解する必要があります。ここで関係する用語は概念的に似ているため、グリッド仕様の関連する定義を最初に覚えていないと、別の概念と簡単に混同してしまう可能性があります。しかし、ここにはそれほど多くの物件はありませんので、ご安心ください。
要素が display: Grid 属性を設定すると、その要素はすべての Grid アイテムの親要素になります。次の例では、コンテナーはグリッド コンテナーです。
<div class="container"> <div class="item item-1"></div> <div class="item item-2"></div> <div class="item item-3"></div></div>
グリッドコンテナの子(子要素など)。ここでは、項目要素はすべてグリッド項目ですが、サブ項目は含まれません。
<div class="container"> <div class="item"></div> <div class="item"> <p class="sub-item"></p> </div> <div class="item"></div></div>
境界線はグリッドの構造を構成します。これらは垂直 (「列グリッド線」) または水平 (「行グリッド線」) にすることができ、行または列のどちらかの側に存在します。下の画像の黄色の線は、柱グリッド線の例です。
2 つの隣接するグリッド ライン間のスペース。これらはグリッドの行または列として考えることができます。以下に、グリッド線の 2 行目と 3 行目の間のグリッド トラックを示します。
隣接する 2 つの行と隣接する 2 つの列の間のグリッド線のスペース。グリッドの「単位」です。以下の画像は、行グリッド線 1 と 2、列グリッド線 2 と 3 の間のグリッド セルを示しています。
四条网格线所包围的所有空间。网格区域可由任意数量的网格单元格组成。下面图片所示的是行网格线 1 和 3 和列网格线 1 和 3 之间的网格区域。
定义一个元素成为网格容器,并对其内容建立一个网格格式的上下文。
.container{ display: grid | inline-grid }
注: column , float , clear , 和 vertical-align 元素对网格容器不起作用。
利用以空格分隔的值定义网格的列和行。值的大小代表轨道的大小,并且它们之间的空格表示网格线。
.container{ grid-template-columns: <track-size> ... | <line-name> <track-size> ... | subgrid; grid-template-rows: <track-size> ... | <line-name> <track-size> ... | subgrid;}
当你在值之间留有空格时,网络线就会自动分配数值名称:
.container{ grid-template-columns: 40px 50px auto 50px 40px; grid-template-rows: 25% 100px auto;}
但是你也可以显示命名,请参考下面括号语法中的名称命名方式:
.container{ grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end]; grid-template-rows: [row1-start] 25% [row1-end] 100% [third-line] auto [last-line];}
请注意,一条网格线可以具有有多个名称。例如,这里的第二行将有两个名字: row1-end 和 row2-start :
.container{ grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];}
如果你的定义中包含重复的部分,你可以使用 repeat() 表示法进行精简:
.container{ grid-template-columns: repeat(3, 20px [col-start]) 5%;}
等效于:
.container{ grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;}
fr 单位允许你将一个轨道大小设置为网格容器内自由空间的一小部分。如下所示,每个网格项就会占据网格容器宽度的三分之一:
.container{ grid-template-columns: 1fr 1fr 1fr;}
这里自由空间表示除去非弹性项以后剩余的空间。在此示例中的 fr 单位的可用空间表示减去 50px 以后的空间大小:
.container{ grid-template-columns: 1fr 50px 1fr 1fr;}
使用 grid-area 属性定义网格区域名称,从而定义网格模板。网格区域重复的名称就会导致内容跨越这些单元格。句点表示一个空单元格。语法本身提供了一种可视化的网格结构。
.container{ grid-template-areas: "<grid-area-name> | . | none | ..." "..."}
.item-a{ grid-area: header;}.item-b{ grid-area: main;}.item-c{ grid-area: sidebar;}.item-d{ grid-area: footer;}.container{ grid-template-columns: 50px 50px 50px 50px; grid-template-rows: auto; grid-template-areas: "header header header header" "main main . sidebar" "footer footer footer footer"}
这将创建一个四列三行的网格。最上面的一行为 header 区域。中间一行由两个 main 区域,一个空单元格和一个 sidebar 区域。最后一行是 footer 区域。
你所声明的每一行都需要具有相同数目的单元格。
你可以使用任意数量的句点( . )声明单个空单元格。只要句点之间没有空格就表示一个空单元格。
注意,你只是使用此语法进行网格区域命名,而不是网格线命名。当你使用此语法时,区域两边的线就会得到自动命名。如果网格区域名称为 foo ,则其行线和列线的名称就将为 foo-start ,最后一行线及其最后一列线的名字就会为 foo-end 。这意味着一些线就可能具有多个名称,如上面示例中所示,拥有三个名称: header-start , main-start , 以及 footer-start 。
指定网格线的大小。你可以把它想像成在行/列之间设置间距宽度。
.container{ grid-column-gap: <line-size>; grid-row-gap: <line-size>;}
.container{ grid-template-columns: 100px 50px 100px; grid-template-rows: 80px auto 80px; grid-column-gap: 10px; grid-row-gap: 15px;}
间距仅仅在列/行之间产生,而不会在边缘区。
grid-column-gap 和 grid-row-gap 的简写值。
.container{ grid-gap: <grid-column-gap> <grid-row-gap>;}
.container{ grid-template-columns: 100px 50px 100px; grid-template-rows: 80px auto 80px; grid-gap: 10px 15px;}
如果没有指定 grid-row-gap 属性的值,默认与 grid-column-gap 属性值相同
沿列轴对齐网格项中的内容(相反于 align-item 属性定义的沿行轴对齐)。此值适用于容器内所有的网格项。
.container{ justify-items: start | end | center | stretch;}
.container{ justify-items: start;}
.container{ justify-items: end;}
.container{ justify-items: center;}
.container{ justify-items: stretch;}
这也可以使用 justify-self 属性对各个网格项进行设置。
沿行轴对齐网格项中的内容(相反于 justify-item 属性定义的沿列轴对齐)。此值适用于容器内所有的网格项。
.container{ align-items: start | end | center | stretch;}
.container{ align-items: start;}
.container{ align-items: end;}
.container{ align-items: center;}
.container{ align-items: stretch;}
这也可以使用 align-self 属性对各个网格项进行设置。
当你使用 px 这种非响应式的单位对你的网格项进行大小设置时,就有可能出现一种情况--你的网格大小可能小于其网格容器的大小。在这种情况下,你就可以设置网格容器内网格的对齐方式。此属性会将网格沿列轴进行对齐(相反于 align-content 属性定义的沿行轴对齐)。
.container{ justify-content: start | end | center | stretch | space-around | space-between | space-evenly; }
.container{ justify-content: start;}
.container{ justify-content: end; }
.container{ justify-content: center; }
.container{ justify-content: stretch; }
.container{ justify-content: space-around; }
.container{ justify-content: space-between; }
.container{ justify-content: space-evenly; }
当你使用 px 这种非响应式的单位对你的网格项进行大小设置时,就有可能出现一种情况--你的网格大小可能小于其网格容器的大小。在这种情况下,你就可以设置网格容器内网格的对齐方式。此属性会将网格沿行轴进行对齐(相反于 justify-content 属性定义的沿列轴对齐)。
.container{ align-content: start | end | center | stretch | space-around | space-between | space-evenly; }
.container{ align-content: start; }
.container{ align-content: end; }
.container{ align-content: center; }
.container{ align-content: stretch; }
.container{ align-content: space-around; }
.container{ align-content: space-between; }
.container{ align-content: space-evenly; }
指定任何自动生成的网格轨道(隐式网格跟踪)的大小。当你显式定位行或列(使用 grid-template-rows / grid-template-columns 属性)时,就会产生超出定义范围内的隐式网格轨道。
.container{ grid-auto-columns: <track-size> ...; grid-auto-rows: <track-size> ...;}
为了说明隐式网格轨道是如何被创造出来的,请思考如下代码:
.container{ grid-template-columns: 60px 60px; grid-template-rows: 90px 90px}
这里创建了一个 2 x 2 的网格。
但是现在你想象你使用 grid-column 和 grid-row 来定位网格项,如下所示:
.item-a{ grid-column: 1 / 2; grid-row: 2 / 3;}.item-b{ grid-column: 5 / 6; grid-row: 2 / 3;}
这里我们定义 .item b 开始于列线 5 并结束于在列线 6 ,但是我们从来没有定义列线 5 或 6 。因为我们引用不存在的线,宽度为 0 的隐式轨道的就会被创建用来填补空白。我们可以使用 grid-auto-columns 和 grid-auto-rows 属性来设置这些隐式轨道的宽度:
.container{ grid-auto-columns: 60px;}
如果你不显式的在网格中放置网格项,自动布局算法就会自动踢出此网格项。此属性用来控制自动布局算法的工作原理。
.container{ grid-auto-flow: row | column | row dense | column dense}
注意: dense 值可能会导致更改网格项的顺序。
考虑如下HTMl代码:
<section class="container"> <div class="item-a">item-a</div> <div class="item-b">item-b</div> <div class="item-c">item-c</div> <div class="item-d">item-d</div> <div class="item-e">item-e</div></section>
这里定义了一个两列五行的网格,并将 grid-auto-flow 属性设置为 row (即默认值):
.container{ display: grid; grid-template-columns: 60px 60px 60px 60px 60px; grid-template-rows: 30px 30px; grid-auto-flow: row;}
将网格项放置在网格中时只需要其中的两个网格项:
.item-a{ grid-column: 1; grid-row: 1 / 3;}.item-e{ grid-column: 5; grid-row: 1 / 3;}
因为我们将 grid-auto-flow 属性设置为了 row ,所以我们的网格看起来会像这个样子。注意我们我们没有对其进行设置的三个网格项( item-b , item-c and item-d ),会沿行轴进行布局。
如果我们将 grid-auto-flow 属性设置为 column , item-b , item-c 和 item-d 就会沿列轴进行布局。
.container{ display: grid; grid-template-columns: 60px 60px 60px 60px 60px; grid-template-rows: 30px 30px; grid-auto-flow: column;}
在一行声明中设置一下所有属性的简写形式: grid-template-rows , grid-template-columns , grid-template-areas , grid-auto-rows , grid-auto-columns , 以及 grid-auto-flow 。它将 grid-column-gap 和 grid-row-gap 属性设置为初始值,即使它们不能显示的设置此属性。
.container{ grid: none | subgrid | <grid-template-rows> / <grid-template-columns> | <grid-auto-flow> [<grid-auto-rows> [/ <grid-auto-columns>]];}
下面两个代码块是等效的:
.container{ grid: 200px auto / 1fr auto 1fr;}.container{ grid-template-rows: 200px auto; grid-template-columns: 1fr auto 1fr; grid-template-areas: none;}
同样,下面的两个代码块也是等效的:
.container{ grid: column 1fr / auto;}.container{ grid-auto-flow: column; grid-auto-rows: 1fr; grid-auto-columns: auto;}
它还接受一次性设置所有属性,更复杂但非常方便的语法。指定 grid-template-areas , grid-auto-rows 和 grid-auto-columns 属性,其他所有子属性都将设置为其初始值。你现在所做的是在其网格区域内,指定网格线名称和内联轨道大小。下面是最简单的描述:
.container{ grid: [row1-start] "header header header" 1fr [row1-end] [row2-start] "footer footer footer" 25px [row2-end] / auto 50px auto;}
等效于:
.container{ grid-template-areas: "header header header" "footer footer footer"; grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end]; grid-template-columns: auto 50px auto; }
使用特定的网格线确定网格项在网格内的位置。 grid-column-start / grid-row-start 属性表示网格项的网格线的起始位置, grid-column-end / grid-row-end 属性表示网格项的网格线的终止位置。
.item{ grid-column-start: <number> | <name> | span <number> | span <name> | auto grid-column-end: <number> | <name> | span <number> | span <name> | auto grid-row-start: <number> | <name> | span <number> | span <name> | auto grid-row-end: <number> | <name> | span <number> | span <name> | auto}
.item-a{ grid-column-start: 2; grid-column-end: five; grid-row-start: row1-start grid-row-end: 3}
.item-b{ grid-column-start: 1; grid-column-end: span col4-start; grid-row-start: 2 grid-row-end: span 2}
如果没有声明 grid-column-end / grid-row-end 属性,默认情况下网格项的跨度为 1 。
网格项可以互相重叠。可以使用 z-index 属性控制堆叠顺序。
grid-column-start + grid-column-end , 和 grid-row-start + grid-row-end 属性分别的简写形式。
.item{ grid-column: <start-line> / <end-line> | <start-line> / span <value>; grid-row: <start-line> / <end-line> | <start-line> / span <value>;}
.item-c{ grid-column: 3 / span 2; grid-row: third-line / 4;}
如果没有声明结束网格线值,默认网格轨道跨度为 1 .
给网格项进行命名以便于模板使用 grid-template-areas 属性创建时可以加以引用。另外也可以被 grid-row-start + grid-column-start + grid-row-end + grid-column-end 属性更为简洁的加以引用。
.item{ grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;}
对网格项进行命名的一种方式:
.item-d{ grid-area: header}
grid-row-start + grid-column-start + grid-row-end + grid-column-end 属性的一种简写方式:
.item-d{ grid-area: 1 / col4-start / last-line / 6}
沿列轴对齐网格项中的内容(相反于 align-item 属性定义的沿行轴对齐)。此值适用于单一网格项中的内容。
.item{ justify-self: start | end | center | stretch;}
.item-a{ justify-self: start;}
.item-a{ justify-self: end;}
.item-a{ justify-self: center;}
.item-a{ justify-self: stretch;}
设置网格中所有网格项的对齐方式,可以使用网格容器上的 justify-items 属性。
沿行轴对齐网格项中的内容(相反于 justify-item 属性定义的沿列轴对齐)。此值适用于单一网格项中的内容。
.item{ align-self: start | end | center | stretch;}
.item-a{ align-self: start;}
.item-a{ align-self: end;}
.item-a{ align-self: center;}
.item-a{ align-self: stretch;}
使网格中所有的网格项对齐,可以使用网格容器上的 align-items 属性。
本文根据 @Chris House 的《 A Complete Guide to CSS Grid Layout 》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处: http://chris.house/blog/a-complete-guide-css-grid-layout/ 。
在校学生,本科计算机专业。一个积极进取、爱笑的女生,热爱前端,喜欢与人交流分享。想要通过自己的努力做到心中的那个自己。微博:@静-如秋叶