初探CSS Grid布局

在CSS3中纳入的Flex Box布局给前端开发者带来了极大的便利,它的强大是有目共睹的。很多以前需要以前复查代码实现的布局,现在通过 Flex Box 很容易就实现。而在下一版本的CSS规范中正在讨论纳入一个更加强大的布局系统,它就是今天要说的: CSS Grid Layout

CSS网格布局是CSS中非常强大的布局系统。这是一个二维系统,意味着它可以同时处理列和行,不像Flex Box,是一维系统。 使用网格布局您可以通过将CSS规则应用于父元素(成为网格容器)和该元素的子元素(成为网格物体)。

浏览器支持情况

由于是一个正在讨论的CSS模块规范,目前支持的浏览器还是比较少。要直接使用需要在IE11(它支持的是旧规范)、Microsoft Edge、Google Chrome Canary或者Firefox Nightly才能看到效果。

最简单的方法是在Chrome浏览器中通过 chrome://flags/#enable-experimental-web-platform-features 打开Chrome浏览器实验网络平台功能。

什么是网格?

网格是一组相交的水平线和垂直线,它定义了网格的列和行。我们可以将网格元素放置在与这些行和列相关的位置上。CSS网格布局具有以下特点:

  • 固定或弹性的轨道尺寸
    :clipboard:你可以使用固定的轨道尺寸创建网格,比如使用像素单位。也可以使用比如百分比或者专门为此目的创建的新单位 fr来创建有弹性尺寸的网格。
  • 定位项目
    :clipboard:你可以使用行号、行名或者标定一个网格区域来精确定位项目。网格同时还使用一种算法来控制未给出明确网格位置的项目。

  • 创建额外的轨道来保存内容
    :clipboard:可以使用网格布局定义一个显式网格,但该规范还涉及在声明网格外添加的内容,如需要添加额外的行和列。包括添加“尽可能多的列,以适应容器”的功能。

  • 对齐控制
    :clipboard:网格包含对齐特征,以便我们可以控制一旦放置到网格区域中的物体对齐,以及整个网格如何对齐。

  • 控制重叠内容
    :clipboard:多个项目可以放置在网格单元格中,或者区域可以部分地彼此重叠。然后可以用这种分层进行控制z-index。

网格基础

网格容器

通过在元素上声明 display:grid 或 display:inline-grid 来创建一个网格容器。
创建一个类名为 grid 的 div 元素作为容器,其内部有五个元素。

  1. <div class="grid">
  2. <div>One</div>
  3. <div>Two</div>
  4. <div>Three</div>
  5. <div>Four</div>
  6. <div>Five</div>
  7. </div>

将 .grid 作为一个网格容器

  1. .grid {
  2. display: grid;
  3. }

所有直系子元素现在都是网格项目了。在浏览器中,项目转为网格前看不出什么差异,因为网格给这些项目创建了一个单列网格。

网格轨道

通过 grid-template-columns 和 grid-template-rows 属性来定义网格中的行和列。这些属性定义了网格的轨道。一个网格轨道就是网格中任意两条线之间的空间。

通过添加 grid-template-columns 属性添加列轨道,然后定义列轨道的大小。

  1. <div class="grid">
  2. <div>One</div>
  3. <div>Two</div>
  4. <div>Three</div>
  5. <div>Four</div>
  6. <div>Five</div>
  7. </div>
  1. .grid {
  2. display: grid;
  3. grid-template-columns: 33.33% 33.33% 33.33%;
  4. }

