所谓弹性盒模型就是首先要有一个盒子,即弹性盒,在盒子中的所有的元素都是弹性元素,我们可以控制里面的元素的排列组合。
例如盒子中有两个元素水平排列时,他们自动等宽排列。我们同样可以使其(弹性元素)竖直排列。
当增加了一个盒子,会自动变为三个元素水平等宽排列。
1 声明弹性盒子
例如当前我们有这样一个结构:
1 2 3 4 5 6 7
| <body> <article> <div>1</div> <div>2</div> <div>3</div> </article> </body>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| * { margin: 0; padding: 0; }
article { border: 2px solid rgb(15, 25, 171); width: 500px; margin: 50px auto; }
article * { width: 100px; height: 100px; background-color: red; margin: 10px; font-size: 50px; }
|
2 弹性元素排列
默认的HTML的文档流排列方法为从上到下, 1,2,3 三个div
以此排列。
当我们在article
上添加 display:flex
时,此时三个div
将编程如下的排列方式:
1 2 3 4 5 6 7
| article { display: flex; border: 2px solid rgb(15, 25, 171); width: 500px; margin: 50px auto; }
|
弹性盒中的弹性元素默认为水平排列,当元素的个数发生变化,元素宽度会自适应伸缩。我们仍然可以使用flex-direction
来改变弹性元素的排列方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| article { display: flex;
flex-direction: row; border: 2px solid rgb(15, 25, 171); width: 500px; margin: 50px auto; }
|
3 弹性元素换行
在上文中, 弹性元素都没有弹性盒子的宽度宽,有时候我们会有很多的弹性元素,默认是自适应伸缩的,但是我们想让他们超过弹性盒子宽度时进行换行要怎么实现呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| article { display: flex; flex-direction: row;
flex-wrap: wrap; border: 2px solid rgb(15, 25, 171); width: 300px; margin: 50px auto; }
|
根据flex-wrap
的属性和flex-direction
的属性,我们可以控制元素的水平、列排布以及在元素溢出的时候的换行排布。css针对上述属性提供了一个快捷的属性flex-flow
。
1 2 3 4 5 6 7 8 9 10 11
| article { display: flex;
flex-flow: column wrap; border: 2px solid rgb(15, 25, 171); width: 300px; height: 300px; margin: 50px auto; }
|
4 弹性盒排列的方式
在弹性元素水平竖直排列时候,会有一个轴的概念。弹性盒主要根据轴来区分弹性元素排列的方向。弹性盒内部会有一个主轴副轴之分,如果是默认排列方式:flex-flow:row nowarp
此时水平方向的轴为弹性盒的主轴。当元素换行的时候元素就会根据副轴(即竖直方向的轴)进行排列。
如果是排列方式为:flex-flow:column nowarp
此时竖直方向的轴为弹性盒的主轴。当元素换行的时候元素就会根据副轴(即水平方向的轴)进行排列。
所以根据上面的图例,可以说明在弹性盒模型中,主轴并不一定是水平方向或者是垂直方向,是要根据弹性盒模型的flex-direction
属性决定的。
5 主轴的排列方式(单行)
使用justify-content
来控制主轴的排列方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| article { display: flex; flex-flow: row wrap;
justify-content: space-around; border: 2px solid rgb(15, 25, 171); width: 600px; height: 600px; margin: 50px auto; }
|
当主轴为竖直方向也是相同的排列规则。
6 副轴(交叉轴)的排列方式(单行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| article { display: flex; flex-flow: row nowrap; justify-content: space-around;
align-items: stretch; border: 2px solid rgb(15, 25, 171); width: 800px; height: 300px; margin: 50px auto; }
article * { width: 100px; background-color: red; margin: 10px; font-size: 50px; }
|
案例:单行元素在弹性盒模型中水平垂直居中。
1 2 3 4 5 6 7
| <body> <article> <div>1</div> <div>2</div> <div>3</div> </article> </body>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| * { margin: 0; padding: 0; }
article { display: flex; justify-content: center; align-items: center; border: 2px solid rgb(15, 25, 171); width: 500px; height: 500px; margin: 50px auto; }
article * { text-align: center; line-height: 100px; width: 100px; height: 100px; background-color: red; margin: 10px; font-size: 50px; }
|
步骤:
- 将盒子设置为弹性盒模型。
- 设置主轴方向上的居中:
justify-content: center
。
- 设置副轴(交叉轴)方向上的居中:
align-items: center
。
7 多行元素在交叉轴的排列
如果交叉轴的元素有margin
属性是auto
,则会忽略align-self
。
1 2 3 4 5 6 7 8 9 10 11
| article :nth-child(2) {
align-self: baseline; }
|
8 弹性元素在弹性盒可用空间的分配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| article { display: flex; width: 600px; height: 600px; border: 1px solid red; flex-flow: row nowrap; }
article :first-child {
flex-grow: 1; }
article :nth-child(2) {
flex-grow: 2; }
article :last-child { flex-grow: 3; }
|
9 关于第八点的案例
在手机应用中,常常会有顶部导航栏,底部菜单栏,中间全部时内容区域。切会根据不同的手机分辨率,自适用伸缩。
1 2 3 4 5
| <body> <header></header> <main></main> <footer></footer> </body>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| * { margin: 0; padding: 0; }
body { height: 100vh; display: flex; flex-direction: column; justify-content: space-between; }
header { height: 60px; background-color: aquamarine; }
main { flex-grow: 1; background-color: blueviolet; }
footer { height: 60px; background-color: forestgreen; }
|
10 元素在单行的缩小关系(弹性盒空间不够,但是元素不换行)
flex-shrink
:控制元素在弹性盒空间不足以容纳弹性元素且不换行时的弹性元素的伸缩比例。
当flex-shirk
为0时,弹性元素不进行缩放,如果设置某个元素的缩放比例。
元素缩小比例的计算规则:(可以缩小的总宽度/((A元素flex-shrink的值) + (B元素flex-shrink的值) + …) * 对应flex-shrink的值) * 元素的本身的宽度。这个属性用的比较少。。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| article :first-child { flex-shrink: 0; }
article :nth-child(2) { flex-shrink: 2; }
article :nth-child(3) { flex-shrink: 3; }
|
11 主轴的基准尺寸
flex-basis
的主轴的基准尺寸,来设置元素的宽度或者高度,当主轴为水平轴时,基准尺寸为元素的宽度,如果是竖直排列,基准尺寸为元素的高度。
基准尺寸会覆盖元素的宽度。但是当元素有max-width
或者min-width
时,他的优先级要比基准尺寸要高。所以优先级为:max/min-width
>flex-basis
>width
。
12 结合弹性元素的放大、缩放、主轴组合定义
flex: 放大 缩放 主轴基准
1 2 3 4 5 6 7 8
| artile div { flex-grow: 1; flex-shrink: 2; flex-basis: 100px; flex: 1 2 100px; }
|
13 控制弹性盒模型的弹性元素顺序
order
属性的值为整数,代表按照顺序排列元素, 按照该整数(最低的值)首先按照视觉顺序放置项目。如果多个项目具有相同的整数值,则在该组中按照源顺序对项目进行布局。
值越低顺序越在前,越高越往后。
14 弹性盒模型中的文本
文本同样适用于弹性盒模型。
15 定位元素在弹性布局中的效果
- 绝对定位
- 和普通的绝对定位一致,直接浮动于其他的元素之上,其他的元素无法感知到他的位置。可以使用top left 等进行控制。
- 相对定位
- 相对定位,原来的空间位是保存的,其他的元素能够感知到他,不会占据他的空间,也可以top left 等进行控制。
16 案例(一)
移动端的弹出菜单栏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title>
<style> * { margin: 0; padding: 0; }
body { height: 100vh; display: flex; flex-direction: column; font-size: 30px; }
main { flex: 1; background-color: #f3f3f3; }
footer { height: 100px; display: flex; border-top: 1px solid #ccc; justify-content: space-between; background-color: rgb(145, 145, 149); }
footer section { flex: 1; background-color: rgb(174, 171, 171); border-right: 1px solid seagreen;
display: flex; flex-direction: column-reverse; }
footer section h4 { flex: 0 0 100px; display: flex; flex-direction: column; justify-content: center; text-align: center; font-size: 2rem; cursor: pointer; }
footer section ul { display: flex; flex-direction: column; border: 1px solid #ccc; text-align: center; }
footer section ul li { border: 1px solid #ccc; flex: 1 0 70px; display: flex; flex-direction: column; justify-content: center; cursor: pointer; } </style> </head> <body> <header></header>
<main></main> <footer> <section> <h4>后端</h4> <ul> <li>Python</li> <li>Django</li> <li>Flask</li> </ul> </section> <section> <h4>AI</h4> <ul> <li>Pytorch</li> <li>TensorFlow</li> </ul> </section> <section> <h4>大前端</h4> <ul> <li>JavaScript</li> <li>CSS</li> <li>Vue</li> <li>React</li> </ul> </section> </footer> </body> </html>
|
效果:
17 案例(二)
导航栏的左右靠边
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title>
<style> * { margin: 0; padding: 0; }
nav { width: 1200px; height: 60px; background-color: #f3f3f3; margin: 0 auto; display: flex; align-items: center; } ul { list-style: none; display: flex; align-items: center; }
ul:nth-child(1) { /* 使用flex:1 代表让第一个ul占满弹性盒, 剩下的元素按照他自身的宽度占据弹性盒的宽度 margin-right:auto也可以达到 flex:1 同样的效果 */ flex: 1; }
ul:nth-child(1) > li { margin: 0 20px; }
ul:nth-child(2) > li { width: 50px; height: 50px; margin-right: 20px; background: chartreuse; border-radius: 100% 100%; justify-content: center; display: flex; justify-content: center; align-items: center; } </style> </head> <body> <nav> <ul> <li><a href="">Python</a></li> <li><a href="">Go</a></li> <li><a href="">JavScript</a></li> </ul> <ul> <li>JS</li> </ul> </nav> </body> </html>
|
效果: