not a better man

css, 前端技术

网格布局完全指南

这个是css网格布局的完全指南,涉及到网格布局的父元素属性说明,以及网格布局的子元素属性说明。

内容列表

1.网格布局介绍

2.网格布局基础知识与浏览器支持

3.网络布局中的重要术语

4.Gird属性

5.网格布局特有单位和函数

6.流式Columns Snippet

7.动画

网格布局介绍

css 网络布局也就是Grid 或css grid ,它是一个二维的布局系统,完全改变了我们过去的布局方式。css是用来布局我们的web页面,但是它有很多做到不到位的地方。最初,我们使用table ,然后是float position 还有inline-block,但是这些方法基本上是hack方式做到的,此外还不支持很多重要功能(如垂直居中)Flexbox是个很强的布局工具,但是它只是一个一维的布局方案。Grid是第一个专门为解决布局问题而创建的CSS模块,在它之前我们做网站的过程中,我们一直在用hack手段解决这些问题。在这片文章里,我不会去讲grid之前版本的相关属性。

网格布局的基础知识与浏览器支持

2017年初,几乎所有的浏览器都支持不带浏览器前缀的grid布局模型,像Chrome,Firefox Oprea 以及Safari 和IE10等,但是这个grid语法的一个过渡版本。现在gird最新属性已经发生变化了,是时候写一份新版的grid布局的指南了。

为了使网格布局开始工作,我们需要利用display:grid 这个样式将一个元素作为网格布局的容器。利用 gird-template-columnsgrid-template-rows来设置行与列的尺寸,然后使用gird-columngrid-row将子元素放入网格中。这个与flexbox布局很相似,每个gird 子项的位置并不重要。我们可以使用的CSS属性按任何顺序放置它们,这样用媒体查询重新安排的网格布局变得非常容易。我们可以想象一下,定义整个页面的布局,然后完全重新排列以适应不同的屏幕宽度,只需几行CSS即可。网格是有史以来最强大的CSS模块之一。

下面的图片是从Caniuse中获取的数据,Caniuse中能够查询到各个浏览器对gird支持更详细的数据。

Desktop支持

pc浏览器支持情况

Mobile/Tablet 支持

移动端浏览器支持情况

网格布局中重要的术语

在深入了解网格的概念之前,了解网格布局中的术语是很重要的。由于这里涉及的术语在概念上都有点类似,如果你不先记住网格规范所定义的含义,就很容易将它们相互混淆。不过不用担心,这些术语并不多。

Gird Contanier

使用了display:grid的元素是grid container。它是所有网格项目的直接父元素。在下列的例子中container是网格的容器。

<div class="container"> 
  <div class="item item-1"> </div>  
  <div class="item item-2"> </div>  
  <div class="item item-3"> </div>
 </div>

Grid Line

构成网格结构的分割线。它们可以是垂直的(”列网格线”)或水平的(”行网格线”),位于行或列的两侧。这里的黄线就是列网格线的一个例子。

网格线

Grid Track

两条相邻网格线之间的空间。你可以把它们看成是网格的列或行。下图是第二行和第三行网格线之间的网格轨迹

网络轨迹

Gird Item

网格容器的孩子(直接子元素)下面的类名为item的元素是grid item。但是sub-item 不是。

<div class="container">   
  <div class="item"> </div>   
  <div class="item">     
    <p class="sub-item"> </p>   
  </div>   
  <div class="item"> </div> 
</div>

Grid Cell

相邻两行和相邻两列网格线之间的空间叫Grid Cell 它是网格的一个 “单位”。下面是行网格线1和2,列网格线2和3之间的网格单元。

网格单元

Grid Area

由四条网格线包围的总空间。一个网格区域可以由任意数量的网格单元组成。下图是行网格线1和3,列网格线1和3之间的网格区域。

网格区域

Grid属性

网格布局的相关属性

父元素的属性(Grid Contanier)

display

将该元素定义为一个网格容器,并为其内容建立一个新的网格格式化上下文
值:

  • grid -生成一个块级网格
  • inline-grid – 生成一个内联级的网格
.container {
  display:grid | inline-grid;
}

注意:通过嵌套元素(又称子网格)向下传递网格参数的能力已被移至CSS网格规范的第二级。这里有一个简单的解释。

