CSS栅格系统

2020-03-01  本文已影响0人  Geeker工作坊

开始之前

栅格系统,做过前端的同学对这个词应该是比较熟悉,作为90后的一批的前端程序员(甚至更早,伟哥也不不是太清楚,因为那个时候还没出生)学习做网站的时候就知道会用 bootstrap 了,当然了bootstrap里面应该是叫做网格系统。row, col-md-1, col-md-5,这些东西不知道有没有唤起过大家的一些回忆。网格系统的出现确实让我们做网站布局轻松了很多,网格系统就好比家里的地砖,把房子分成了一个一个的小格子,然后我们在上面随意摆放东西即可。三大框架(react angular vue)出来后。基于三大框架衍生出来的一些 UI 框架也有自己的栅格系统,像 ant-design 中深蓝栅格系统 <Row> <Col span={4}> </Row>, element-ui 响应式栅格布局 <el-row><el-col :span=4></el-row>都是栅格系统的代表。CSS3的新特性 Grid 同样是为了实现网格布局,这次就聊聊这个 Grid。本篇内容理论基础大部分是参考了阮一峰老师的教程,在撸代码的时候,加进去了一些自己疑问地方的,仿照移动端小米首页加入了实战的一些内容。

概述

网格布局(Grid)是最强大的CSS布局方案。
它将网页划分成了一个个网格可以任意组合不同的网格,作出各种各样的布局。


上图这样的布局,就是Grid布局的拿手好戏。
Grid布局与flex布局有一定的相似性。都可以指定容器内部多个项目的位置。但是他们也存在重啊区别。
Flex布局是轴线布局,只能指定“项目”针对轴线的位置,可以看作是 一维布局。Grid布局则是将容器分成“行”和“列”,产生单元格,然后指定“项目所在”的单元格,可以看作是“二维布局”。Grid布局远比Flex布局强大。

基本概念

学习 Grid 布局之前,需要了解一些基本概念。

容器和项目

采用网格布局的区域,称为“容器”(container)。容器内部采用网格定位的字元素,称为“项目”(item)。

<div>
  <div><p>1</p></div>
  <div><p>2</p></div>
  <div><p>3</p></div>
</div>

上面代码中,最外层的 <div> 元素就是容器,内层的三个<div>元素就是项目。
注意:项目只能是容器的顶层子元素,不包含项目的子元素,比如上面代码中<p>元素就不是项目。Grid 布局只对项目生效。

行和列

容器里面水平区域称为“行”(row), 垂直区域称为"列"(column)。



上图中,水平的深色区域就是"行",垂直的深色区域就是"列"。

单元格

行和列的交叉区域,称为"单元格"(cell)。
正常情况下,n行和m列会产生n x m个单元格。比如,3行3列会产生9个单元格。

网格线

划分网格的线,称为"网格线"(grid line)。水平网格线划分出行,垂直网格线划分出列。
正常情况下,n行有n + 1根水平网格线,m列有m + 1根垂直网格线,比如三行就有四根水平网格线。


上图是一个 4 x 4 的网格,共有5根水平网格线和5根垂直网格线。

容器属性

Grid 布局的属性分成两类。一类定义在容器上面,称为容器属性;另一类定义在项目上面,称为项目属性。这部分先介绍容器属性。

display 属性

display: grid指定一个容器采用网格布局。这个跟弹性盒布局 flex 一样

<span>foo</span>
<div id="container">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
  <div class="item item-4">4</div>
  <div class="item item-5">5</div>
  <div class="item item-6">6</div>
  <div class="item item-7">7</div>
  <div class="item item-8">8</div>
  <div class="item item-9">9</div>
</div>
<span>bar</span>
#container{
  display: grid;
  grid-template-columns: 50px 50px 50px;
  grid-template-rows: 50px 50px 50px;
}

.item {
  font-size: 2em;
  text-align: center;
  border: 1px solid #e5e4e9;
}

.item-1 {
  background-color: #ef342a;
}

.item-2 {
  background-color: #f68f26;
}

.item-3 {
  background-color: #4ba946;
}

.item-4 {
  background-color: #0376c2;
}

.item-5 {
  background-color: #c077af;
}

.item-6 {
  background-color: #f8d29d;
}

.item-7 {
  background-color: #b5a87f;
}

.item-8 {
  background-color: #d0e4a9;
}

.item-9 {
  background-color: #4dc7ec;
}

展示效果



默认情况下,容器元素都是块级元素,但也可以设成行内元素。

#container{
  display: inline-grid;
  grid-template-columns: 50px 50px 50px;
  grid-template-rows: 50px 50px 50px;
}

上面代码将容器元素指定成为了行内块级元素。


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

grid-template-columns 属性, grid-template-rows 属性

容器指定了网格布局之后,接着就要划分行和列。grid-template-columns属性定义每一列的列宽,grid-tempalge-rows定义每一列的行高。

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

上面的代码指定了一个三行三列的网格,行列的宽高都是100px



当然, 除了使用绝对单位,也可以使用百分比

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

(1) repeat()
有时候,重复写同样的值非常麻烦,尤其是网格很多的时候。这是可以使用repeat()函数,简化重复的饿值。上面的代码使用repeat改写如下。

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

repeat()接收两个参数,第一个参数是重复的次数,第二个参数是所有要重复的值。
repeat()重复也可以是某种模式。

grid-template-columns: repeat(2, 100px 20px 80px)

上面的代码定义了6列,第一类和第四列的宽度为100px, 第二类和第五列宽度为20px,第三列和第六列宽度为80px。



这里补充一点,网格一旦划分好,每个网格的大小就固定,不会因为里面的div的大小形式有任何改变。
举个列子,上面的例子中我们的html布局如下:

<div id="container">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
  <div class="item item-4">4</div>
  <div class="item item-5">5</div>
  <div class="item item-6">6</div>
  <div class="item item-7">7</div>
  <div class="item item-8">8</div>
  <div class="item item-9">9</div>
</div>
.container{
  display:grid;
  grid-template-row: repeat(3, 100px);
  grid-template-columns: repeat(3, 100px);
}

其他的没有任何变化。大家知道现在的展示就是一个九宫格,里面的元素充满每个格子。但是我们现在要给每个 item 里面增加一个如下的样式:

.small{
    width:50px;
  height:50px;
}

网页就会出现下面的样子,可以看出即使我们吧每个item里面定义了样式,但是一旦在container我们规定了格子的大小,那么格子大小就不会改变。


(2)auto-fill 关键字

有时,单元格的大小是固定的,但是容器的大小确不确定。如果希望每一行(或者每一列) 容纳尽可能多的单元格,这是可以使用 auto-fill 关键字表示自动填充。

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

(3) fr 关键字
为了方便表示比例关系,网格布局提供了 fr 关键字(fraction的缩写,意为“片段”)。如果两列的宽分别为 1fr 和 2fr,就表示后者是前者的两倍。
.container{
  display: grid;
  grid-template-columns: 1fr 1fr;
}

上面表示两个相同宽度的列
fr可以与绝对长度的单位结合使用,这时会非常方便。

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

上面的代码表示,第一列的宽度为150px, 第二例的宽度是第三列的一半。


(4) minmax()
minmax()函数产生一个长度的范围,表示长度就在这个范围之中。它接受两个参数,分别为最大值和最小值。这样网格就不会随着容器的任何变化变化,会始终在这个长度范围内波动,类似我们设置 min-width;max-width。
grid-template-columns: 1fr 1fr minmax(100px 1fr)

(5) auto 关键字
auto关键字表示由浏览器长度自己决定。

grid-template-columns: 100px auto 100px

(6)网格线的名称
grid-template-columnsgrid-template-rows属性里面,还可以使用方括号,指定每一根网格线的名字,方便以后的引用。

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

上面的代指定网格为 3 X 3 的布局,因此有 4 根垂直网格线 和 4 根水平网格线。方括号里面依次是这八根弦的名字。网格布局允许同一根线有多个名字,比如 [fifth-line row-5]
当然了如果没有给网格线起别名,那么浏览器也自动给网格线起一个名字,那就是每个网格线的位置,比如本例中 水平网格线的默认名字是 1 2 3 4,垂直网格线的默认名字同样是 1 2 3 4。 至于为什么给网格线起个名字,那可能是有关网格item的占位有关,具体有什么用会在后面介绍,现在先不多说。

(7)布局实例
grid-template-columns属性对于网页布局非常有用。两栏布局只需要一行代码。

.wrapper{
  display: grid;
  gird-template-columns: 70% 30%
}

上面的代码将左栏设置为 70%,右栏设置为30%。
传统的十二栏布局,写起来也很容易。

.wrapper{
    display: grid;
  grid-template-columns: repeat(12, 1fr);
}

3.3 grid-row-gap 属性, grid-column-gap 属性, grid-gap 属性

布局里面的元素总不能是挨在一起,设计上要有空间感,留白一般是比不可少的。对于里面的留白我们可以使用我们原来的一次CSS属性方法 margin padding 等,但是 栅格布局也有自己的间距属性来控制留白。
gird-row-grap 属性用来设置行与行的间距(行间距),grid-column-grap 属性设置列于列的间距(列间距)。现在这两个属性可以分别简写为 row-grapcolumn-grap

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

本文开始时代码,添加以上两个属性后


grid-grap属性时 grid-column-gapgrid-row-gap的合并简写形式,现简写为 gap 语法如下:
gap: <row-gap> <column-gap>

因此上面一段 CSS 代码等同于以下代码。

.container{
  gap: 20px 20px
}

如果 gap省略了第二个值,浏览器默第二个值等于第一个值。这个跟margin 和 padding 一样的。

实战一下

实现一下小米移动端首页红框里面的布局



可以看到要实现红框里面的布局,其实就是画了四个格子,左边的图片占了两个格子,右边的两个小的图片各占了一个格子。
实现之前先介绍一点 项目上上的属性,用到了上面介绍的网格线名称,我们按照栅格线编号放置元素。

<div class="container">
  <div item item-1>1</div>
  <div item item-2>2</div>
  <div item item-3>3</div>
</div>
.container{
  width:300px;
  height:300px;
  display:grid;
  grid-template-rows:repeat(2,1fr);
  grid-template-columns: repeat(2, 1fr);
}
.container div:nth-child(1){
  grid-row-start: 1; // 元素从行的第几条线开始,如果设置了别名可以使用别名
  grid-column-start:1; // 元素从列的第几条开始 如果设置了别名可以使用别名
  grid-row-end:3; // 元素在行的第几条线结束
  grid-column-end:2; //元素在列的第几条结束
}

使用栅格布局可以轻松的实现了要求,如果使用之前的方法,那就可能就要多画几个div, 设置一些浮动和偏移等。

grid-template-areas 属性

网格布局允许指定 “区域” (area),一个区域由多个单元格组成。grid-template-areas 数据定义区域。

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

上面的代码划分出 9 个单元格,然后将其定义为 a 到 i 的九个区域,分别对应这 9 个单元格。
多个单元格合并成一个区域的写法如下:

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

下面是一个实例布局

grid-template-areas: "header header header"
                     "main main sidebar"
                     "footer footer footer";

上面代码中,顶部是页眉区域,底部是页脚区域,中间则分为 main 和 sidebar。
如果某些某些区域不需要利用,则使用 “点” (.)表示。
上面代码中,中间一列为点,表示没有用到该单元格,或者该单元格不属于任何区域。

注意,区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为区域名-start,终止网格线自动命名为区域名-end。
比如,区域名为header,则起始位置的水平网格线和垂直网格线叫做header-start,终止位置的水平网格线和垂直网格线叫做header-end。

grid-auto-flow 属性

划分网格以后,容器的子元素会按照顺序,自动放着在每一个网格。默认的防治顺序是“先行后列”,即先填满第一行,在开始放入第二行,即按照下图数字的顺序。


这个顺序由grid-auto-flow属性决定,默认值是 row, 即 “先行后列”。也可以将它设成 column,变成 “先列后行”。这个分 弹性盒模型中 flex-direction 属性类似。
grid-auto-flow: column;

上面代码设置了 column以后,放置顺序就变成了下图。


grid-auto-flow属性除了设置成 rowcolumn,还可以设置成 row densecolumn dense。这两个值主要用于某些项目指定以后,剩下的项目该怎么自动放置。
假设我们让 1号项目和2号项目各占据两个单元格,然后在默认的 grid-auto-flow:row情况下,会产生下面这样的布局。

上面1号项目后面的位置是空的,这是因为3号项目默认跟着2号项目,所以会排在2号项目后面。
现在修改设置,修改为row dense ,表示“先行后列”,并且尽可能紧密填满,尽量不出现空格。
grid-auto-flow: row dense

效果如下:


上图会先填满第一行,再填满第二行,所以3号就会紧跟在1号项目的后面。8号和9号项目就会排到第四行。
如果将设置改为 column dense,表示“先列后行”,并且尽量填满空格。
grid-auto-flow: column dense
上面代码效果

上图会先填满第一列,再填满第二列,所以3号项目在第一列,4号项目在第二列。8号和9号项目被挤到了第四列。

justify-items 属性, align-items 属性, place-items 属性

justify-items属性设置单元格内容的水平位置(左中右),align-items属性设置单元格内容的垂直位置(上中下)。

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

