哈?原来css网格布局这么简单!!!

2,897 阅读9分钟

前言

在你确认css网格布局真的很简单之前,你肯定要知道css的那些基础知识,比如选择器,属性等,一言概之,你得知道css怎么用。

开篇

css属性大多属性名就已经说明它本身是什么作用了,而你要记住的只不过是相应的值会有什么效果。然而,英文意思翻译过来有时会对理解其作用造成干扰,因而这里列举一些可能会如此的词出来,解释其含义。当你困惑时可回来印证。

  1. “wrap”:包,缠绕

比如:这个词出现在white-space:wrap | nowrap; 粗浅的理解:当文本内容超过容器盒子时,要不要换行。你可能困惑:包和缠绕怎么也跟换行联系不到一起啊。这是因为wrap的主语是“容器盒子”,即容器盒子要不要包住文本。而换行的主语是文本,容器盒子如果要求包住,那文本只能为了达到要求而进行换行。下面将会多次出现该词。

  1. “content”:内容

剑桥词典:“the articles or parts contained in a magazine or book, with the number of the page they begin on”--英文解释起来反而make sense(实用、有实效)。也就是说:这个内容是复数的,有多个的。了解过Flex布局的,最多见的还是justify-contentalign-content。这里你先记住一个重点就够了:复数,也就是多个的。

  1. “item”:项目

剑桥词典:“one of several subjects to be considered”。这里我想强调的点是这个词是单数的,这里与content对比下。而你常见的应该是align-items(多了个“s”)。

  1. “justify”和“align”

这两个词比较难以“make sense”,你且直接记住,justify代表主轴,align代表交叉轴(副轴)。

正文:网格布局挺简单呐!

首先,要形成网格布局,需要一个容器盒子,然后里面就是一个一个的格子,格子之间还有间隙。因此,相关的属性可以分为两组:设置在容器盒子的属性,设置在格子的属性。

1. 总纲领

1.1 设置在容器盒子的属性。

display: grid | inline-grid 一个网格的诞生

😊行列间隔伸缩扎堆
grid-template-columnsgrid-column-gapjustify-itemsjustify-content
grid-template-rowsgrid-row-gapalign-itemsalign-content
简写grid-templategrid-gapplace-itemsplace-content
😁备胎
grid-auto-rowsgrid-auto-flow
grid-auto-columns

1.2 设置在格子的属性。

😆定位开始定位结束简写
grid-column-startgrid-column-endgrid-column
grid-row-startgrid-row-endgrid-row
😘特立独行
align-self
justify-self
简写place-self

1.3 父子组合

💕父盒子子格子
属性grid-template-areasgrid-area

你先别被吓到,上面看起来很多的属性,其实很多是CP 或者是简写,总之你很容易记住。


2. 各个击破。

先从容器盒子的属性开始。display: grid | inline-grid;就不用说了,一个网格布局诞生的前提。

2.1 行列

grid-template-columnsgrid-template-rowsgrid-template。 这一组挺好理解,grid-template-columnsgrid-template-rows列和行分别多少,grid-template将行列简写。

上代码

    <div class="container">
        <h1>Grid Layout</h1>
        <div class="grid-container">
            <div class="item1">item1</div>
            <div class="item2">item2</div>
            <div class="item3">item3</div>
            <div class="item4">item4</div>
            <div class="item5">item5</div>
            <div class="item6">item6</div>
            <div class="item7">item7</div>
            <div class="item8">item8</div>
            <div class="item9">item9</div>
        </div>
    </div>
.grid-container {
    display: grid;
    grid-template-rows: 33.33% 33.33% 33.33%;
    grid-template-columns: 33.33% 33.33% 33.33%; 
}

效果 grid-template

   拓展:

  • grid-template-columns: 33.33% 33.33% 33.33%; 可以换一个写法:grid-template-columns: repeat(3, 33.33%); 多简单!第一个参数代表重复的次数,而第二个参数就是被重复的对象。grid-template-rows同理。
  • fr 是 fraction的缩写,表示“片段、分数”。你直接理解为一个占比的单位。grid-template-columns: 33.33% 33.33% 33.33%; 可以写成grid-template-columns: 1fr 1fr 1fr;或者template-columns: repeat(3, 1fr)。(除了百分比,fr,值还可以是具体的像素距离如100pxautominmax()…自己试试)。
  • repeat(arg1, model)的第一个参数还可以是auto-fill,表示”重复多少次看情况,塞满就行”。