grid-template-columns
grid-template-rows

这两个属性用一个以空格分隔的数值列表定义网格的列和行。这些值代表轨道的大小,它们之间的空间代表网格线。

值:

  • <轨道尺寸> 单位可以是 一个具体长度,百分比,或者是网格中自由空间的一小部分(使用 fr 单位)
  • <网格线的名字> 自定义命名
.container {
  grid-template-columns: ... ...;
  /* e.g.
  1fr 1fr
  minmax(10px, 1fr) 3fr
  repeat(5, 1fr)
  50px auto 100px 1fr
  */
  grid-template-rows: ... ...;
  /* e.g
  min-content 1fr min-content
  100px 1fr max-content
  */
}

网格线会从这些分配中自动分配正数(-1也代表最后一行或一列)。

网络线的序列说明

我们也可以为每个网格线进行命名,注意[]中的名字就是每条网格线的名字。

.container{
  grid-template-columns:[first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
  grid-template-rows:[row1-start] 25% [row1-end] 100px 
[third-line] auto [last line];
}
自定义网格线

注意每条线可以取多个名字,例如下面的代码中的第二条线有两个名字,分别为row1-end,row2-start:

.container{
   grid-template-columns:[row1-start] 25% [row2-start] 25% [row2-end];
}

如果我们的定义包含重复的部分,我们可以使用repeat()符号来进行简化事情

.container {
  grid-template-columns: repeat(3, 20px [col-start]);
}

等价于

.container {   
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start]; 
}

如果多个行有相同的名称,可以通过行名和计数来引用它们。

.item {
grid-column-start: col-start 2;
}

fr这个单位,允许我们使用网格容器的剩余空间设置网格track的尺寸。举个例子。下列的代码是,是将每个grid item 的宽度设置成网格容器的三分之一。

.container{
  grid-template-columns:1fr 1fr 1fr;
}

自由空间是在任何非柔性项目之后计算的。下面这个例子,fr单元可用的自由空间总量不包括50px的空间。

.container{
   grid-template-columns:1fr 50px 1fr 1fr;
}

grid-template-areas

通过引用用grid-area属性指定的网格区域的名称,定义一个网格模板。重复一个网格区域的名称会使内容跨越这些单元格。一个”.”表示一个空单元。这个语法本身提供了一个可视化的网格结构。

语法:

  • <grid-area-name> 使用grid-area指定的网格区域的名字
  • . 表示一个空的网格单元
  • none 表示没有定义网格区域

例如

.item-a {
  grid-area: header;
}

.item-b {
  grid-area: main;
}

.item-c {
  grid-area: sidebar;
}

.item-d {
  grid-area: footer;
}

