CSS 布局之 Grid

125 阅读5分钟

栅栏、栅格、网格等只是翻译不同

先来个 grid 容器(三列四行,每个元素都是100px的正方形),给容器设置 display:grid;

行数用这个设置 grid-template-rows:100px 100px 100px 100px; ,四行,每行100px高

列数则用这个 grid-template-colunmns:100px 100px 100px; ,三列,每列100px宽

行和列的设置中,可以使用 repeat() 函数,这个可以快速构造某种模式的布局,将上面的设置用 repeat() 实现一下

.container{
    display: grid;
    grid-template-rows:repeat(4,100px);
    grid-template-columns:repeat(3,100px);
    /* repeat()函数可以传多个参数,第一个是重复次数,后面的是重复的样式 */
    /* 如果需要做一个4列的布局,其中1、3列是20px,2、4列是50px,按照下面所写即可 */
    /* grid-template-columns:repeat(2,20px 50px); */
}

gird-template 是 gird 布局模板 行和列 的缩写。所以上面的代码可以简写成:

.container{
    grid-template:repeat(4,100px) / repeat(3,100px);
}

行和列的属性不止可以用确定单位px,也可以用相对单位比如百分比。但当px和百分制同时使用的时候,会出现内容比容器大、内容超出容器的现象,因为百分比是根据容器的宽度设置的,但是它并不会自动计算可用空间的百分比。比如设置成三列,分别是100px 40% 60%,那么第一列会出现100px的宽度,但后面会出现容器宽度的40%、60%,也就是说后面的两列加起来的宽度是容器宽度的100%,所以再加上100px就会超过容器自身的宽度。

如果一定要用百分制达到预期效果的话,上面的属性值可以改成 100px 40fr 60fr 。fr 就是剩余可用空间的百分比。

属性值同样可以使用auto ,代表让内容决定网格的长宽。可以采用100px auto 类似这样混合的形式。

对齐

  • justify-items 元素横向对齐

    • center
    • start
    • end
    • stretch 伸展(在网格有确定长宽时没有变化,当网格没有确定长宽,网格内元素会自动拉伸适应网格,是默认值,不用特意声明)
  • align-items 元素纵向对齐

  • justify-content 网格横向对齐

  • align-content 网格纵向对齐

间距

row-gap 行间距

column-gap 列间距

gap 间距的缩写,值是 行间距 列间距 这样的排列,如果只设置一个值,代表行间距列间距一样。

合并

理解这个内容要先知道 gird 布局的 线 是如何排布的,简单分了一个 3*3 有 7 个元素的 grid 容器,可以在浏览器的布局中看到它的线的划分。 note2grid-row0.png

grid-row 合并行

grid-column 合并列

个人理解,以行合并为例。

当值为1,该元素在第一行第一列,坐标(1,1);当值为2,该元素在第二行第一列,坐标(1,2);当值为3,该元素在第三列第一行,坐标(1,3)。当该元素改编了位置后,在它后面的元素会按顺序顶替掉它的位置,它占位置的那个地方,原先的元素依次往后面挪出空间。

note2grid-row1.png

当值为 x / y 这种形式后,就代表这它的占地位置从第 x 根线开始,到第 y 根线结束。比如 1/3,就是从行的第一根线开始,到行的第三根线结束。

note2grid-row2.png

如果是 2 / 4 ,就是从行的第二根线开始,到第四根线结束。

note2grid-row3.png

从上面看出,如果选中的元素改变位置,其他元素会按顺序从左上角开始补齐位置。

所以说是合并,其实是包括了决定位置,操作性变大了。

如果想独占容器的一行或者一列,可以直接写 1 / 最后一根线的序号,也可以简化为 1 / -1,-1 代表最后一行。

x / span y 代表了从第 x 根线出发,占用 y 格,也可以达到上面合并的效果。

再聊一下 grid-area ,它是上面行纵合并的简写,它的语法是 row / column ,也就是如果 2 / 3 的话,就代表元素的位置是(2,3),可以看出在区域合并中 x / y 的写法并不是以网格的线为标准。那如果想用网格的线或是要合并某个元素,应该怎么写呢?

grid-area:x1 / y1 / x2 / y2 这样写,感觉很怪,但是就是这个样子,并且请注意,这个写法也需要数线,比如这样写grid-area:2/1 / 4/2 ,就代表从行的 2 线、列的 1 线开始,到行的 4 线、列的 2 线结束。

note2grid-row4.png

grid-template-areas:"hearder header header" "sidebar main main" "sidebar main ." 这个属性用来划分各个区域的属性,用 "" 来包裹每一行的属性名称,名称是自定义的。. 表示这里是一个空格。

然后继续使用 grid-area:hearder 来按照区域名称来进行一个自动合并,注意这里不要加引号。个人认为这个方法要比上面需要数线的好得多,并且还为每一个区域划分好功能,感觉一下子就清晰明了了很多。

那么它兼容.....吗?

在如今二〇二二年吧,市面上大部分浏览器都兼容了 grid 布局,这个布局看似很麻烦,但是复习了一遍的我觉得其实很好用,甚至在很多方面变得更便捷了。

如果不用 u know who 的浏览器的话,基本上不用考虑兼容问题啦。

note2grid-row5.png