2.2 间隔

grid-column-gapgrid-row-gapgrid-gap。这一组也很好理解。gap表示间隔,前两个的值是20px等表示距离的值。

上代码

.grid-container {
    display: grid;
    grid-template-rows: 33.33% 33.33% 33.33%;
    grid-template-columns: 33.33% 33.33% 33.33%; 
    grid-column-gap: 20px;
    grid-row-gap: 20px;
}

效果 间隔

   拓展:

  • 我们加上gap之后,发现内容超出了盒子,也间接知道了:gap不包含在用百分比分割的格子里面,长度自己算自己的。

grid-gap: <grid-row-gap> <grid-column-gap>;简写

2.3 伸缩

justify-itemsalign-itemsplace-items。这一组很好说,前面解释过item,它是单数,然后加上“s”. 我之所以强调这一点,是因为如下效果。

上代码

.grid-container {
    display: grid;
    grid-template-rows: 33.33% 33.33% 33.33%;
    grid-template-columns: 33.33% 33.33% 33.33%; 
    grid-column-gap: 20px;
    grid-row-gap: 20px;
    justify-items: center;
    align-items: center;
}

效果 place-items

分析助记:首先我们要知道其有四个值:stretch | start | end | center;而其效果是:

  • 对一个格子里面的布局进行拉伸收缩,且不管如何都不会超出原来的格子范围,这对应item单数;
  • 根据item前面是justify或align,控制主轴或副轴,让每一个都重复单个格子的伸缩,这都应了item后面的“s”。

place-items: <align-items> / <justify-items>;简写。

2.4 扎堆

justify-contentalign-contentplace-content。这一组与前面2.3讨论的对应,也简单。首先justify-contentalign-content都有七个值start | end | center | stretch | space-around | space-between | space-evenly;对应有什么效果我只写一个,其他你自己玩一下就懂了,我后面的分析才是重点。

上代码

.grid-container {
    display: grid;
    grid-template-rows: 25% 25% 25%;
    grid-template-columns: 25% 25% 25%; 
    grid-column-gap: 20px;
    grid-row-gap: 20px;
    justify-content: start;
    align-content: end;
}

效果 place-content

分析助记:还记得前面说过吗,content是复数,与2.3的item对立,所以其效果也是“人如其名”,它控制的是主轴或副轴方向的多个格子的拉伸收缩,注意这里要把多个格子看成一个整体。(PS:格子+间隔gap的宽度要<容器宽度才有效果)

place-content: <align-content> / <justify-content>;依旧简写。

2.5 备胎

grid-auto-columnsgrid-auto-rows。这组属性,如果你理解了前面grid-template-columns/rows, 那么这组属性也很好理解。你理解为他们的“备胎”就行,也就是说,当某一个格子被自己的属性“定位”到容器盒子之外的地方时,你提前设定的“备胎”行列就发挥作用了。

上代码

.grid-container {
    display: grid;
    grid-template-rows: 25% 25% 25%;
    grid-template-columns: 25% 25% 25%; 
    grid-auto-columns: 10%;
}
.item3 {
    grid-column-start:4;
}

效果

grid-auto

分析助记:其中控制格子item3定位到容器格子外后面讲解,你只要关心设定的“备胎”列宽度为10%,所以item3“出轨”的列就只要10%。grid-auto-rows同理。 这两个倒是没有简写。

2.6 流

grid-auto-flow。这个属性的重点字眼是flow,即“流”。有值: grid-auto-flow: row | column | row dense | column dense。前两个好理解,就是流的方向,那后面又分别加了dense,意思“紧密,使紧密”。可否理解为流中的排列更加紧密?

且看代码

.grid-container {
    display: grid;
    grid-template-rows: 25% 25% 25%;
    grid-template-columns: 25% 25% 25%; 
    grid-auto-rows: 25%;
    grid-auto-flow: row;
}
.item1 {
    grid-column-start:1;   
    grid-column-end:3;

}
.item2 {
    grid-column-start:1;   
    grid-column-end:3;
}