.container {
  display: grid;
  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区域、一个空单元格和一个slider区域组成。最后一行是由footer 组成,如下图所示

grid-template-areas 说明图

我们声明中每一行都需要有相同数量的单元格。

我可以使用任何数量的相邻句点来声明一个空单元。只要这些句号之间没有空格,它们就代表一个单元格。

我们需要注意,用这种语法命名的不是线,只是区域。当我们使用这种语法时,区域两端的线实际上是被自动命名的。如果网格区域的名称是foo,那么该区域的起始行和起始列的名称将是foo-start,而最后一行和最后一列的名称将是foo-end。这意味着有些行可能有多个名字,比如上例中最左边的行,它将有三个名字:header-start、main-start和footer-start。

grid-template

这个属性可以同时设置grid-template-rows,grid-template-columns,和 grid-template-areas

语法:

.container {
  grid-template: none | <grid-template-rows> / <grid-template-columns>;
}

当然这个属性还介绍一种复杂,但是比较上手的语法来设置这三个属性的值。我们来看一下下面的例子。

.container{
  grid-template: [row1-start] "header header header" 25px [row1-end]
        [row2-start] "footer footer footer" 25px [row2-end] / auto 50px auto
}

这个等价于

.container{
   grid-template-rows:[row1-start] 25px [row1-end row2-start] 25px [row2-end];
   grid-template-columns: auto 50px auto;
   grid-template-areas:
     "header header header"
     "footer footer footer";
}

由于grid-template不会重置隐含的网格属性(grid-auto-columns, grid-auto-rows, 以及 grid-auto-flow),这可能是你在大多数情况下想要做的,所以建议使用grid属性而不是grid-template。

column-gap
row-gap
grid-column-gap
grid-column-gap

指定网格线的大小。我们可以把它看作是设置列/行之间的沟槽的宽度。

语法:

  • <line-size> – 长度值
.container{
  /* standard */
  column-gap: <line-size>;
  row-gap: <line-size>;
  /* old * /
  grid-column-gap: <line-size>;
  grid-row-gap:<line-size>;
}

例如:

.container {
  grid-template-columns: 100px 50px 100px;
  grid-template-rows: 80px auto 80px;
  column-gap: 10px;
  row-gap: 15px;
}
column-gap,row-gap含义示意图

这个 沟槽只在列和行之间创建,对外边缘不生效。

注意:grid-前缀将被移除,grid-column-gap和grid-row-gap将被更名为column-gap和row-gap。在Chrome 68+、Safari 11.2 Release 50+和Opera 54+中已经支持无前缀的属性。

gap
grid-gap

这个属性是row-gapcolumn-gap的简写

语法:

  • <grid-row-gap> <grid-column-gap> – 长度单位值
.container {
  /* standard */
  gap: <grid-row-gap> <grid-column-gap>;
  /* old */
  grid-gap: <grid-row-gap > <grid-column-gap>;
}

例如:

.container{
  grid-template-columns: 100px 50px 100px;
  grid-template-rows:80px auto 80px;
  gap: 15px 10px;
}

如果 row-gap没有设置值,那么它的值与column-gap的值一样。

注意:grid-前缀已被废弃(但谁知道呢,可能永远不会从浏览器中删除) grid-gap改名为gap。在Chrome 68+、Safari 11.2 Release 50+和Opera 54+中已经支持无前缀的属性。

justify-items

这个属性是设置容器内的所有网格沿着内联(行)轴对齐网格项目(与沿着块(列)轴对齐的 align-items 相反)。

语法:

  • start – 使每个子项与单元格的起始边缘齐平。
  • end – 使每个子项与单元格的末端边缘齐平
  • center – 使每个子项在单元格重中心位置对齐
  • stretch – 使每个子项填充整个单元格的宽度(这是默认值)。
.container{
  justify-items: start | end | center | stretch;
}

例如:

.container{
 justify-items:start;
}
justify-items:start 所有子项在网格中的位置
.container{
  justify-items:end;
}
justify-items:end 所有子项在网格中的位置
.container{
  justify-itmes:center;
}
justify-items:center 所有子项在网格中的位置
.container{
  justify-items:stretch;
}
justify-items:stretch 所有子项在网格中的位置

这种行为也可以通过justify-self属性在单个网格项目上设置。

align-items

这个属性用来设置沿着块(列)轴对齐网格项目(与justify-items相反,它沿内联(行)轴对齐)。这个值适用于容器内的所有网格项目。

语法:

  • stretch – 填充整个单元格的高度(默认值)。
  • start – 使每个子项与单元格的起始边缘齐平。
  • end – 使每个子项与单元格的末端边缘齐平
  • center – 使每个子项在其单元格的中心位置对齐
  • baseline -使每个子项 沿着文本基线对齐。基线有一些修饰词–第一条基线和最后一条基线,在多行文本的情况下,将使用第一行或最后一行的基线。
.container{
  align-items:start | end | center | stretch;
}

举例如下:

.container{
  align-items:start;
}
align-items:start 所有子项在网格对齐的位置
.container{
  align-items:end;
}
align-items:end 所有子项在网格中对齐的位置
.container {
  align-items:center;
}
align-items为center时,所有子项在网格中对齐的位置
.container {
  align-items:stretch;
}
align-items为stretch时,所有子项在网络中的位置

这种位置对齐也可以通过align-self属性在单个网格项目上设置。

还有修改关键字safe和unsafe(例如 align-items: safe end)。安全关键字的意思是 “尝试像这样对齐,但如果这意味着对齐一个项目,使其移动到不可访问的溢出区域,则不能这样做”,而不安全关键字将允许将内容移动到不可访问的区域(”数据丢失”)。

place-items

这个属性可以同时设置 align-items 和 justify-items的值。

语法:

  • <align-items>/<justify-items> – 第一个值是设置align-items。第二个值是设置 justify-items。如果第二个值没有设置的话,那么第一值被两个属性同时使用。

更详细的信息查看 align-itemsjustify-items

这个对于快速居中对齐很有用。

.center {
  display:grid;
  place-items:center;
}

justify-content

有时候,我们设置网格的总尺寸可能小于其网格容器的尺寸。如果所有的网格项目都是用非弹性的单位(如 px)来确定大小,就会发生这种情况。在这种情况下,我们可以使用justify-content来设置网格在网格容器中的对齐方式。这个属性沿内联(行)轴对齐网格(与沿块(列)轴对齐网格的 align-content 属性相反)。

值:

  • start – 将网格与网格容器的起始边缘对齐。
  • end – 将网格与网格容器的末端边缘对齐。
  • center – 将网格在网格容器的中心对齐
  • stretch – 调整网格项目的大小,让网格填满网格容器的整个宽度。
  • space-around – 让每个网格项目之间有一个均匀的空间,在最远的两端网格与边缘的间距是网格之间的一半间距。
  • space-between – 在每个网格项目之间放置一个均匀的空间,最远的两端没有任何空间。
  • space-evenly – 在每个网格项目之间都有均匀的空间,包括最远端网络与网格容器空间都保持一致。

语法

.container{
  justify-content:start | end | center | stretch | space-around | space-between | space-evenly
}

各个属性例子如下:

.container {
  justify-content: start;
}
justify-content为start 的时候,网格在容器中的位置
.container{
  justify-content:end;
}
justify-content为end的时候,网格在容器中的位置
.container{
  justify-content:center;
}
justify-content为end的时候,整个网格在容器中的位置
.container{
  justify-content:stretch;
}
justify-content为stretch的时候网格充满整个容器
.container{
  justify-content:space-around;
}
justify-content为space-around的时候,网格在网格容器中的布局
.container{
  justify-content:space-between;
}
justify-content为space-between的时候,网格在网格容器中布局
.container{
 justify-content:space-evenly;
}
justify-content为space-evenly的时候,网格在网格容器中的布局

align-content

有时候,设置网格的总尺寸可能小于其网格容器的尺寸。例如当我们所有的网格项目都是用非弹性的单位(如 px)来确定大小,就会发生这种情况。在这种情况下,你可以设置网格在网格容器中的对齐方式。align-content这个属性使网格沿着块(列)轴对齐(与justify-content相反,它使网格沿着内联(行)轴对齐)。

值:

  • start -调整网格,使其与网格容器的起始边缘齐平。
  • end – 调整网格,使其与网格容器的末端边缘齐平。
  • center – 将网格与网格容器的中心位置对齐
  • stretch – 重新设置网格高度,让网格充满整个容器高度
  • space-around – 在每个网格项目之间放置一个均匀的空间,在最远的两端有一半大小的空间。
  • space-between – 在每个网格项目之间放置一个均匀的空间,在最远的两端没有空间。
  • space-evenly -在每个网格项目之间都有均匀的空间,包括远端。

语法:

.container {
  align-center: start | end | center | stretch | space-around | space-between
}

例子:

.container{
  align-content:start;
}
align-content为start 时,网格在容器中的位置
.container{
  align-content:end;
}
align-content为end时,网格在容器中位置
.container{
  align-content:center;
}
align-content的值为center时,网格在容器中的位置。
.container{
  align-content: stretch;
}
align-content的值为 stretch时,网格在容器中的位置
.container{
  align-content:space-around;
}
align-content的值为space-around时,网格在容器中的位置。
.container{
  align-content:space-between;
}
align-content的值为space-between时,网格在容器中的位置。
.container{
  align-content:space-evenly;
}
align-content的值为space-evenly时,网格在容器中的位置。

place-content

place-content这个属性可以同时设置 align-content和justify-content的值。

值:

  • <align-content> / <justify-content> 第一个值是用align-content的值,第二值是justify-content的值。如果第二个值没有写,那么第一个值同时分配给align-content和justify-content。

目前所有现代化浏览器都支持这个属性。

更多的信息,可以查看 align-content justify-content

grid-auto-columns
grid-auto-rows

这个属性是用来指定任何自动生成的网格轨迹(又称隐式网格轨迹)的大小。当网格中的网格项多于单元格时,或者当一个网格项被放置在显式网格之外时,隐式轨道就会被创建。(这里查看显性网格和隐性网格的区别

值:

  • <track-size> -可以是一个具体长度,百分比,或网格中自由空间的一小部分(使用 fr 单位)。
.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按照下面的代码来设置gird 子项的位置。

.item-a {
  grid-column: 1 / 2;
  grid-row: 2 / 3;
}
.item-b {
  grid-column: 5 / 6;
  grid-row: 2 / 3;
}
创建宽度为0的隐性轨道来填补空隙
创建宽度为0的隐性轨道来填补空隙

我们将.item-b 的位置从第5列开始,第六列结束。但是我们就没有定义第5列和第6列。.item-b子项的引用的列数并不存在,这个时候会创建宽度为0的隐性轨道,来填补空隙。我们这个时候可以使用 grid-auto-columnsgrid-auto-rows来设置这些隐性轨道的宽度。

.container {
  grid-auto-columns: 60px
}
设置隐性轨道的宽度为60px

grid-auto-flow

如果我们有没有明确放置在网格上的网格项目,自动放置算法会启动,自动放置这些项目。grid-auto-flow这个属性控制了自动摆放算法的工作方式。

值:

  • row – 告诉自动放置算法依次填入每一行,如有必要,添加新行(默认值)。
  • column – 告诉自动放置算法,依次填入每一列,如有必要,增加新的一列。
  • dense – 告诉自动摆放算法,如果稍后出现较小的项目,则尝试在网格中较早的位置填上。
.container {
  grid-auto-flow: row | column | row dense | column dense;
}

请注意,dense 只是改变了你的项目的视觉顺序,可能会导致它们出现失序,这对可访问性不利。

例子如下:

<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>

我们定义一个2行5列的网格,然后将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和item-d)的位置,我们可以看它们是怎么排序的。

grid-auto-flow:row时 子网格的排序

如果把上述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-auto-flow设置为column时子项排序。

grid

grid 是 grid-template-rowsgrid-template-columns,grid-template-areas,grid-auto-rows,grid-auto-columns,以及grid-auto-flow这些属性的简写(注意:你只能在一个网格声明中指定显性或隐性的网格属性)。

值:

  • none – 将所有的子属性设置成它们的初始值。
  • <grid-template> – 功能与grid-template一样。
  • <grid-template-rows> / [ auto-flow && dense ?] <grid-auto-columns> ? – 将grid-template-rows设置特定值,如果 / 的右边设置了auto-flow关键字,这个是将grid-auto-flow设置成column。如果dense关键字被添加,那么使用“密集”包装算法。 如果 grid-auto-columns没有,那么它被设置成auto。
  • [ auto-flow && dense? ] <grid-auto-rows>? / <grid-template-columns> 将 grid-template-columns 设为指定的值。如果auto-flow关键字在斜线的左边,它将grid-auto-flow设置为row。如果另外指定了dense关键字,自动放置算法就会使用 “密集 “的打包算法。如果grid-auto-rows被省略,它被设置为auto。

举例如下:

下列的两个代码块是等价的。

.container {
  grid: 100px 300px / 3fr 1fr;
}

.container {
  grid-template-rows: 100px 300px;
  grid-template-columns: 3fr 1fr;
}

下面的两个代码也是等价的。

.container {
  grid: auto-flow / 200px 1fr;
}

.container {
  grid-auto-flow: row;
  grid-template-columns: 200px 1fr;
}

这两个代码块也是等价的

.container {
  grid: auto-flow dense 100px / 1fr 2fr;
}

.container {
  grid-auto-flow: row dense;
  grid-auto-rows: 100px;
  grid-template-columns: 1fr 2fr;
}

下面的代码块也是等价的

.container {
  grid: 100px 300px / auto-flow 200px;
}

.container {
  grid-template-rows: 100px 300px;
  grid-auto-flow: column;
  grid-auto-columns: 200px;
}
gird 也支持一种更复杂但相当方便的语法,用于一次性设置所有内容。
我们可以设置 grid-template-areas,grid-template-rows以及grid-template-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 Items)

注意:floatdisplay: inline-blockdisplay: table-cellvertical-align 和 column-* 属性 对 grid item 没有影响gird-column-start
grid-column-end
grid-row-start
grid-row-end

grid-column-start
grid-column-end
grid-row-start
grid-row-end

通过引用特定的网格线来确定一个网格item在网格中的位置。 grid-column-start/grid-row-start是item开始的线,grid-column-end/grid-row-end是item结束的线。

值:

  • <line> 可以是对应网格线的数字,也可以是对应网格线的名字
  • span <number> 跨越网格轨道的数量
  • span <name> 该item一直横跨到所提供的名字的位置
  • auto 表示自动放置,自动跨度,或默认跨度为1。
.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-column-row。那么网格子元素将占据一个grid 轨道。

我们可以通过 z-index 属性来将item设置不同层级。

grid-column
grid-row

grid-column 是grid-column-startgrid-column-end 的简写。grid-row是 grid-row-start和grid-row-end的简写

Values:

  • <start-line>/<end-line> 每一个都接受所有与长写版相同的值,包括跨度。
.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;
}
item在图中展示的位置

grid-area

grid-area是给与item一个名称,以便它可以被用grid-template-areas属性创建的模板所引用。另外,这个属性可以作为grid-row-start + grid-column-start + grid-row-end + grid-column-end的一个更简短的缩写。

语法:

  • <name> 我声明的名字
  • <row-start>/<column-start>/<row-end>/<column-end> 可以是数字或线的名字
.item{
  grid-area:<name> | <row-start>/<column-start>/<row-end>/<column-end>
}

例如:将使用名字分配给item

.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;
}
简写代码的示意图

justify-self

将单元格内的网格项沿内联(行)轴对齐(与沿(列)轴对齐的 align-self 相反)。这个属性应用于单个单元格内的网格项。

语法:

  • start -将网格项目与单元格的起始边缘齐平。
  • end -将网格项目与单元格的末部边缘齐平。
  • center – 使网格项目在单元格的中心对齐。
  • stretch – 填充整个单元格的宽度(这是默认值)。
.item {
  justify-self:start | end | center | stretch
}

举例

.item-a {
  justify-self:start;
}
justify-self:start在网格中的位置
.item-a {
 justify-self:center;
}
justify-self:center在网格中的位置
.item-a {
  justify-self:end
}
justify-self:end在网格中位置
.item-a {
  justify-self:stretch
}
justify-self:strech 在网格中位置

当需要设置所有网格中子项的对齐方式时,我们可以在gird 容器中使用justify-items属性来进行设置。

align-self

将一个单元格内的网格项沿块(列)轴对齐(与justify-self相反,它沿内联(行)轴对齐)。这个属性值适用于单个网格项的内容。

语法:

  • start – 将网格项目与单元格的起始边缘齐平。
  • end – 将网格项目与单元格的末部边缘齐平。
  • center -将网格项目在单元格的中心对齐。
  • stretch -填充整个单元格的高度(这是默认的)。
.item {
  align-self:start | end | center | stretch;
}

例如:

.item-a {
  align-self:start;
}
align-self:start 在网格中位置
.item-a {
  align-self:end;
}
align-self:end 在网格中位置
.item-a {
  align-self: center;
}
align-self:center 在网格中位置
.item-a {
  align-self: stretch;
}
align-self:stretch 在网格中位置(默认)

place-self

place-self这个属性可以同时设置 align-self 和 justify-self 属性。

语法:

  • auto 使用默认的对齐方式
  • <align-self> /<justify-self> – 第一个值是设置 align-self,第二个值是设置justify-self。如果第二个值忽略,那就是第一个值被赋值给两个属性。

例如:

.item-a {
  place-self:center;
}
place-self:center 子项在网格中的位置
.item-a {
 place-self:center stretch
}
place-self:center stretch 子项在网格中的位置

几乎所有的支持grid布局的浏览器都支持place-self属性 (Edge浏览器从79版本开始支持)

特殊的单位和函数

我们会在css 网格布局使用很多的 fr 这个单位值,例如 1fr 。这个值的含义是“剩余空间的一部分”。因此下列的代码意味着:

.grid-template-columns:1fr 3fr;

第一栏占据25%的空间,第二栏占据75%的空间。

如果我们基于百分比的列去添加填充物。但是我们使用了其他的单位。fr这个单位能够与其他长度单位组合的很好。如下列代码所示:

grid-template-clomuns: 50px min-content 1fr;

