Flex快速上手
容器的属性和常用值
容器可以通过设置
display
属性为flex
/ inline-flex
(行内 flex)来指定其为 flex 布局。下面,将记录一下容器的属性和常用值,基本可以囊括大多数应用场景。
属性
含义
值
常用值
水平对齐方向
flex-start(默认)、flex-end、center、space-between、space-around
center(水平居中)/ space-around(等间距布局)
项目的属性和常用值
首先来看下项目元素上常用的 2 个属性,
order
和flex-grow
:其中,
order
很好理解,下面通过一个例子来展示flex-grow
属性的妙用:<html> <head> <style> div { display: flex; } span:nth-child(1) { flex-grow: 1; } </style> </head> <body> <div> <span>1</span> <span>2</span> <span>3</span> </div> </body> </html>
可以在浏览器中看到,第一个
<span>
标签由于设置了flex-grow: 1
,它自动占据了父容器除了剩下两个<span>
标签外的所有空间!Flex缩放研究
经常会看到
flex: 1 1
的写法,其实它是缩写:flex-grow: 1; flex-shrink: 1; flex-basis: 0%;
flex-grow:放大比例
默认为 0,即有多余空间的时候,项目不放大。
如果所有项目均 flex-grow 为 1,那么会自动等分多余空间;如果有个 2,也按照比例等分。
flex-shrink:缩小比例
默认为 1,如果空间不够,项目自动缩小。
如果一个项目为 0,其他为 1,那么空间不足,为 0 的项目不缩小。
flex-basis:项目主轴空间
默认值是
auto
。定义的是未缩放前,项目所占主轴空间。可以指定百分比、
auto
、pxFlex常见应用场景
场景 ①:水平垂直居中
以上面的
html
结构为例,如果要让<div>
中的元素水平垂直居中,只需要以下样式代码:div { display: flex; justify-content: center; align-items: center; }
场景 ②:左右两侧布局,其中一侧宽度确定;另一侧宽度占满剩余空间,并且自动响应
我们要做的就是将自动响应的那一侧的元素的
flex-grow
属性设置为 1 即可。场景 ③:栅栏布局系统
还是以上面的
html
结构为例,实现一个将屏幕等分为 12 列,3 个<span>
标签分别占据屏幕宽度的:1/6、1/6 和 2/3。span:nth-child(1) { flex: 2; } span:nth-child(2) { flex: 2; } span:nth-child(3) { flex: 8; }
和原来相比,
flex
实现的栅栏布局优点有两个:- 不再局限于 12 列
- 不再需要计算宽度,也不需考虑宽度浮点数带来的误差
经常会看到
flex: 1 1
的写法,其实它是缩写:flex-grow: 1; flex-shrink: 1; flex-basis: 0%;
Flex的坑
在实现水平垂直居中的过程中,发现了
flex
布局仅仅影响容器的一级子元素。例如下面这段代码:<html> <head> <style> .level1 { display: flex; align-items: center; justify-content: center; } </style> </head> <body> <div class="level1"> <div class="level2"> <span>1</span> <span>2</span> <span>3</span> </div> </div> </body> </html>
level2 类就不是水平垂直居中的,因为水平垂直居中仅仅影响到了
level2
,而不会进一步向下”污染“更深级别的子元素的布局样式。如果要让 level2 也实现水平垂直居中,我们可以专门封装一个用于水平垂直居中的类,代码如下:
<html> <head> <style> .center { display: flex; align-items: center; justify-content: center; } </style> </head> <body> <div class="level1 center"> <div class="level2 center"> <span>1</span> <span>2</span> <span>3</span> </div> </div> </body> </html>