效果

flow origin

上面代码让第一个格子和第二个格子各占据2各格子的宽度(后面讲解),你关注默认的流动。

加了dense呢?

.grid-container {
    grid-auto-flow: row dense;
}

效果

flow dense

分析助记:蛮简单,就是流动方向控制,没有dense就“松”的“流”动,会留下空格;加dense会填满多余空格。

到这里,其实你已经把容器盒子的grid属性看完了:说白了就六个“东西”:

  • 控制几行几列的grid-template-columns/rows
  • -控制格子间隔的grid-row/column-gap
  • 单个格子里面的拉伸收缩方式align/justify-items
  • 主轴或副轴方向的多个格子的整体的拉伸收缩方式align/justify-content。这样看来,是不是就清晰明了啦。
  • 备胎grid-auto-columns/rows
  • 流动方向及松紧grid-auto-flow。So easy!

grid以上所有属性简写,这里不建议初学者用,等有css优化需求再尝试用。


接下来说一下单个格子自己的属性,就更加简单呐。

2.7 定位

grid-column-startgrid-column-endgrid-row-startgrid-row-endgrid-columngrid-row 这一组就很直接了,start和end,开始和结束,又是应用在格子上面,那就很“make sense”了,意思就是格子开始和结束的位置,接着其值是数字,如果我们这样描述一个格子:格子从第1个*开始,到第3个*结束。那盒子容器里面有什么能够作为*的代表呢?不就是网格线么?至于主轴和副轴还有简写就无须赘述啦~

再上代码

.grid-container {
    display: grid;
    grid-template-rows: 25% 25% 25%;
    grid-template-columns: 25% 25% 25%; 
    grid-auto-rows: 25%;
}
.item1 {
    grid-column-start:1;   
    grid-column-end:3;
}
.item2 {
    grid-column-start:1;   
    grid-column-end:3;
}

效果

start-end

2.8 特立独行

justify-selfalign-selfplace-self。这是格子的最后一组属性啦。self单词意思大家都懂:自己。首先自己是单数的,其次,自己-自己说了算。前面我们提到的容器盒子align-items,他就是对格子发出拉伸收缩的指令,且带“s”,对一群格子施令。而总有那么一两个不听,想自己说了算。至于主轴和副轴还有简写就无须赘述啦!

看代码

.grid-container {
    display: grid;
    grid-template-rows: 25% 25% 25%;
    grid-template-columns: 25% 25% 25%; 
    justify-items: center;
}
.item5 {
    justify-self: start;
}

效果

self

到这里,格子上单独自己设置的属性就没啦,也就两组:第一组就是给格子定位的start 和end,以网格线为参照;第二组就是特立独行的self。So easy, right ?


3. 父子CP

还有最后一组,这一组与上面的不同,不是单独设置就能生效的,要容器盒子和格子配合才有效果。但是,简单得有点尴尬。CP(组合使用)grid-template-areas(父)、grid-area(子)。打个比方:诸侯分封,土地各自属于哪个诸侯。 上代码

    <div class="container">
        <h1>Grid Layout</h1>
        <div class="grid-container">
            <div class="item1">item1</div>
            <div class="item2">item2</div>
            <div class="item3">item3</div>
            <div class="item4">item4</div>
        </div>
    </div>
.grid-container {
    display: grid;
    grid-template-rows: 25% 25% 25%;
    grid-template-columns: 25% 25% 25%; 
    grid-template-areas: 
      "item1 item1 item2"
      "item3 item3 item2"
      "item4 item4 item4";
}
.item1 {
    grid-area: item1
}
.item2 {
    grid-area: item2
}
.item3 {
    grid-area: item3
}
.item4 {
    grid-area: item4
}

效果图

area

结语

其实我前面一直强调简单,原因有三:其一,网格布局各个属性的设置很全面也很好理解,“难”的只是多和杂;其二,我只有强调简单才能减少你阅读时的枯燥和增加你的自信;其三,本文是对参考博文的的总结,具体的细节还需要你用心去实践和体会,毕竟修行靠个人。

参考文献

1. CSS Grid 网格布局教程,阮一峰

(条理清晰,简单易懂)

2. 写给自己看的display: grid布局教程,张鑫旭

(深入分析,互动性强)