现在创建了一个网格,包含了三个列轨道,每个宽度为父元素的三分之一。子项目将在网格上每个网格单元中展开。

  • fr 单位
    网格轨道可以使用任何长度单位进行定义。 网格还引入了一个额外的长度单位来帮助我们创建灵活的网格轨道。新的fr单位代表网格容器中可用空间的一等份。

    通过fr可以把空间按比例等分,类似Flex Box的 flex

    1. <div class="grid">
    2. <div>One</div>
    3. <div>Two</div>
    4. <div>Three</div>
    5. <div>Four</div>
    6. <div>Five</div>
    7. </div>
    1. .grid {
    2. display: grid;
    3. grid-template-columns: 2fr 3fr 4fr;
    4. }

    fr 同样可以和普通数值混合使用

    1. .grid {
    2. display: grid;
    3. grid-template-columns: 70px 2fr 3fr;
    4. }
  • 在网格轨道中使用repeat()
    有着多轨道的大型网格可使用 repeat() 标记来重复部分或整个轨道列表。

    如:

    1. .grid {
    2. display: grid;
    3. grid-template-columns: 1fr 1fr 1fr;
    4. }

    可以写成:

    1. .grid {
    2. display: grid;
    3. grid-template-columns: repeat(3, 1fr);
    4. }

    repeat() 可以只重复轨道中的一部分:

    1. .grid {
    2. display: grid;
    3. /* grid-template-columns: repeat(3, 1fr); */
    4. grid-template-columns: 70px repeat(3, 100px) 20px;
    5. }

    还可以创建一个多轨道模式的重复轨道列表:

    1. .grid {
    2. display: grid;
    3. /* grid-template-columns: repeat(3, 1fr); */
    4. /*grid-template-columns: 70px repeat(3, 100px) 20px;*/
    5. grid-template-columns: repeat(3, 70px 2fr);
    6. }
  • 关于显式和隐式网格
    所谓显式网格就是我们通过 grid-template-columns 和 grid-template-rows 属性中明确定义的行和列。
    而隐式网格就是网格根据内容自动创建的行和列,默认地,这些轨道将自动定义尺寸,会根据它里面的内容改变尺寸。

    我们可以通过grid-auto-rows 和 grid-auto-columns 属性来定义隐式网格的尺寸,如下:

    1. <div class="grid">
    2. <div>One</div>
    3. <div>Two</div>
    4. <div>Three</div>
    5. <div>Four</div>
    6. <div>Five</div>
    7. </div>
    1. .grid {
    2. display: grid;
    3. grid-template-columns: 2fr 3fr 4fr;
    4. grid-auto-rows: 100px; // 默认创建的网格行高度将为100px;
    5. }
  • minmax()
    minmax() 用来控制网格的最大最小尺寸。

  1. <div class="grid">
  2. <div>One</div>
  3. <div>Two</div>
  4. <div>Three
  5. <p class='height'> height: 140px;</p>
  6. </div>
  7. <div>Four</div>
  8. <div>Five</div>
  9. <div>Sixe</div>
  10. </div>
  1. .grid {
  2. display: grid;
  3. grid-template-columns: 2fr 3fr 4fr;
  4. grid-auto-rows: minmax(100px, auto);;
  5. }

网格线

当我们创建网格时,网格会为网格线进行编号,以便我们通过网格线来定位每一个网格项目。
网格线的编号顺序取决于文章的书写模式。在从左至右书写的语言中,编号为 1 的网格线位于最左边。在从右至左书写的语言中,编号为 1 的网格线位于最右边。

:warning:当我们定义网格时,我们定义的是网格轨道,不是网格线。

  • 跨轨道放置网格项目
    当放置元素时,我们使用 网格线 定位,而非 网格轨道
    要实现跨轨道放置网格项目(有点像table 合并 cell),我们需要用到 grid-column-start, grid-column-end, grid-row-start 和 grid-row-end 属性,看一下示例:
  1. <div class="grid">
  2. <div class='one'>One</div>
  3. <div class='two'>Two</div>
  4. <div>Three</div>
  5. <div>Four</div>
  6. <div>Five</div>
  7. <div>Sixe</div>
  8. </div>
  1. .grid {
  2. display: grid;
  3. grid-template-columns: 2fr 3fr 4fr;
  4. grid-auto-rows: 100px;
  5. }
  6. .one {
  7. grid-column-start: 1;
  8. grid-column-end: 4;
  9. grid-row-start: 1;
  10. grid-row-end: 3;
  11. }
  12. .two {
  13. grid-column-start: 1;
  14. grid-row-start: 3;
  15. grid-row-end: 5;
  16. }

