第十章 css3FLEX 弹性盒模型
A.了解弹性
1.弹性盒模型你真的需要掌握
2.浏览器调试功能的使用
3.弹性布局与传统布局响应对比
Terms:display: flex,flex:1
html
<style>
* {
padding: 0;
margin: 0;
}
div.container {
display: flex;
height: 100vh;
justify-content: space-evenly;
}
div.container div {
border: solid 1px #ddd;
}
div.container div:nth-of-type(1) {
min-width: 80px;
background: #4e9166;
}
div.container div:nth-of-type(2) {
flex: 1;
background: #ddd;
}
</style>
<div class="container">
<div></div>
<div></div>
</div>
4.传统方式布局微信客户端界面
html
传统布局
<style>
* {
padding: 0;
margin: 0;
}
main,
footer {
border: solid 1px #ddd;
box-sizing: border-box;
}
main {
background: #ddd;
height: 100vh;
padding-bottom: 55px;
background-clip: content-box;
}
footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 50px;
}
footer div {
width: 33%;
float: left;
text-align: center;
line-height: 3em;
height: 100%;
background: linear-gradient(to bottom, #f3f3f3, #eee, #f3f3f3);
cursor: pointer;
}
footer div:nth-child(n + 2) {
border-left: solid 1px #ddd;
}
</style>
<body>
<main></main>
<footer>
<div>1</div>
<div>2</div>
<div>3</div>
</footer>
</body>
5.使用弹性盒模型布局微信客户端
html
<!-- 弹性布局 -->
<style>
* {
padding: 0;
margin: 0;
}
body {
display: flex;
flex-direction: column;
height: 100vh;
}
main {
border: solid 1px #ddd;
background: #ddd;
background-clip: content-box;
margin-bottom: 5px;
flex: 1;
}
footer {
flex: 0;
display: flex;
justify-content: space-evenly;
border-top: solid 1px #ddd;
min-height: 50px;
}
footer div {
flex: 1;
text-align: center;
line-height: 3em;
background: linear-gradient(to bottom, #f3f3f3, #eee, #f3f3f3);
cursor: pointer;
}
footer div:nth-child(n + 2) {
border-left: solid 1px #ddd;
}
</style>
<body>
<main></main>
<footer>
<div>1</div>
<div>2</div>
<div>3</div>
</footer>
</body>
B.弹性盒子
6.声明弹性盒子的几种方式
Terms:display:flex
- 容器盒子里面包含着容器元素,使用
display:flex
或display:inline-flex
声明为弹性盒子
html
<!-- 声明块级弹性盒子 -->
<style>
* {
padding: 0;
margin: 0;
}
article {
height: 150px;
margin-left: 100px;
margin-top: 100px;
outline: solid 5px silver;
display: flex;
padding: 20px;
}
article div {
outline: solid 5px blueviolet;
text-align: center;
font-size: 28px;
line-height: 5em;
width: 300px;
}
</style>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
html
<!-- 声明内联级弹性盒子 -->
<style>
...
article {
...
display: inline-flex;
...
}
...
</style>
7.改变弹性元素方向
Terms:flex-direction
- 用于控制盒子元素排列的方向。
值 | 描述 |
---|---|
row | 从左到右水平排列元素(默认值) |
row-reverse | 从右向左排列元素 |
column | 从上到下垂直排列元素 |
column-reverse | 从下到上垂直排列元素 |
html
<!-- row-reverse -->
<style>
* {
padding: 0;
margin: 0;
}
body {
margin: 100px;
font-size: 14px;
color: #555;
}
article {
width: 500px;
border: solid 5px silver;
display: flex;
box-sizing: border-box;
padding: 10px;
flex-direction: row-reverse;
}
article * {
border: solid 5px blueviolet;
padding: 10px;
margin: 10px;
}
</style>
<article>
<h4>hd</h4>
<span>hdcms.com</span>
<p>houdunren.com</p>
</article>
html
<!-- column-reverse -->
<style>
article {
flex-direction: column-reverse;
}
</style>
8.控制弹性元素溢出换行处理
Terms:flex-wrap:wrap
- flex-wrap 属性规定 flex 容器是单行或者多行,同时横轴的方向决定了新行堆叠的方向。
选项 | 说明 |
---|---|
nowrap | 元素不拆行或不拆列(默认值) |
wrap | 容器元素在必要的时候拆行或拆列。 |
wrap-reverse | 容器元素在必要的时候拆行或拆列,但是以相反的顺序 |
8.1 行元素换行
html
<style>
* {
padding: 0;
margin: 0;
outline: solid 1px silver;
padding: 10px;
margin: 10px;
}
head {
display: block;
}
body {
font-size: 14px;
color: #555;
}
article {
width: 500px;
border: solid 5px silver;
box-sizing: border-box;
padding: 10px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
article div {
border: solid 5px blueviolet;
padding: 30px 80px;
margin: 10px;
text-align: center;
font-size: 28px;
}
</style>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
8.2 水平排列反向换行
html
<style>
flex-direction: row;
flex-wrap: wrap-reverse;
</style>
8.3 垂直元素换行
html
<style>
flex-direction: column;
flex-wrap: wrap;
</style>
8.3 垂直元素反向换行
html
<style>
flex-direction: column;
flex-wrap: wrap-reverse;
</style>
9.统一设置元素排列方式与换行
Term:flex-flow
html
<style>
flex-flow: row-reverse wrap-reverse;
</style>
10.主轴与交叉轴详解
- 根据 row,column,reverse 来确定主轴,交叉轴的方向(x,y 轴,水平轴,垂直轴)
10.1 水平排列
- flex-flow: row wrap
- flex-flow: row-reverse wrap-reverse
10.2 垂直排列
- flex-flow: column wrap
11.主轴元素的多种排列方式
Terms:justify-content
- 用于控制元素在主轴上的排列方式,再次强调是主轴的排列方式。
选项 | 说明 |
---|---|
flex-start | 元素紧靠主轴起点 |
flex-end | 元素紧靠主轴终点 |
center | 元素从弹性容器中心开始 |
space-between | 第一个元素靠起点,最后一个元素靠终点,余下元素平均分配空间 |
space-around | 每个元素两侧的间隔相等。所以,元素之间的间隔比元素与容器的边距的间隔大一倍 |
space-evenly | 元素间距离平均分配 |
11.1 justify-content: flex-end
html
<style>
* {
padding: 0;
margin: 0;
padding: 10px;
margin: 10px;
}
body {
font-size: 14px;
color: #555;
}
article {
border: solid 5px silver;
box-sizing: border-box;
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
}
article div {
width: 80px;
border: solid 5px blueviolet;
text-align: center;
font-size: 28px;
}
</style>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
11.2 space-evenly
html
<style>
article {
border: solid 5px silver;
box-sizing: border-box;
display: flex;
flex-flow: row wrap;
justify-content: space-evenly;
}
</style>
11.3 垂直排列时对齐到主轴终点
html
<style>
article {
height: 400px;
border: solid 5px silver;
box-sizing: border-box;
display: flex;
flex-flow: column wrap;
justify-content: flex-end;
}
</style>
12.交叉轴元素的多种排列方式
Terms:align-items
- 元素在交叉轴上有行的概念,理解这个概念会对理解 align-items 与 align-content 有更好的帮助。
- align-item 是控制元素在行上的排列
- align-content 是控制行在交差轴上的排列
align-items
选项 说明 stretch 元素被拉伸以适应容器(默认值) center 元素位于容器的中心 flex-start 元素位于容器的交叉轴开头 flex-end 元素位于容器的交叉轴结尾
12.1 拉伸适应交叉轴
- 如果设置了 width | height | min-height | min-width | max-width | max-height ,将影响 stretch 的结果,因为 stretch 优先级你于宽高设置。
html
<style>
* {
padding: 0;
margin: 0;
padding: 10px;
margin: 5px;
}
head {
display: block;
}
body {
font-size: 14px;
color: #555;
}
article {
height: 200px;
border: solid 5px silver;
box-sizing: border-box;
display: flex;
flex-direction: row;
align-items: stretch;
}
article div {
width: 80px;
border: solid 5px blueviolet;
text-align: center;
font-size: 28px;
}
</style>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
12.2 对齐到交叉轴的顶部
html
<style>
flex-direction: row;
align-items: flex-start;
</style>
12.3 对齐到交叉轴底部
html
<style>
flex-direction: row;
align-items: flex-end;
</style>
12.4 对齐到交叉轴中心
html
<style>
flex-direction: row;
align-items: center;
</style>
12.5 纵向排列时交叉轴排列
html
<style>
* {
padding: 0;
margin: 0;
padding: 10px;
margin: 5px;
}
article {
height: 400px;
border: solid 5px silver;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
}
article div {
height: 50px;
min-width: 100px;
border: solid 5px blueviolet;
text-align: center;
font-size: 28px;
}
</style>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
13.多行元素在交叉轴的排列方式
Terms:align-content
- 只适用于多行显示的弹性容器,用于控制行(而不是元素)在交叉轴上的排列方式。
选项 | 说明 |
---|---|
stretch | 将空间平均分配给元素 |
flex-start | 元素紧靠主轴起点 |
flex-end | 元素紧靠主轴终点 |
center | 元素从弹性容器中心开始 |
space-between | 第一个元素靠起点,最后一个元素靠终点,余下元素平均分配空间 |
space-around | 每个元素两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍 |
space-evenly | 元素间距离平均分配 |
13.1 水平排列在交叉轴中居中排列
html
<style>
* {
padding: 0;
margin: 0;
padding: 10px;
margin: 5px;
}
article {
height: 500px;
border: solid 5px silver;
box-sizing: border-box;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-start;
align-content: center;
}
article div {
width: 90px;
border: solid 5px blueviolet;
text-align: center;
font-size: 28px;
}
</style>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
13.2 垂直排列时交叉轴的排列
html
<style>
* {
padding: 0;
margin: 0;
padding: 10px;
margin: 5px;
}
article {
height: 300px;
border: solid 5px silver;
box-sizing: border-box;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: flex-start;
align-content: center;
}
article div {
min-width: 50px;
min-height: 80px;
border: solid 5px blueviolet;
text-align: center;
font-size: 28px;
}
</style>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
C.弹性元素
14.弹性元素(单个)交叉轴控制
Terms:align-self
放在容器盒子中的元素即为容器元素。
- 不能使用 float 与 clear 规则
- 弹性元素均为块元素
- 绝对定位的弹性元素不参与弹性布局
align-self:用于控制单个元素在交叉轴上的排列方式,align-items 用于控制容器中所有元素的排列,而 align-self 用于控制一个弹性元素的交叉轴排列。
选项 | 说明 |
---|---|
stretch | 将空间平均分配给元素 |
flex-start | 元素紧靠主轴起点 |
flex-end | 元素紧靠主轴终点 |
center | 元素从弹性容器中心开始 |
html
<style>
* {
padding: 0;
margin: 0;
padding: 10px;
margin: 5px;
}
article {
height: 400px;
border: solid 5px silver;
box-sizing: border-box;
display: flex;
flex-direction: row;
align-items: center;
}
article div {
height: 50px;
min-width: 50px;
border: solid 5px blueviolet;
text-align: center;
font-size: 28px;
}
article div:nth-of-type(1) {
align-self: flex-start;
}
article div:nth-of-type(3) {
align-self: flex-end;
}
</style>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
15.元素可用空间分配
Terms:flex-grow
- 用于将弹性盒子的可用空间,分配给弹性元素。可以使用整数或小数声明。
- 下例中为三个 DIV 弹性元素设置了 1、3、6 ,即宽度分成 10 等份,第三个元素所占宽度为(宽度/(1+3+6)) X 6。
html
<style>
* {
padding: 0;
margin: 0;
}
body {
padding-left: 50px;
padding-top: 15px;
}
article {
border: solid 5px silver;
width: 550px;
height: 100px;
display: flex;
flex-direction: row;
}
article * {
flex-grow: 1;
width: 100px;
height: 100px;
background: blueviolet;
background-clip: content-box;
padding: 10px;
box-sizing: border-box;
font-size: 35px;
color: white;
}
</style>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
- 如果弹性元素设置了宽度,将把(弹性盒子-弹性元素宽度和)后按照
flex-grow
进行分配
html
<style>
* {
padding: 0;
margin: 0;
padding: 10px;
margin: 5px;
}
article {
width: 600px;
position: relative;
height: 200px;
border: solid 5px silver;
display: flex;
}
article div {
min-height: 80px;
border: solid 5px blueviolet;
text-align: center;
font-size: 28px;
}
article div:nth-of-type(1) {
width: 100px;
flex-grow: 1;
}
article div:nth-of-type(2) {
width: 100px;
flex-grow: 3;
}
article div:nth-of-type(3) {
width: 300px;
flex-grow: 6;
}
</style>
16.布局小米移动端页面结构(main 占完中间)
html
<style>
* {
padding: 0;
margin: 0;
}
body {
height: 100vh;
display: flex;
flex-direction: column;
justify-content: space-between;
}
header {
height: 60px;
background-color: blueviolet;
}
main {
flex-grow: 1;
background-color: #ccc;
}
footer {
height: 60px;
background-color: #383881;
}
</style>
<body>
<header></header>
<main></main>
<footer></footer>
</body>
17.元素动态缩小的处理技巧
Terms:flex-shrink
- 与 flex-grow 相反 flex-shrink 是在弹性盒子装不下元素时定义的缩小值。
- 下例在 600 宽的弹性盒子中放了 1000 宽的弹性元素。并为最后两个元素设置了缩放,最后一个元素的缩放比例为 500 -( ( (1000-600) / (100X1+400x3+500X6) ) x 3 ) X 500 = 220.9,计算公式说明如下:
- 缩小比例 = 不足的空间 / (元素 1 宽度 x 缩小比例) + (元素 2 宽度 x 缩小比例)
- 最终尺寸 = 元素三宽度 - (缩小比例 x 元素 3 的宽度) X 元素宽度
html
<style>
* {
padding: 0;
margin: 0;
}
body {
padding-left: 50px;
padding-top: 15px;
}
article {
border: solid 5px silver;
width: 400px;
height: 120px;
display: flex;
padding: 10px;
box-sizing: content-box;
}
article div:nth-child(1) {
flex-shrink: 0;
}
article div:nth-child(2) {
flex-shrink: 1;
}
article div:nth-child(3) {
flex-shrink: 3;
}
article * {
width: 200px;
height: 100px;
overflow: hidden;
background: blueviolet;
background-clip: content-box;
padding: 10px;
border: solid 1px blueviolet;
box-sizing: border-box;
font-size: 30px;
color: white;
}
</style>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
18.主轴的基准尺寸的定义
Terms:flex-basis
flex-basis 属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。
可以是长度单位,也可以是百分比。flex-basis 的优先级高于 width、height 属性。
优先级:flex-basis>max-height,min-height>height,width
html
<style>
* {
padding: 0;
margin: 0;
}
article {
width: 600px;
position: relative;
height: 150px;
margin-left: 100px;
margin-top: 100px;
outline: solid 5px silver;
display: flex;
padding: 20px;
}
article div {
outline: solid 5px blueviolet;
text-align: center;
font-size: 28px;
line-height: 5em;
}
article div:nth-of-type(1) {
flex-basis: 100px;
width: 200px;
}
article div:nth-of-type(2) {
flex-basis: 200px;
}
article div:nth-of-type(3) {
flex-basis: 200px;
}
</style>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
19.弹性元素组规则和定义
Terms:flex
- flex 是 flex-grow、flex-shrink 、flex-basis 缩写组合。建议使用 flex 面不要单独使用 flex-grow / flew-shrink / flex-basis 。
html
<!-- 下例定义平均分配剩余空间,并不进行尺寸缩小,基础尺寸为 200px。 -->
<style>
* {
padding: 0;
margin: 0;
}
article {
width: 600px;
position: relative;
height: 150px;
margin-left: 100px;
margin-top: 100px;
outline: solid 5px silver;
display: flex;
padding: 20px;
}
article div {
outline: solid 5px blueviolet;
text-align: center;
font-size: 28px;
line-height: 5em;
flex: 1 0 100px;
}
</style>
20.控制弹性元素的排序
Terms:order
- 用于控制弹性元素的位置,默认为 order:0 数值越小越在前面,可以负数或整数。
html
<style>
* {
margin: 0;
padding: 0;
}
body {
padding-left: 50px;
padding-top: 15px;
}
article {
border: 5px solid silver;
width: 400px;
display: flex;
height: 550px;
padding: 10px;
flex-direction: column;
justify-content: space-between;
}
article div {
background-color: blueviolet;
background-clip: content-box;
padding: 10px;
flex: 1;
color: #fff;
font-size: 55px;
}
article :nth-child(1) {
order: 1;
}
article :nth-child(2) {
order: -1;
}
article :nth-child(3) {
order: -11;
}
</style>
<body>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
</body>
21.弹性元素排序实例
- 下面是通过 J 动态改变 order 属性产生移动效果,因为本章节是讲 CSS 所以 JS 功能没有完善,只是体验一下 order。
html
<style>
* {
padding: 0;
margin: 0;
}
body {
padding-left: 50px;
padding-top: 15px;
}
article {
border: solid 5px silver;
width: 400px;
height: 400px;
padding: 10px;
display: flex;
flex-direction: column;
}
article section {
order: 1;
flex: 1 0 100px;
padding: 10px;
background: blueviolet;
background-clip: content-box;
display: flex;
flex-direction: column;
text-align: center;
color: white;
}
article section div {
flex: 1;
}
article section div {
display: flex;
flex-direction: column;
justify-content: center;
}
article section span {
flex: 0;
background: #000;
padding: 20px;
cursor: pointer;
}
</style>
<article>
<section>
<div>houdunren.com</div>
<span onclick="up(this)">up</span>
</section>
<section>
<div>hdcms.com</div>
<span onclick="up(this)">up</span>
</section>
</article>
<script>
function up(el) {
el.parentElement.style.order = getOrder(el.parentElement) * 1 - 1;
console.log(getOrder(el.parentElement));
}
function getOrder(el) {
return getComputedStyle(el, null).order;
}
</script>
D.弹性文本
22.弹性布局操作文本节点
- 文本节点也在弹性布局操作范围内。
html
<style>
article {
display: flex;
flex-direction: row;
justify-content: space-between;
height: 100vh;
align-items: center;
font-size: 14px;
}
</style>
<article>
hd
<span>houdunren</span>
hd
</article>
E.绝对定位
23.定位元素在弹性布局中的表现
- 绝对定位的弹性元素不参与弹性布局
html
<style>
* {
padding: 0;
margin: 0;
padding: 10px;
margin: 5px;
}
article {
position: relative;
height: 400px;
border: solid 5px silver;
box-sizing: border-box;
display: flex;
justify-content: space-evenly;
align-items: flex-start;
}
article div {
min-width: 50px;
min-height: 80px;
border: solid 5px blueviolet;
text-align: center;
font-size: 28px;
}
article div:nth-of-type(1) {
position: absolute;
top: 0;
}
</style>
<article>
<div>1</div>
<div>2</div>
<div>3</div>
</article>
F.微信公众号
24.弹性布局移动端通用菜单
25.多级菜单的弹性布局
html
<style>
* {
padding: 0;
margin: 0;
}
body {
display: flex;
flex-direction: column;
height: 100vh;
color: #666;
}
main {
flex: 1;
}
footer {
height: 50px;
background: blueviolet;
display: flex;
justify-content: space-evenly;
}
footer section {
display: flex;
flex: 1 0;
flex-direction: column-reverse;
border-right: solid 1px #555;
border-top: solid 1px #555;
}
footer section:last-child {
border-right: none;
}
footer section h4 {
flex: 0 0 50px;
display: flex;
text-align: center;
flex-direction: column;
justify-content: center;
cursor: pointer;
color: white;
}
footer section ul {
text-align: center;
display: flex;
flex-direction: column;
border: solid 1px #555;
margin-bottom: 5px;
border-radius: 5px;
margin: 5px;
}
footer section ul li {
flex: 1 0 50px;
border-bottom: solid 1px #555;
display: flex;
flex-direction: column;
justify-content: center;
cursor: pointer;
}
footer section ul li:last-child {
border: none;
}
</style>
<main></main>
<footer>
<section>
<h4>教程</h4>
<ul>
<li>PHP</li>
<li>LINUx</li>
</ul>
</section>
<section>
<h4>直播</h4>
</section>
</footer>
G.自动空间
26.使用 magin 自动撑满空间技巧 margin-right: auto
- 在弹性布局中对元素使用
margin-right:auto
等形式可以自动撑满空间。下例为第一个 ul 设置margin-right:auto
表示右侧空间自动撑满,第二个 ul 靠近父元素右边界。
html
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
* {
padding: 0;
margin: 0;
}
.container {
width: 1200px;
margin: 0 auto;
}
nav {
display: flex;
border: solid 1px green;
margin-top: 20px;
align-items: center;
height: 60px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
background: #f3f3f3;
}
ul {
list-style: none;
}
ul:nth-child(1) {
display: flex;
align-items: center;
margin-right: auto;
}
ul:nth-child(1) > li {
margin: 0 10px;
}
ul:nth-child(2) > li {
width: 50px;
height: 50px;
border-radius: 50%;
background: #9b59b6;
}
</style>
</head>
<body>
<div class="container">
<nav>
<ul>
<li>houdunren</li>
<li>视频教程</li>
<li>每晚直播</li>
<li>在线文档</li>
</ul>
<ul>
<li></li>
</ul>
</nav>
</div>
</body>