【阅读简记】CSS3 Grid

CY 2019年03月28日 1,729次浏览

刚才阅读了一下CSS的Grid布局相关文档,简单的总结一下我学到的东西。

任何界面编程语言都有自己的一套的布局方式,JavaFXAndroid还有好多这种可以做界面的技术,里面都是有很多很多的布局方式供用户选择,这些布局方式都是UI设计师的智慧结晶,CSS也一样,之前学习的Flex布局,他和JavaFX中的HBoxVBox非常的类似,但是缺点在于他们都是一维布局,只能在一个方向上完成想要的布局,这样的话完成复杂的布局还是有一定的难度的,所以我想使用更加自由的布局方式,回想起JavaFX中的布局方式,Grid最为自由了,之前学习CSS3Flex布局的时候无意间在MDN文档看到了CSS支持Grid布局,所以就找文档看了看。

CSS的布局

  • 正常布局流:实际上就是HTML的默认布局,就是不加入任何CSS布局的时候呈现出来的布局方式

  • display属性:这种布局就是之前使用的blockinline属性值,可以稍微的改变一下原来的正常布局流

  • 弹性盒子:就是Flex布局,用水平和垂直轴的方式来完成单一方向上的布局

  • 网格:目前CSS中最强大的布局,就是平常所说的栅格布局,他和弹性盒子布局的不一样就是可以同时控制横方向和纵方向,而不需要一个方向一个方向的去布局

  • 浮动 :这个稍微有点CSS基础的人都知道的布局

  • 定位 :定位布局有时候太死板了,有些时候用用还不错,比如说fixed和sticky

  • CSS 表格布局:这个就是使用css去模仿table表格标签的方式去完成布局了,用的人应该不多,毕竟每个东西都是有一定的使用范围的,如果是一个表单组件,使用这个再好不过了。

  • 多列布局:MDN多列布局介绍,BootStrap的Card columns组件就用到了这种布局方式

Grid布局当前因为兼容性的问题所以真正用这种布局的网站也不是特别多。

摘录一下【阮一峰】CSS Grid 网格布局教程中我感觉重要的知识点,怎么感觉全摘录下来了

Grid布局概念

容器:和之前的容器一样

项目:容器里面的一个个子元素就是项目

Grid布局的开发步骤

创建容器,画网格线,然后填充内容。

Grid的容器属性

启用网格布局

在容器上规定:display: grid;即可

默认是块级元素,变为行内元素:display: inline-grid;

设为网格布局以后,容器子元素(项目)的floatdisplay: inline-blockdisplay: table-cellvertical-aligncolumn-*等设置都将失效。

画单元格

画单元格使用到了grid-template-columns 属性和grid-template-rows 属性

  • grid-template-columns属性规定了有几列,每一列有多宽

  • grid-template-rows 属性规定了有几行,每一行有多高

使用绝对单位

.container {
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
}

3 * 3的一个单元格,每个单元格的长宽都是100px

查看效果

使用百分比

.container {
    display: grid;
    grid-template-columns: 33.33% 33.33% 33.33%;
    grid-template-rows: 33.33% 33.33% 33.33%;
}

查看效果

repeat()

.container {
    display: grid;
    grid-template-columns: repeat(3, 33.33%);
    grid-template-rows: repeat(3, 33.33%);
}

使用grid-template-columns: repeat(2, 100px 20px 80px);的话相当于划了6列单元格

查看效果

auto-fill 关键字

.container {
    display: grid;
    grid-template-columns: repeat(auto-fill, 100px);
}

上面代码的意思是以100px一列的宽度来完成自动填充

查看效果

fr 关键字

.container {
    display: grid;
    grid-template-columns: 1fr 1fr;
}
.container {
    display: grid;
    grid-template-columns: 150px 1fr 2fr;
}

第一列的宽度为150像素,第二列的宽度是第三列的一半。

查看效果

minmax()

grid-template-columns: 1fr 1fr minmax(100px, 1fr);

第三列列宽不小于100px,不大于1fr

auto 关键字

grid-template-columns: 100px auto 100px;

第二列自动确定

网格线的名称

.container {
    display: grid;
    grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
    grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4];
}
.container {
    display: grid;
    grid-template-columns: [c1-start] 100px [c1-end c2-start] 100px [c2-end c3-start] auto [c3-end];
    grid-template-rows: [r1-start] 100px [r1-end r2-start] 100px [r2-end r3-start] auto [r3-end];
}

规定网格线的名称后方便后面确定项目在容器中的位置。

查看效果

单元格间距

  • row-gap 属性:行间距

  • column-gap 属性:列间距

  • gap 属性:行间距和列间距(组合)

.container {
    row-gap: 20px;
    column-gap: 20px;
}

等同于

.container {
    gap: 20px 20px;
}

查看效果

区域属性

一个区域由单个或多个单元格组成。grid-template-areas属性用于定义区域

.container {
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    grid-template-areas: 'a b c'
        		 'd e f'
        		 'g h i';
}

