Web/02-CSS基础/13-CSS3属性:Flex布局图文详解.md

634 lines
15 KiB
Markdown
Raw Normal View History

---
title: 13-CSS3属性Flex布局图文详解
publish: true
---
<ArticleTopAd></ArticleTopAd>
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
## 前言
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
CSS3中的 flex 属性,在布局方面做了非常大的改进,使得我们对**多个元素之间**的布局排列变得十分灵活,适应性非常强。其强大的伸缩性和自适应性,在网页开中可以发挥极大的作用。
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
### flex 初体验
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
我们先来看看下面这个最简单的布局:
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
![](http://img.smyhvae.com/20191009_1555.png)
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
上面这张图中的布局是我们都熟悉的:默认文档流中,在一个父容器里放置多个块级的子元素,那么,这些子元素会默认从上往下排列。
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
在此基础之上,如果我给父容器仅仅加一个 `display: flex`属性,此时,这些子元素的布局会摇身一变:
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
![](http://img.smyhvae.com/20191009_1600.png)
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
没错,子元素们会**在水平方向上,从左至右排列**,就是这么神奇。到此为止,你已经掌握了关于 flex 的一半的知识。
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
### flex 布局的优势
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
1、**flex 布局的子元素不会脱离文档流**,很好地遵从了“流的特性”。
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
但你如果用 float 来做布局float 属性的元素会脱离文档流,而且会涉及到各种 BFC、清除浮动的问题。浮动相关的问题比较麻烦所以也成了面试必问的经典题目。但有了 flex 布局之后,这些问题都不存在的。
2018-02-23 12:23:47 +08:00
2、**flex 是一种现代的布局方式,是 W3C 第一次提供真正用于布局的 CSS 规范**。 flex 提供了非常丰富的属性,非常灵活,让布局的实现更佳多样化,且方便易用。
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
flex 唯一的缺点就在于,它不支持低版本的 IE 浏览器。
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
### flex 的兼容性问题
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
![](http://img.smyhvae.com/20191005_1200.png)
2018-02-23 12:23:47 +08:00
2019-10-13 14:05:52 +08:00
上图中可以看到, flex 布局不支持 IE9 及以下的版本IE10及以上也只是部分支持。如果你的页面不需要处理 IE浏览器的兼容性问题则可以放心大胆地使用 flex 布局。
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
但是,比如网易新闻、淘宝这样的大型网站,面对的是海量用户,即便使用低版本浏览器的用户比例很少,但绝对基数仍然是很庞大的。因此,这些网站为了兼容低版本的 IE 浏览器,暂时还不敢尝试使用 flex 布局。
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
### 概念:弹性盒子、子元素
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
在讲 flex 的知识点之前,我们事先约定两个概念:
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
- **弹性盒子**:指的是使用 `display:flex``display:inline-flex` 声明的**父容器**。
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
- **子元素/弹性元素**:指的是父容器里面的子元素们(父容器被声明为 flex 盒子的情况下)。
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
### 概念:主轴和侧轴
在上面的“初体验”例子中,我们发现,弹性盒子里面的子元素们,默认是从左至右排列的,这个方向,代表的就是主轴的方向。
在此,我们引入主轴和侧轴的概念。
![](http://img.smyhvae.com/20191009_1701.png)
如上图所示:
- 主轴flex容器的主轴默认是水平方向从左向右。
- 侧轴:与主轴垂直的轴称作侧轴,默认是垂直方向,从上往下。
PS主轴和侧轴并不是固定不变的可以通过 `flex-direction` 更换方向,我们在后面会讲到。
## 弹性盒子
### 声明定义
使用 `display:flex``display:inline-flex` 声明一个**父容器**为弹性盒子。此时,这个父容器里的子元素们,会遵循弹性布局。
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
备注:一般是用 `display:flex`这个属性。`display:inline-flex`用得较少。
2018-02-23 12:23:47 +08:00
2019-10-08 17:30:30 +08:00
### flex-direction 属性
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
`flex-direction`:用于设置盒子中**子元素**的排列方向。属性值可以是:
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
| 属性值 | 描述 |
|:-------------|:-------------|
| row | 从左到右水平排列子元素(默认值) |
|column|从上到下垂直排列子元素|
| row-reverse |从右向左排列子元素 |
|column-reverse|从下到上垂直排列子元素|
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
备注:如果我们不给父容器写`flex-direction`这个属性,那么,子元素默认就是从左到右排列的。
2018-02-23 12:23:47 +08:00
代码演示:
```html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}
body{
background-color: #eee;
font-family: "Microsoft Yahei";
font-size:22px;
}
h3{
font-weight: normal;
}
section{
width: 1000px;
margin:40px auto;
}
ul{
background-color: #fff;
border: 1px solid #ccc;
}
ul li{
width: 200px;
height: 200px;
background-color: pink;
margin:10px;
}
section:nth-child(1) ul{
overflow: hidden; /* 清除浮动 */
}
section:nth-child(1) ul li{
float: left;
}
/* 设置伸缩盒子*/
section:nth-child(2) ul{
display: flex;
}
section:nth-child(3) ul{
/* 设置伸缩布局*/
display: flex;
/* 设置主轴方向*/
flex-direction: row;
}
section:nth-child(4) ul{
/* 设置伸缩布局*/
display: flex;
/* 设置主轴方向 :水平翻转*/
flex-direction: row-reverse;
}
section:nth-child(5) ul{
/* 设置伸缩布局*/
display: flex;
/* 设置主轴方向 :垂直*/
flex-direction: column;
}
section:nth-child(6) ul{
/* 设置伸缩布局*/
display: flex;
/* 设置主轴方向 :垂直*/
flex-direction: column-reverse;
}
</style>
</head>
<body>
<section>
<h3>传统布局</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>伸缩布局 display:flex</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>主轴方向 flex-direction:row</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>主轴方向 flex-direction:row-reverse</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>主轴方向 flex-direction:column</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>主轴方向 flex-direction:column-reverse</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
</body>
</html>
```
2019-10-08 17:30:30 +08:00
### flex-wrap 属性
2018-02-23 12:23:47 +08:00
2019-10-08 17:30:30 +08:00
`flex-wrap`:控制子元素溢出时的换行处理。
2019-10-08 17:26:18 +08:00
2019-10-08 17:30:30 +08:00
### justify-content 属性
`justify-content`:控制子元素在主轴上的排列方式。
2019-10-08 17:26:18 +08:00
## 弹性元素
### justify-content 属性
2018-02-23 12:23:47 +08:00
- `justify-content: flex-start;` 设置子元素在**主轴上的对齐方式**。属性值可以是:
- `flex-start` 从主轴的起点对齐(默认值)
- `flex-end` 从主轴的终点对齐
- `center` 居中对齐
- `space-around` 在父盒子里平分
- `space-between` 两端对齐 平分
2019-10-08 17:26:18 +08:00
代码演示:(在浏览器中打开看效果)
2018-02-23 12:23:47 +08:00
```html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
list-style:none;}
body{
background-color: #eee;
font-family: "Microsoft Yahei";
}
section{
width: 1000px;
margin:50px auto;
}
section h3{
font-size:22px;
font-weight: normal;
}
ul{
border: 1px solid #999;
background-color: #fff;
display: flex;
}
ul li{
width: 200px;
height: 200px;
background: pink;
margin:10px;
}
section:nth-child(1) ul{
/* 主轴对齐方式:从主轴开始的方向对齐*/
justify-content: flex-start;
}
section:nth-child(2) ul{
/* 主轴对齐方式:从主轴结束的方向对齐*/
justify-content: flex-end;
}
section:nth-child(3) ul{
/* 主轴对齐方式:居中对齐*/
justify-content: center;
}
section:nth-child(4) ul{
/* 主轴对齐方式:在父盒子中平分*/
justify-content: space-around;
}
section:nth-child(5) ul{
/* 主轴对齐方式:两端对齐 平分*/
justify-content: space-between;
}
</style>
</head>
<body>
<section>
<h3>主轴的对齐方式justify-content:flex-start</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>主轴的对齐方式justify-content:flex-end</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>主轴的对齐方式justify-content:center</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>主轴的对齐方式justify-content:space-round</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>主轴的对齐方式justify-content:space-bettwen</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</section>
</body>
</html>
```
2019-10-08 17:30:30 +08:00
### align-items 属性
2018-02-23 12:23:47 +08:00
2019-10-08 17:30:30 +08:00
`align-items`:设置子元素在**侧轴上的对齐方式**。属性值可以是:
2018-02-23 12:23:47 +08:00
- `flex-start` 从侧轴开始的方向对齐
- `flex-end` 从侧轴结束的方向对齐
- `baseline` 基线 默认同flex-start
2018-03-13 23:12:27 +08:00
- `center` 中间对齐
2018-02-23 12:23:47 +08:00
- `stretch` 拉伸
代码演示:
```html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
list-style:none;
}
body{
background-color: #eee;
font-family: "Microsoft Yahei";
}
section{
width: 1000px;
margin:50px auto;
}
section h3{
font-size:22px;
font-weight: normal;
}
ul{
border: 1px solid #999;
background-color: #fff;
display: flex;
height:500px;
}
ul li{
width: 200px;
height: 200px;
background: pink;
margin:10px;
}
section:nth-child(1) ul{
/* 侧轴对齐方式 :从侧轴开始的方向对齐*/
align-items:flex-start;
}
section:nth-child(2) ul{
/* 侧轴对齐方式 :从侧轴结束的方向对齐*/
align-items:flex-end;
}
section:nth-child(3) ul{
/* 侧轴对齐方式 :居中*/
align-items:center;
}
section:nth-child(4) ul{
/* 侧轴对齐方式 :基线 默认同flex-start*/
align-items:baseline;
}
section:nth-child(5) ul{
/* 侧轴对齐方式 :拉伸*/
align-items:stretch;
}
section:nth-child(5) ul li{
height:auto;
}
</style>
</head>
<body>
<section>
<h3>侧轴的对齐方式:align-items flex-start</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>侧轴的对齐方式align-items:flex-end</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>侧轴的对齐方式align-items:center</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>侧轴的对齐方式align-itmes:baseline</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>侧轴的对齐方式align-itmes: stretch</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
</body>
</html>
```
2019-10-08 17:26:18 +08:00
### `flex`属性:设置子盒子的权重
2018-02-23 12:23:47 +08:00
代码演示:
```html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
list-style:none;
}
body{
background-color: #eee;
font-family: "Microsoft Yahei";
}
section{
width: 1000px;
margin:50px auto;
}
section h3{
font-size:22px;
font-weight: normal;
}
ul{
border: 1px solid #999;
background-color: #fff;
display: flex;
}
ul li{
width: 200px;
height: 200px;
background: pink;
margin:10px;
}
section:nth-child(1) ul li:nth-child(1){
flex:1;
}
section:nth-child(1) ul li:nth-child(2){
flex:1;
}
section:nth-child(1) ul li:nth-child(3){
flex:8;
}
section:nth-child(2) ul li:nth-child(1){
}
section:nth-child(2) ul li:nth-child(2){
flex:1;
}
section:nth-child(2) ul li:nth-child(3){
flex:4;
}
</style>
</head>
<body>
<section>
<h3>伸缩比例:flex</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
<section>
<h3>伸缩比例:flex</h3>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</section>
</body>
</html>
```
2019-10-08 17:26:18 +08:00
## 相关链接
### CSS Flexbox 可视化手册
2019-08-21 21:09:21 +08:00
2019-08-21 21:27:39 +08:00
可视化的截图如下:(请点开链接,查看大图)
2019-08-21 21:09:21 +08:00
2019-08-21 21:27:39 +08:00
<http://img.smyhvae.com/20190821_2101.png>
2019-08-21 21:09:21 +08:00
相关文章:
- 【英文原版】 CSS Flexbox Fundamentals Visual Guide<https://medium.com/swlh/css-flexbox-fundamentals-visual-guide-1c467f480dac>
- 【中文翻译】CSS Flexbox 可视化手册:<https://zhuanlan.zhihu.com/p/56046851>
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
### flex 相关的推荐文章
2018-02-23 12:23:47 +08:00
2019-08-21 21:09:21 +08:00
- flex 效果在线演示:<https://demos.scotch.io/visual-guide-to-css3-flexbox-flexbox-playground/demos/>
2018-02-23 12:23:47 +08:00
2019-08-21 21:09:21 +08:00
- A Complete Guide to Flexbox | 英文原版:<https://css-tricks.com/snippets/css/a-guide-to-flexbox/>
2018-02-23 12:23:47 +08:00
2019-08-21 21:09:21 +08:00
- CSS3 Flexbox 布局完全指南 | 中文翻译:<https://www.html.cn/archives/8629>
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
### flex 相关的教程
2018-02-23 12:23:47 +08:00
2019-10-08 17:30:30 +08:00
- [后盾人 flex 教程](http://houdunren.gitee.io/note/css/10%20%E5%BC%B9%E6%80%A7%E5%B8%83%E5%B1%80.html)
2018-02-23 12:23:47 +08:00
2019-10-08 17:26:18 +08:00
## 技巧:使用 margin 自动撑满剩余空间
2018-02-23 12:23:47 +08:00