当我们设置行和列的尺寸时,我们使用用到过所有单位进行设置,像 px,rem,pt等等单位。此外我们还可以使用一些关键字。

  • min-content: 内容的最小尺寸。想象一下像 “E pluribus unum “这样的一行文字,最小内容可能是 “pluribus “这个词的宽度。
  • max-content:内容的最大尺寸。上面的那个句子,整个句子的长度就是max-content的值。
  • auto: 这个关键词很像fr单位,只是在分配剩余空间时,它们在与fr单位的大小之争中 “输了”。
  • fit-content:使用合适的空间,但绝对不能少于min-content,也不能多于max-content。
  • fr 单位:上图提过。

与尺寸相关的函数

  • minmax()函数的作用与他名字的含义一样:它为长度设定了一个最小和最大的值。这在与相对单位结合起来是很有用的。比如我们就像让一列最小只能缩小到100px。当需要使用时候,它很有用
grid-template-columns:minmax(100px, 1fr) 3fr;
  • min() 函数
  • max() 函数

repeat()函数和关键字

repeat()函数能够让我们少敲几次键盘。看下面的例子:

grid-template-columns:
    1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
/* easier: */
repeat(8, 1fr);

/*especially when: */
grid-template-columns:
  repeat(8, minmax(10px, 1fr));

与一些关键字结合的时候,repeat()可以变得更加灵活花哨。

  • auto-fill:在一行中尽可能多地装入可能的列,即使它们是空的。
  • auto-fit:自动拟合。不管有多少列,都要装入空间。倾向于扩大列来填补空间,而不是空列。

下面的代码所有CSS网格中最著名的片段,也是历史上最伟大的CSS技巧之一

这两个关键字的不同点可以参考auto-fill与auto-fit的不同点

Masonry

CSS网格的一个实验性特征是砖石结构布局(masonry layout).

请注意,有很多方法可以实现CSS砌体布局,但大部分都是骗人的,要么有很大的弊端,要么不是你所期望的那样。

现在这个布局有官方规范。在firefox浏览器中可以开启这个支持。

.container { display:grid; grid-template-columns:repeat(4, 1fr); grid-template-rows:masonry; } 可以参考Rachel’s article这篇文章有个更深的了解。

Subgrid

subgrid 是网格的一个非常有用的功能,它允许网格项有一个自己的网格,从父网格中继承网格线。

.parent-grid { 
  display:grid;
  grid-template-columns: repeat(9, 1fr);
}
.grid-item {
  grid-column: 2 / 7
  display:grid;
  grid-template-columns:subgrid;
}
.child-of-grid-item {
  /* gets to participate on parent grid! */
  grid-column: 3 / 6;
}

这个目前只有火狐浏览器支持,但是这个功能需要在所有浏览器中普及。

了解display: contents;也很有用。这与subgrid不一样,但它有时也是一个有用的工具,其方式类似。

<div class="grid-parent">
  <div class="grid-item"></div>
  <div class="grid-item"></div>

  <ul style="display: contents;">
    <!-- These grid-items get to participate on 
         the same grid!-->
    <li class="grid-item"></li>
    <li class="grid-item"></li>
  </ul>
</div>

流体柱片段

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  /* This is better for small screens, once min() is better supported */
  /* grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); */
  gap: 1rem;
}

动画

根据css grid 布局模型 leve1 规范。有5个可以动画的gird 属性:

  • grid-gap, grid-row-gap, grid-column-gap 这个属性设置为具体长度,百分比或者使用 calc 的时候。
  • grid-template-columns, grid-template-rows: 设置成一个具体长度,百分比,或者使用 calc列表 。

在写这篇文章的时候,只有(gird-)gap, (grid-)column, (grid-) column-gap实现了动画。

Browser(grid-)gap, (grid-)row-gap, (grid-)column-gapgrid-template-columnsgrid-template-rows
Firefoxsupported ✅ 53+supported ✅ 66+supported ✅ 66+
Safari 12.0not supported ❌not supported ❌not supported ❌
chromesupported ✅ 66+not supported ❌not supported ❌
Chrome for Android 66+,Opera Mini 33+supported ✅not supported ❌not supported ❌
Edgesupported ✅ 16+not supported ❌not supported ❌
浏览器对grid布局动画支持的情况

发表评论