前言
flex
已经强大到足够实现很多种布局方案了,为什么又出来一个新的布局方案grid
呢?
一个新的技术的出现必然是为了解决现有技术的不足之处的。
与flex的一纬布局不同,grid布局是一个二维布局系统,也就意味着它可以同时处理列和行。
通过一个示例来窥探grid的神奇之处
实现这样一个经典布局
grid有着更加语义化的属性,可以让我们像搭积木一样进行的网页布局。
grid的还有一个特性就是grid可以让我们的布局与html语义结构解耦出来,不用根据html所定义的结构顺序来渲染。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| body { font-weight: 900; color: #ffffff; }
.wrapper { width: 100vw; height: 100vh; display: grid; grid-template-columns: 200px auto; grid-template-rows: 60px auto 60px; grid-template-areas: "header header header" "menu content content" "footer footer footer"; }
.header, .footer { background: #5b5b8e; }
.header { grid-area: header; }
.footer { grid-area: footer; }
.menu { background: #66cc99; grid-area: menu; }
.content { background: #f9cc6e; grid-area: content; }
<div class="wrapper"> <div class="header">HEADER</div> <div class="menu">MENU</div> <div class="content">CONTENT</div> <div class="footer">FOOTER</div> </div>
|
点此看demo
grid的一些属性
grid布局相关的属性以及值远比flex多,需要好好的厘清一下。
display:grid 和 inline-grid
给父元素加上grid或者inline-grid属性即可创建一个网格容器。
一个是块级一个是行内元素,一张图就能明白。
grid-template-columns 和 grid-template-rows
同样是应用在父级的属性,grid-template-columns设置列宽,grid-template-rows设置行高,这两个属性在grid布局中尤为重要
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| .wrapper { display: grid; grid-template-columns: 200px 200px 200px; grid-gap: 5px; grid-template-rows: 50px; }
<div class="wrapper"> <div class="item one">1</div> <div class="item two">2</div> <div class="item three">3</div> </div>
|
repeat函数
三列的话200px要写三次,如果更多呢?
我们可以使用repeat() 函数简化重复的值,该函数接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值。
1 2
| // 上面的css可以简写为 grid-template-columns: repeat(3, 200px);
|
auto-fill关键字
auto-fill:表示自动填充,让一行(或者一列)中尽可能的容纳更多的单元格。grid-template-columns: repeat(auto-fill, 200px) 表示列宽是 200 px,但列的数量是不固定的,只要浏览器能够容纳得下,就可以放置元素,代码以及效果如下图所示:
1 2 3 4 5 6 7
| .wrapper { display: grid; grid-template-columns: repeat(auto-fill, 200px); grid-gap: 5px; grid-auto-rows: 50px; }
|
fr关键字
grid中的长度单位,和vw,vh类似,1fr单位代表网格容器中可用空间的一等份。
1 2 3 4 5 6 7 8 9 10 11 12 13
| .wrapper { display: grid; grid-template-columns: 200px 1fr 2fr; grid-gap: 5px; grid-template-rows: 50px; }
<div class="wrapper"> <div class="item one">1</div> <div class="item two">2</div> <div class="item three">3</div> </div>
|
minmax()函数
minmax()函数包含两个参数,最小值 和 最大值,表示长度就在这个范围之中都可以应用到网格项目中。概念有点晦涩难懂蛤,那就直接上代码。
1 2 3 4 5 6 7
| .wrapper { display: grid; // 第三个列宽最少也是要200px,但是最大不能大于第一第二列宽的两倍 grid-template-columns: 1fr 1fr minmax(200px, 2fr); grid-gap: 5px; grid-template-rows: 50px; }
|
auto 关键字
和flex:1
一样的效果,由浏览器决定长度。
1 2 3 4 5 6
| .wrapper { display: grid; // 表示第一第三列为200px,中间由浏览器决定长度 grid-template-columns: 200px auto 200px; grid-template-rows: 50px; }
|
grid-row-gap 属性、grid-column-gap 属性以及 grid-gap 属性
grid-row-gap
属性、grid-column-gap
属性分别设置行间距和列间距。grid-gap
属性是两者的简写形式。
1 2 3 4 5
| grid-row-gap: 10px; grid-column-gap: 20px;
grid-gap: 10px 20px;
|
grid-template-areas 属性
一个布局样式,grid-template-areas
属性用于定义区域,一个区域由一个或者多个单元格组成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #page { display: grid; width: 100%; height: 100%; grid-template-areas: "head head" "nav main" "nav foot"; grid-template-rows: 50px 1fr 30px; grid-template-columns: 150px 1fr; } #page>header { grid-area: head; background-color: #8ca0ff; }
#page>nav { grid-area: nav; background-color: #ffa08c; }
#page>main { grid-area: main; background-color: #ffff64; }
#page>footer { grid-area: foot; background-color: #8cffa0; } <section id="page"> <header>Header</header> <nav>Navigation</nav> <main>Main area</main> <footer>Footer</footer> </section>
|
演示地址
grid-auto-flow 属性
grid-auto-flow
属性控制着自动布局算法怎样运作,精确指定在网格中被自动布局的元素怎样排列。默认的放置顺序是”先行后列”,即先填满第一行,再开始放入第二行。
理解起来复杂,直接戳这边看演示demo
justify-items 属性、align-items 属性以及 place-items 属性
justify-items
属性设置单元格内容的水平位置(左中右),align-items
属性设置单元格的垂直位置(上中下),place-items
是align-items和justify-items的简写属性。
同样戳这边看演示demo
justify-content 属性、align-content 属性以及 place-content 属性
*-content
属性是整个内容区域在容器里面的位置,效果同flex不再过多介绍。
grid-auto-columns 属性和 grid-auto-rows 属性
grid-auto-columns
和grid-auto-rows
是作用于隐式网格的两个属性。
先来看看隐式和显式网格的概念,显式网格包含了你在 grid-template-columns 和 grid-template-rows 属性中定义的行和列。如果你在网格定义之外又放了一些东西,或者因为内容的数量而需要的更多网格轨道的时候,网格将会在隐式网格中创建行和列。
如果不给隐式网格设置grid-auto-columns
和grid-auto-rows
属性,则浏览器会根据单元格内容的大小,自行决定网格的列宽和行高
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| .wrapper { display: grid; grid-template-columns: 100px 100px; grid-template-rows: 100px 100px; grid-gap: 50px; grid-auto-columns: 50px; grid-auto-rows: 50px; }
<div class="wrapper"> <div class="item one">1</div> <div class="item two">2</div> <div class="item three">3</div> <div class="item four">3</div> <div class="item five">3</div> <div class="item six">3</div> </div>
|
grid子元素的一些属性
grid-column-start、grid-column-end、grid-row-start 以及grid-row-end
可以指定网格项目所在的四个边框,分别定位在哪根网格线,从而指定项目的位置
- grid-column-start 属性:左边框所在的垂直网格线
- grid-column-end 属性:右边框所在的垂直网格线
- grid-row-start 属性:上边框所在的水平网格线
- grid-row-end 属性:下边框所在的水平网格线
上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| .wrapper { display: grid; grid-template-columns: repeat(3, 100px); grid-template-rows: repeat(3, 100px); background-color: #cccccc; }
.two { grid-column-start: 2; grid-column-end: 4; // 上面两个属性可以写为grid-column-start: span 2; 或者 grid-column-end: span 2; }
<div class="wrapper"> <div class="item one">1</div> <div class="item two">2</div> <div class="item three">3</div> <div class="item four">4</div> <div class="item five">5</div> </div>
|
grid-column-start的一个demo
1 2 3 4 5 6 7 8 9 10
| .three { grid-column-start: 1; grid-column-end: 3; }
<div class="wrapper"> <div class="item one">1</div> <div class="item two">2</div> <div class="item three">3</div> </div>
|
grid-row-start的一个demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| .wrapper { display: grid; grid-template-columns: repeat(2, 100px); grid-template-rows: repeat(2, 100px); background-color: #cccccc; margin-left: 100px; }
.one { grid-row-start: 1; grid-row-end: 3; // 上面两个属性同样可以简写为grid-row-start: span 2;或者grid-row-end: span 2; }
<div class="wrapper"> <div class="item one">1</div> <div class="item two">2</div> <div class="item three">3</div> </div>
|
justify-self 、align-self 以及 place-self
justify-self
属性设置单元格内容的水平位置(左中右),跟 justify-items 属性的用法完全一致,但只作用于单个项目
align-self
属性设置单元格内容的垂直位置(上中下),跟align-items属性的用法完全一致,也是只作用于单个项目
place-self
则是align-self
和justify-self
的简写
点此处看演示demo
参考资料
最强大的 CSS 布局 —— Grid 布局
CSS Grid 网格布局教程