这两个属性的写法完全相同,都可以取下面的值

start:对齐单元格的起始边缘。
end:对齐单元格的结束边缘。
center:单元格内部居中。
stretch:拉伸,占满单元格的整个宽度(默认值)。
.container {
  justify-items: start;
}
表示,单元格内内容左对齐,效果如下:
.container {
  align-items: start;
}

表示,单元格的内容头部对齐,效果如下。


place-items 属性是 align-itemsjustify-items 属性的合并简写形式。
// place-items: <align-items> <justify-items>

place-items: start end;

如果省略第二个值,则浏览器认为与第一个值相等。

justify-content 属性, align-content 属性, place-content 属性

justify-content属性是整个内容区域在容器里面的水平位置(左中右),align-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;  
}

这两个属性的写法完全相同,都可以取下面这些值。(下面的图都以justify-content属性为例,align-content属性的图完全一样,只是将水平方向改成垂直方向。)

start - 对齐容器的起始边框
end - 对齐容器的结束边框
center - 容器内部居中
stretch - 项目大小没有指定时,拉伸占据整个网格容器
space-around - 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍
 space-between - 项目与项目的间隔相等,项目与容器边框之间没有间隔。
space-evenly - 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。

place-content属性是align-content属性和justify-content属性的合并简写形式。
// place-content: <align-content> <justify-content>

place-content: space-around space-evenly;

如果省略第二个值,浏览器就会假定第二个值等于第一个值。

实战 实现一个底部菜单栏

还是以小米官网移动端为例;要实现的状态如下:



要实现移动端官网下面底部菜单栏:我们可以看出底部菜单栏时分成了5个格子,那我们可以做成一个1行5列的布局,假设我们的容器高度时100px;宽度是自适应的不知道,里面每个图标和文字容器宽高是80px。那就可以如下实现。

<div class="container">
    <div class="item item-1">1</div>
    <div class="item item-2">2<div>
    <div class="item item-3">3</div>
    <div class="item item-4">4</div>
    <div class="item item-5">5</div>
</div>
.container{
  display:grid;
  grid-template-columns: repeat(5, 1fr);
  grid-template-rows: 1fr;
  place-items: center;
}
.container div{
  width:80px;
  height:80px;
}

实现效果如下图所示:


grid-auto-columns 属性, grid-auto-rows 属性

有些时候,一些项目的指定位置,在现有网格的外部。比如网格只有3列,但是某一个项目指定在第五行。这时,浏览器会自动生成多余的网格,一便放置项目。

grid-auto-columns 属性和 grid-auto-rows属性用来设置浏览器会自动创建的多余网格的列宽和行高。它们的写法与grid-templat-columnsgrid-template-rows完全相同。如果不指定这两个属性,浏览器会完全根据单元内容的大小决定新增网格的列宽和行高。

下面的例子,划分的网格是 3 X 3,但是8号项目和9号项目指定子第四行,9行项目指定在第五行。

.container{
    dispaly: grid;
  grid-template-columns: repeat(3, 100px);
  gird-template-row: repeat(3, 100px);
  grid-auto-rows: 50px; //为新增行指定统一行高度
}

.item-8 {
  background-color: #d0e4a9;
  grid-row-start: 4;
  grid-column-start: 2;
}

.item-9 {
  background-color: #4dc7ec;
  grid-row-start: 5;
  grid-column-start: 3;
}

项目属性

上面描述了定义在容器上的属性,下面这些属性定义在项目上面。

grid-column-start 属性, grid-column-end 属性, grid-row-start 属性, grid-row-end 属性

这些属性上面有提到过,用来指定项目的位置,具体的方法就是指定项目的四个边框,分别定位在哪根网格线。

grid-column-start属性:左边框所在的垂直网格线
grid-column-end属性:右边框所在的垂直网格线
grid-row-start属性:上边框所在的水平网格线
grid-row-end属性:下边框所在的水平网格线
.item-1 {
  grid-column-start: 2;
  grid-column-end: 4;
}

上面的代码指定, 1号项目的左边框是第二根垂直网格线,右边框是第四根垂直网格线。


上图中,只指定了1号项目的左边框和右边框,没有指定上下边框,所以会采用默认位置,即上边框是第一根水平网格线,下边框是第二根水平网格线。

除了1号项目以外,其他项目都没有指定位置,由浏览器自动布局,这时它们的位置由容器的grid-auto-flow属性决定,这个属性的默认值是row,因此会"先行后列"进行排列。读者可以把这个属性的值分别改成columnrow densecolumn dense,看看其他项目的位置发生了怎样的变化。

