CSS中布局是很重要的一部分,从一个元素块的水平居中、垂直居中或者水平垂直居中,再到整个页面的常规布局、圣杯布局、双飞翼布局等等。这些布局有的只需要CSS比较常规写法就可以完成,不过有的还是需要一些特殊技巧的。但是Flex和Grid的出现,让页面布局变的简单而且灵活。
Flex
属性介绍
Flex相关的CSS属性可以分为两大类:Flex容器属性和Flex子项属性
Flex容器指设置了display: flex
的元素。Flex子项指Flex容器的子元素。
建议配合Playround来了解各个属性
Flex容器属性
属性涉及到的有:主轴方向、换行、主轴侧轴对齐,多行对齐。(主轴侧轴可以简单理解为行列,但不是对应的,主轴也可以是列)
-
display
将元素定义为flex布局 取值:flex | inline-flex -
flex-direction
用于指定Flex主轴的方向,继而决定 Flex子项在Flex容器中的位置
取值:row | row-reverse | column | column-reverse -
flex-wrap
用于指定Flex子项是否换行
取值:nowrap | wrap | wrap-reverse -
flex-flow
复合属性,是flex-direction 和 flex-wrap 的简写属性,是用于指定Flex子项的排列方式 -
justify-content
用于指定主轴上Flex子项的对齐方式 取值:flex-start | flex-end | center | space-between | space-around -
align-items
用于指定侧轴(垂直方向)上Flex子项的对齐方式
取值:stretch | flex-start | flex-end | center | baseline -
align-content
该属性只作用于多行的情况下,用于多行的对齐方式
取值:stretch | flex-start | flex-end | center | space-between | space-around
Flex容器的子元素
属性涉及到:排列顺序、空间分配、对齐
-
order
该属性用来指定Flex子项的排列顺序,数值越小,越靠前,可以为负数
取值:数值,默认值为0 -
flex-grow
用来指定Flex子项的扩展比例,不可以为负数,Flex容器会根据Flex子项设置的扩展比例作为比率来分配剩余空间
取值:数值,默认值为0,表示即使存在剩余空间,Flex子项也不会扩展 -
flex-shrink
用来指定Flex子项的收缩比例,不可以为负数,Flex容器会根据Flex子项设置的收缩比例作为比率来收缩各个Flex子项
取值:数值,默认值为1,表示所有子项在剩余空间为负数时,等比例收缩 -
flex-basis 用来指定Flex子项的占据的空间,不可以为负数 取值:auto | length | percentage | content
-
flex
复合属性,是flex-grow 、 flex-shrink 和 flex-basis 的简写属性,用来指定Flex子项如何分配空间
取值:none | 各拆分项属性- none:0 0 auto
- auto:1 1 auto
- 1:1 1 0%
- 0 auto 或 initial:0 1 auto 即初始值
-
align-self
用来单独指定某Flex子项的对齐方式
取值:auto | flex-start | flex-end | center | baseline | stretch
实例
垂直居中
垂直居中的写法有很多,用flex也可以实现
.parent {
display: flex;
width: 200px;
height: 200px;
border: 1px solid #ccc;
}
.child {
width: 50px;
height: 50px;
margin: auto; /* 关键点 */
background-color: #FF9800;
}
复制代码
制作Header
制作一个如下图的Header,常规方法可能是左边一个nav,右边的按钮使用float来居右。现在可以思考下用flex怎么实现。
<style>
.header {
display: flex;
width: 520px;
height: 36px;
line-height: 36px;
color: white;
background-color: #03A9F4;
border: 1px solid #ccc;
}
.header div {
padding: 0 10px
}
.header div:last-child {
margin-left: auto
}
</style>
<header class="header">
<div>Home</div>
<div>Search</div>
<div>Logout</div>
</header>
复制代码
实现:header元素设置display: flex
, header的子元素会沿着主轴方法排列,最后一个元素设置margin-left: auto
来居右。
制作评价栏
制作一个评价栏,左右两个都是宽度都是自适应的,中间输入框的宽度随着两边而变化。常规做法的话可能需要js来配合完成。使用flex的话可以轻松完成这个布局。
<style>
.flex .bottom-bar {
display: flex;
width: 520px;
height: 32px;
line-height: 32px;
padding: 6px 10px;
border: 1px solid #ccc;
margin-bottom: 10px
}
.flex .bottom-bar__description {
padding: 0 8px;
}
.flex .bottom-bar__input {
flex: 1
}
.flex .bottom-bar__input input{
width: 100%
}
.flex .bottom-bar__praise {
padding: 0 8px;
}
</style>
<div class="bottom-bar">
<div class="bottom-bar__description">你的评价</div>
<div class="bottom-bar__input">
<input type="text">
</div>
<div class="bottom-bar__praise">
<button class="praise__thumb-up">点赞</button>
<button class="praise__flower">送花</button>
</div>
</div>
复制代码
实现:把bottom-bar
设置为flex布局,然后其他正常布局,在空间分配方面,输入框占用所有的剩余空间,左右两边自适应即可。
Grid
相关概念
同样的Grid相关的CSS属性可以分为两大类:Grid容器属性和Grid子项属性
Grid容器指设置了display: grid
的元素。Grid子项指Grid容器的子元素。
除了上面两个概念,还要介绍一些其他相关术语。
- 网格线:用于分割行列的水平或者垂直的线
- 网格单元:网格系统的一个单元
- 网格区域: 四条网格线围成的一个区域,包含多个网格单元
- 网格轨道:两条网格形成的一个区域
-
网格行:网格系统中一行
-
网格列:网格系统中一列
-
网格间隙:行或者列之间的空隙
属性介绍
Grid属性比较多,这边粗略介绍下属性大体作用,要具体了解可以看这篇文章
Grid容器
Grid容器属性主要这几个方面:定义行、列、区域,定义网格线大小、网格项内容的对齐,网格容器对齐、隐式网格
Grid项
Grid项主要有这几个方面:定义占据的网格空间、对齐
实例
页面布局
对于下面这种页面布局,常规的的模式就划分出大模块,然后在细分模块布局。使用Grid布局会让这一切变得简单起来。
<style>
.grid-layout {
display: grid;
width: 800px;
height: 600px;;
grid-gap: 10px;
grid-template-columns: 1fr 5fr 2.5fr;
grid-template-rows: 1fr 5fr 1fr;
grid-template-areas:
"header header header"
"sidebar main aside"
"sidebar footer footer";
}
header, aside, .content, .content-aside, footer{
background: #ffbf66;
border: 2px solid #555
}
header {
grid-area: header
}
aside {
grid-area: sidebar
}
.content {
grid-area: main
}
.content-aside {
grid-area: aside
}
footer {
grid-area: footer
}
</style>
<div class="grid-layout">
<header></header>
<aside></aside>
<div class="content"></div>
<div class="content-aside"></div>
<footer></footer>
</div>
复制代码
实现:在Grid容器上定义行列数据,同时在对网格区域进行划分,最后只要子项设置为对应的区域即可。
Flex VS Grid
Flexbox 多用于一维布局, Grid 多用于二位布局
就如上述的例子,Flexbox适合用于布局Header这样的模块,而对于整个页面的布局来说,使用Grid更合适。
总结
Flex和Grid的出现,让页面布局变的简单而且灵活。但是实际项目还是要考虑兼容性问题。
最后推荐个游戏化学习的课堂:FLEXBOX FROGGY、Grid GARDEN