前言
Flex 这个布局前前后后看了3次,第一次学的时候,发现有十几个属性值没耐心看完就没往下学了,作罢。第二次去看的时候大概搞明了Flex每个属性的用法,可没过几天又全部忘光了。第三次了解 Flex,于是就有了这篇笔记。估计是全网最易懂的Flex布局的文章。
前端布局的传统解决方案是基于盒状模型,依赖 display + position + float 方式来实现,灵活性较差。Flex 布局可以通过简单的属性灵活实现复杂的响应式布局。
当你会了Flex布局后,几乎所有布局都可以通过Flex解决,作为一个后端程序员,用起来很爽。
Flex的基本概念
Flex 布局顾名思义弹性布局,意味着灵活。里面有两个概念,叫容器和轴。使用flex布局的元素称为容器(flex container),该容器里面所有的子元素称为项目(flex item)。
容器有两根轴,分为主轴(main axis)和交叉轴(cross asix)。默认情况下,主轴是水平方向的,交叉轴是垂直方向的。容器里面的项目默认沿着主轴方向排列。
Flex 属性分为两部分,一部分是作用在容器上的称为容器属性,另一部分是是作用于项目上的称为项目属性。
容器属性
1、display
.container {
display: flex | inline-flex;
}
要使用flex布局,首先必须设置容器的display属性为flex或inline-flex, 块元素使用flex, 内联元素就使用inline-flex。指定flex后,项目的float、clear属性都将失效。
来看个最简单的例子
<div class="container">
<div class="item">flex itemdiv>
<div class="item">flex itemdiv>
<div class="item">flex itemdiv>
div>
外面的div是容器,里面有3个flex item,只需要外面的div的display属性设置为flex,该容器就成了flex布局。三个项目会沿着主轴方向依次排列。
.container {
display: flex;
border: 1px black solid;
width: 500px;
}
.item {
width: 100px;
height: 100px;
background-color: paleturquoise;
margin: 20px;
}
下面就是flex布局的页面效果,3个项目沿着主轴水平排列在一行
2、flex-direction
flex-direction用于指定主轴的方向, 有四个值, 默认是row,水平方向。项目始终沿着主轴的方向排列,如果改变了flex-direction,项目的布局排列就会跟着发生变化。
flex-direction: row|row-reverse|column|column-reverse;
来分别看下4个值对应的效果是咋样吧
.container {
flex-direction: row;
}
row 表示主轴为水平方向,从左至右
.container {
flex-direction: row-reverse;
}
row-reverse: 主轴为水平方向,从右到左(和row是相反的)
.container {
flex-direction: column ;
}
column: 主轴为垂直方向,从上至下
.container {
flex-direction: column-reverse;
}
column-reverse 主轴为垂直方向,从下往上
3、flex-wrap
flex-wrap 用于确定项目元素是否换行展示, 当所有 item 在主轴(假设主轴为水平方向 flex-direction:row)的宽度之和超过容器的大小,可以用flex-wrap决定是否换行显示。
flex-wrap: no-wrap|wrap|wrap-reverse;
默认值为no-wrap,表示不换行,当项目的宽度超出时,会自动缩小item的宽度,确保他们都显示在一行。
我们将容器的宽度设置为200px, 三个item的宽度之和是300px,超过了容器的宽度
.container {
width: 200px;
flex-wrap: no-wrap;
}
wrap 就是换行显示,当子项目的宽度之和超出父容器宽度时,就会另起一行。
.container {
flex-wrap: wrap;
}
.container {
flex-wrap: wrap-reverse;
}
wrap-reverse 表示换行,方向与wrap相反,后面的元素在上面。
4、flex-flow
flex-flow 就是 flex-direction 与 flex-wrap 的缩写, 两个值可以用flex-flow 来表示
.container {
flex-flow: column wrap;
}
5、justify-content
justify-content 用于指定item在主轴对齐方式, item可沿着主轴开始方向(flex-start)对齐、结束方向(flex-end)对齐、居中对齐(center)、两端对齐(space-between)、两侧对齐(space-around)。
沿主轴开始方向对齐
.container {
justify-content: flex-start; //默认值
}
沿主轴结束方向对齐
.container {
justify-content: flex-end;
}
居中对齐
.container {
justify-content: center;
}
居中对齐后,最左侧和右侧两边流出的空间是相等的
.container {
justify-content: space-between;
}
两端对齐是指两两项目之间的间隔是相等的
.container {
justify-content: space-around;
}
两侧对齐是指单个项目左右两侧的间隔是相等的,所以项目边缘的空隙是两个项目之前间隔的一半
6、align-item
align-item 定义了项目在交叉轴方向的对齐方式,同样有沿轴的开始方向(flex-start)对齐,结束方向对齐(flex-end)对齐和居中对齐(center)baseline和stretch。
align-item:flex-start|flex-end|center|baseline|stretch
stretch 为默认值,如果项目没有设置高度或者高度为auto,那么项目的高度将被拉伸到占满整个容器的高度。前面的图因为给3个项目设置了相同的高度,所以stretch并不会生效。现在把项目的高度去掉,显式指定 align-items 为 stretch 。
.container {
align-items: stretch;
height: 200px;
}
.item {
width: 100px;
background-color: paleturquoise;
margin: 0 20px;
}
.container {
align-items: center;
justify-content: center;
}
当给项目设置主轴和交叉轴的对齐方式都是center时,那么项目就可以同时在水平和垂直方向居中了。flex-end 和 flex-start 就不介绍了,自己试验看下效果就行。
7、align-content
align-content 是指项目如果有多行时,在交叉轴的对齐方式
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
这些属性值在前面都出现过,意义是一样的。你可以通过设置不同的值来看效果
总结一下容器下的几个属性
容器总共7个属性,除了display就6个,flex-flow 是 flex-drection 和 flex-wrap 的组合, 所以最后其实你要记住的属性就5个。flex-drection 指定主轴和交叉轴。flex-wrap 用于项目超出父容器时是否要换行,justfiy-content 是主轴的对齐方式,align-items 和 align-content 是项目在交叉轴方向的对齐方式,align-content只在多行时才生效。
项目属性
flex item 项目也有5个属性
这5个属性是设置在项目中的属性, 当所有项目的宽度或高度之和在主轴或交叉轴方向还有很多
剩余空间
或者空间不足以装载这些子项目时,我们可以用这些属性通过拉伸或者压缩子项目来控制子项目,使之灵活实现弹性布局。
剩余空间
什么是剩余空间呢?假设容器的宽度是400px, A、B、C3个子项目的宽度都100px, 他们的内外边距都为0,那么容器主轴方向的剩余空间是400-300=100px。
这剩余出来的100px空间我们可以通过拉伸项目来填满。
<div class="container">
<div class="item a">
<p>Ap>
div>
<div class="item b">
<p>Bp>
div>
<div class="item c">
<p>Cp>
div>
div>
.container