下面的例子是指定四个边框位置的效果。

.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;
}

上面代码中,左边框和右边框的位置,都指定为网格线的名字。

这四个属性的值还可以使用span关键字,表示"跨越",即左右边框(上下边框)之间跨越多少个网格。也是根据偏移量对元素进行定位。使用过 element-UI 的朋友会比较熟悉。<el-col :span='4'></el-col>

下面代码表示,1号项目的左边框距离有边框跨越2个网格。

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

这与下面的代码效果完全一样

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

使用这四个属性,如果产生了项目的重叠,则使用z-index属性指定项目的重叠顺序。

grid-column 属性, grid-row 属性

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

.item {
  grid-column:  / ;
  grid-row:  / ;
}

下面是一个例子

.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占据第一行,从第一根列线到第三根列线。

这两个属性之中,也可以使用span关键字,表示跨越多少个网格。

.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;
}

上面代码中,项目item-1占据的区域,包括第一行 + 第二行、第一列 + 第二列。


斜杠以及后面的部分可以省略,默认跨越一个网格。

.item-1 {
  grid-column: 1;
  grid-row: 1;
}

上面代码中,项目item-1占据左上角第一个网格。

实战 自主实现一个类似 bootstrap 栅格系统

bootstrap栅格系统是把一行分成12个格子,然后使用 col-1,2,3,4,5.... 分别表示跨越几列。对于实现一个非响应式的这样的栅格系统有了 grid 我们实现起来就非常的方便了。

.row{
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 10px; // 网格之间给10个间距
}
.col-1{
  grid-column-end:span 1; //在原来的技术长列向后偏移一个单位 
}
.col-2{
  grid-column-end:span 2; //在原来的技术长列向后偏移一个单位 
}
.col-3{
  grid-column-end:span 3; //在原来的技术长列向后偏移一个单位 
}

/*一次类推到12 就是闲了我们需要栅格布局*/
/*当然了里面的属性也可以简写*/
.col-1{
  grid-column: span 1;
}

grid-area 属性

grid-area属性指定项目放在哪一个区域。

#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';
}

.item-1 {
  grid-area: e;
}

以上代码, 1号项目位于 e 区域,效果如下图所示


grid-area属性还可用作grid-row-startgrid-column-startgrid-row-endgrid-column-end的合并简写形式,直接指定项目的位置。
.item {
  grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
}

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

实战 实现小米移动端首页布局

要实现的效果如下图所示



实现该布局的网格划分可以下面的形式:
可以看出我们将真个网页划分成一个三行两列的结构,下面就开始实现该布局。
.container{
    width:100vw;
  height:100vh;
  display:grid;
  gap:10px;
  gird-template-rows:60px 1fr 60px;
  gird-template-columns:60px 1fr;
  gird-template-areas: 'header header'
                                         'nav main'
                                         'footer footer'
}

.item {
  font-size: 4em;
  text-align: center;
}

.item-1 {
  grid-area:header;
  background-color: #ef342a;
 
}

.item-2 {
  grid-area:nav;
  background-color: #f68f26;
}

.item-3 {
  background-color: #4ba946;
}

.item-4 {
  grid-area:footer;
  background-color: #0376c2;
}
<div class="container">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
  <div class="item item-4">4</div>
</div> 

justify-self 属性, align-self 属性, place-self 属性

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

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

.item {
  justify-self: start | end | center | stretch;
  align-self: start | end | center | stretch;
}

这两个属性都可以取下面四个值。

start:对齐单元格的起始边缘。
end:对齐单元格的结束边缘。
center:单元格内部居中。
stretch:拉伸,占满单元格的整个宽度(默认值)。

下面是justify-self: start的例子。

.item-1  {
  justify-self: start;
}

place-self属性是align-self属性和justify-self属性的合并简写形式。
place-self: <align-self> <justify-self>;

place-self: center center;

如果省略第二个值,place-self属性会认为这两个值相等。

写在最后

本来觉得写CSS这部分的内容应该是比较容易,但是发现写下来还真的很多,疫情期间家里储备弹尽粮绝,饿着写完了这一部分的内容。就是搬运也很耗时间,吐槽一下简书对于Typora兼容行还是不够好,直接copy过来很多的错误和乱码,还要重新写一遍。。希望自己能够再接再厉,继续写下去!

上一篇 下一篇

猜你喜欢

热点阅读