网格单元

一个网格单元是在一个网格元素中最小的单位, 从概念上来讲其实它和表格的一个单元格很像。一旦一个网格元素被定义在一个父级元素当中,那么他的子级项目将会排列在每个事先定义好的网格单元中。

网格区域

网格项目可以向行或着列的方向扩展一个或多个单元,并且会创建一个网格区域。网格区域的形状应该是一个矩形 - 也就是说你不可能创建出一个类似于“L”形的网格区域。下图高亮的网格区域扩展了2列以及2行。

网格间距

在两两单元格之间,有时候我们需要为其设置间距。这个可以通过 grid-column-gap(网格纵向间距) 和 grid-row-gap(网格横向间距) 属性来设置,或者直接使用两个合并的缩写形式 grid-gap。

  1. <div class="grid">
  2. <div class='one'>One</div>
  3. <div class='two'>Two</div>
  4. <div>Three</div>
  5. <div>Four</div>
  6. <div>Five</div>
  7. <div>Sixe</div>
  8. </div>
  1. .grid {
  2. display: grid;
  3. grid-template-columns: 2fr 3fr 4fr;
  4. grid-auto-rows: 100px;
  5. /*grid-column-gap: 10px;
  6. grid-row-gap: 20px;*/
  7. grid-gap: 10px 20px;
  8. }

网格顺序

在网格项目发生堆积时使用 z-index 属性控制堆积的顺序。

  1. <div class="grid">
  2. <div class='one'>One</div>
  3. <div class='two'>Two</div>
  4. <div>Three</div>
  5. <div>Four</div>
  6. <div>Five</div>
  7. <div>Sixe</div>
  8. </div>
  1. .grid {
  2. display: grid;
  3. grid-template-columns: 2fr 3fr 4fr;
  4. grid-auto-rows: 100px;
  5. grid-gap: 10px 20px;
  6. }
  7. .one {
  8. grid-column-start: 1;
  9. grid-column-end: 4;
  10. grid-row-start: 1;
  11. grid-row-end: 3;
  12. z-index: 2;
  13. background-color: #1e4c27;
  14. opacity: 0.8;
  15. }
  16. .two {
  17. grid-column-start: 1;
  18. grid-row-start: 2;
  19. grid-row-end: 5;
  20. z-index: 1;
  21. }

总结

以上仅仅是网格布局的基本知识,但是已足以显示出它的强大之处。当它真正纳入规范后,必将给前端开发效率的提高带来极大的提升。

写于 2018年02月28日Css 6018

如非特别注明,文章皆为原创。

转载请注明出处: https://www.liayal.com/article/5a96599bca0de01ec9713c43

记小栈小程序上线啦~搜索【记小栈】【点击扫码】体验

你不想说点啥么?
😀😃😄😁😆😅😂🤣☺️😊😇🙂🙃😉😌😍😘😗😙😚😋😜😝😛🤑🤗🤓😎🤡🤠😏😒😞😔😟😕🙁☹️😣😖😫😩😤😠😡😶😐😑😯😦😧😮😲😵😳😱😨😰😢😥🤤😭😓😪😴🙄🤔🤥😬🤐🤢🤧😷🤒🤕😈👿👹👺💩👻💀☠️👽👾🤖🎃😺😸😹😻😼😽🙀😿😾👐👐🏻👐🏼👐🏽👐🏾👐🏿🙌🙌🏻🙌🏼🙌🏽🙌🏾🙌🏿👏👏🏻👏🏼👏🏽👏🏾👏🏿🙏🙏🏻🙏🏼🙏🏽🙏🏾🙏🏿🤝👍👍🏻👍🏼👍🏽👍🏾👍🏿👎👎🏻👎🏼👎🏽👎🏾👎🏿👊👊🏻👊🏼👊🏽👊🏾👊🏿✊🏻✊🏼✊🏽✊🏾✊🏿

评论

gongph08-16 2018

讲的不错,学习了。。