划分了a-i9个区域

grid-template-areas: 'a a a'
		     'b b b'
		     'c c c';

上面代码划分了a,b,c3个区域

如果只想要使用一部分区域,比如说上面的c区域,可以写成下面的形式:

grid-template-areas: '. . .'
		     '. . .'
		     'c c c';

其他的区域全部用.来代替

注意:如果命名了区域,网格线的名字也会被重新命名了。

每个区域的起始网格线,会自动命名为区域名-start,终止网格线自动命名为区域名-end

行列交换

grid-auto-flow属性有两个重要的值rowcolumn

如果设置成了column,之前的第一行,就变成了现在的第一列了。

还有两个属性row densecolumn dense ,用来做剩余空间的填充

grid-auto-flow切换成column后的效果

grid-auto-flow切换成row dense后的效果

针对于所有项目的对齐方式

  • justify-items 属性:容器中的元素左中右的对齐方式

  • align-items 属性:容器中的元素上中下的对齐方式

  • place-items 属性:左中右 、上中下的结合

.container {
    justify-items: start | end | center | stretch;
    align-items: start | end | center | stretch;
}

其中的stretch为拉伸的意思,也是默认的属性值

需要注意的是place-items的属性顺序如下

place-items: <align-items> <justify-items>;

查看效果

针对于整体项目的对齐方式

  • justify-content 属性:整体的左中右

  • align-content 属性:整体的上中下

  • place-content 属性:整体的左中右和上中下的结合属性

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

其中:

  • space-around表示每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍。

  • space-between项目与项目的间隔相等,项目与容器边框之间没有间隔。

  • space-evenly 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。

需要注意的是place-content属性的顺序如下:

place-content: <align-content> <justify-content>

查看效果

规定自动生成网格的宽和高

如果有项目超出了规定的网格,Grid会自动创建网格来容纳这些项目,下面两个属性就有用了。

  • grid-auto-columns属性:规定自动生成的网格的列宽,只有在水平方向超出的时候才有用
  • grid-auto-rows属性:规定自动生成的网格的行宽,只有在垂直方向超出的时候才有用

查看效果

其他组合写法

  • grid-template属性是grid-template-columnsgrid-template-rowsgrid-template-areas这三个属性的合并简写形式。

  • grid属性是grid-template-rowsgrid-template-columnsgrid-template-areasgrid-auto-rowsgrid-auto-columnsgrid-auto-flow这六个属性的合并简写形式。

Grid的项目属性

Grid项目的位置

根据网格线确定项目的位置

  • grid-column-start属性:左边框所在的垂直网格线
  • grid-column-end属性:右边框所在的垂直网格线
  • grid-row-start属性:上边框所在的水平网格线
  • grid-row-end属性:下边框所在的水平网格线

使用方法如下:

.item-1 {
    grid-column-start: 1;
    grid-column-end: 3;
    grid-row-start: 2;
    grid-row-end: 4;
}

查看效果

使用网格线的名字

在上面曾经定义了网格线的名字,在这里就派上用场了:

.item-1 {
    grid-column-start: header-start;
    grid-column-end: header-end;
}

上面的网格线的名字是使用了规定了area名称后自动生成的网格线名字

使用偏移量

.item-1 {
    grid-column-start: span 2;
}

如果确定了项目的位置后,产生了两个项目重叠的话,可以使用z-index,这和定位中的z-index使用方式一样

项目位置属性的缩写

  • grid-column属性是grid-column-startgrid-column-end的合并简写形式

  • grid-row属性是grid-row-start属性和grid-row-end的合并简写形式。

.item-1 {
    grid-column: 1 / 3;
    grid-row: 1 / 2;
}
/* 等同于 */
.item-1 {
    grid-column-start: 1;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 2;
}
.item-1 {
    background: #b03532;
    grid-column: 1 / 3;
    grid-row: 1 / 3;
}
/* 等同于 */
.item-1 {
    background: #b03532;
    grid-column: 1 / span 2;
    grid-row: 1 / span 2;
}

使用area确定项目位置(重点)

  • grid-area属性指定项目放在哪一个区域
.item-1 {
    grid-area: header;
}

模拟小米商城布局

原界面

grid-area属性还可用作grid-row-startgrid-column-startgrid-row-endgrid-column-end的合并简写形式

.item-1 {
    grid-area: 1 / 1 / 3 / 3;
}

单个项目的对齐方式

  • justify-self属性设置单元格内容的水平位置(左中右),跟justify-items属性的用法完全一致,但只作用于单个项目。

  • align-self属性设置单元格内容的垂直位置(上中下),跟align-items属性的用法完全一致,也是只作用于单个项目。

.item {
    justify-self: start | end | center | stretch;
    align-self: start | end | center | stretch;
}
  • place-self 属性是上面两个属性的简写形式
place-self: <align-self> <justify-self>;

参考资料

【后盾人】CSS文档-栅格介绍