flex布局
flex布局
Flex 是 Flexible Box 或 flexbox 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
简单易懂:与传统的布局方式相比,Flex布局的语法和理解起来更加简单,容易上手。
弹性和自适应:Flex布局能够自动适应不同尺寸的屏幕,让页面更具有弹性。
等高布局:Flex布局可以方便地实现多列等高布局。
对齐和排序:Flex布局支持各种对齐方式,包括水平和垂直对齐,并且可以通过设置order属性对子元素进行排序。
可以与传统布局结合使用:Flex布局并不是完全取代传统的布局方式,它可以与传统布局方式结合使用,实现更灵活的布局效果
# 1 采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目" -容器和项目:container、item # 2 容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis) -主轴和交叉轴:main axis、cross axis # 3 主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。 -起始位置: main start 主轴起始位置 cross start 侧轴起始位置 -结束位置: main end 主轴结束位置 cross start 侧轴结束位置 # 4 项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size -主轴尺寸 -侧轴尺寸
容器样式属性
flex-direction
: 决定主轴的方向。
flex-wrap
: 如果一条轴线排不下,如何换行。
flex-flow
: flex-direction 属性和 flex-wrap 属性的简写属性。
justify-content
: 定义项目在主轴上的对齐方式。
align-items
: 定义项目在交叉轴上如何对齐。
align-content
: 定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
flex-direction
row(默认值)
: 主轴为水平方向,起点在左端。
row-reverse
: 主轴为水平方向,起点在右端。
column
: 主轴为垂直方向,起点在上沿。
column-reverse
: 主轴为垂直方向,起点在下沿。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { width: 800px; height: 400px; border: 1px solid black; margin: auto; /* box 居中*/ /* 使用弹性布局 */ display: flex; /* row(默认值):主轴为水平方向,起点在左端。 */ flex-direction: row; /* row-reverse column column-reverse */ } .box div { width: 100px; height: 100px; background-color: pink; border: 1px solid red; } </style> </head> <body> <div class="box"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> </div> </body> </html>
flex-wrap
默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行
flex-wrap 属性规定flex容器是单行或者多行,同时横轴的方向决定了新行堆叠的方向
nowrap
: 不换行
wrap
: 换行,第一行在上方
wrap-reverse
: 换行,第一行在下方
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { width: 800px; height: 400px; border: 1px solid black; margin: auto; /* box 居中*/ /* 使用弹性布局 */ display: flex; /* row(默认值):主轴为水平方向,起点在左端。 */ flex-direction: row; /* row-reverse column column-reverse */ flex-wrap:wrap; } .box div { width: 100px; height: 100px; background-color: pink; border: 1px solid red; } </style> </head> <body> <div class="box"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> <div>8</div> <div>9</div> </div> </body> </html>
flex-flow
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
flex-flow: row wrap; # 等同于 flex-direction : row; flex-wrap : wrap;
justify-content x轴
justify-content属性定义了项目在主轴上的对齐方式
flex-start(默认值)
: 左对齐
flex-end
: 右对齐
center
: 居中
space-between
: 两端对齐,项目之间的间隔都相等
space-around
: 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍
space-evenly
: 项目与项目之间,项目与边框之间的间隔都相等
flex-start
左对齐(默认)
justify-content: flex-start;
flex-end
右对齐
justify-content: flex-end;
center
居中
justify-content: center;
space-between
两端对齐
justify-content: space-between;
space-around
每个项目两侧的间隔相等
justify-content: space-around;
space-evenly
项目与项目之间,项目与边框之间的间隔都相等
justify-content: space-evenly;
align-items y轴
align-items属性定义项目在交叉轴上如何对齐。
flex-start
: 交叉轴的起点对齐。
flex-end
: 交叉轴的终点对齐。
center
: 交叉轴的中点对齐。
baseline
: 项目的第一行文字的基线对齐。
stretch(默认值)
: 如果项目未设置高度或设为 auto,将占满整个容器的高度
flex-start
交叉轴的起点对齐
align-items: flex-start;
flex-end
交叉轴的终点对齐
align-items: flex-end;
center
交叉轴的中点对齐
align-items: center;
baseline
项目的第一行文字的基线对齐
align-items: baseline;
stretch
如果项目未设置高度或设为 auto,将占满整个容器的高度
align-items: stretch;
align-content
align-content属性定义了多根轴线的对齐方式。
如果项目只有一根轴线,该属性不起作用。
使用align-content属性的前提,必须是flex-wrap: wrap
flex-start
: 与交叉轴的起点对齐。
flex-end
: 与交叉轴的终点对齐。
center
: 与交叉轴的中点对齐。
space-between
: 与交叉轴两端对齐,轴线之间的间隔平均分布。
space-around
: 每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值)
: 轴线占满整个交叉轴。
flex-start
与交叉轴的起点对齐
align-content:flex-start;
flex-end
与交叉轴的终点对齐
align-content:flex-end;
center
与交叉轴的中点对齐
align-content:center;
space-between
与交叉轴两端对齐,轴线之间的间隔平均分布
align-content:space-between;
space-around
每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍
align-content:space-around;
stretch(默认值)
轴线占满整个交叉轴
align-content: stretch;
项目样式属性
order
order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { width: 800px; height: 400px; border: 1px solid black; margin: auto; /* box 居中*/ /* 使用弹性布局 */ display: flex; flex-flow: row wrap; /* flex-start:与交叉轴的起点对齐。 */ align-content: flex-start; /* flex-end:与交叉轴的终点对齐。 */ align-content: flex-end; /* center:与交叉轴的中点对齐。 */ align-content: center; /* space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。 */ align-content: space-between; /* space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。 */ align-content: space-around; /* stretch(默认值):轴线占满整个交叉轴。 */ align-content: stretch; } .box div { width: 100px; height: 100px; /*align-content: stretch 不设置高度*/ background-color: pink; border: 1px solid red; } .box div:nth-child(1){ order: -1; } .box div:nth-child(2){ order: 2; } .box div:nth-child(3){ order: 4; } .box div:nth-child(4){ order: 0; } .box div:nth-child(5){ order: 3; } .box div:nth-child(6){ order: 7; } </style> </head> <body> <div class="box"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> </div> </body> </html>
flex-grow
flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大
如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍
均匀分布
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { width: 800px; height: 400px; border: 1px solid black; margin: auto; /* box 居中*/ /* 使用弹性布局 */ display: flex; flex-flow: row wrap; /* flex-start:与交叉轴的起点对齐。 */ align-content: flex-start; /* flex-end:与交叉轴的终点对齐。 */ align-content: flex-end; /* center:与交叉轴的中点对齐。 */ align-content: center; /* space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。 */ align-content: space-between; /* space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。 */ align-content: space-around; /* stretch(默认值):轴线占满整个交叉轴。 */ align-content: stretch; } .box div { width: 100px; height: 100px; /*align-content: stretch 不设置高度*/ background-color: pink; border: 1px solid red; } .box div:nth-child(1) { flex-grow: 1; } .box div:nth-child(2) { flex-grow: 1; } .box div:nth-child(3) { flex-grow: 1; } </style> </head> <body> <div class="box"> <div>1</div> <div>2</div> <div>3</div> </div> </body> </html>
中间占两倍,两边一样大
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { width: 800px; height: 400px; border: 1px solid black; margin: auto; /* box 居中*/ /* 使用弹性布局 */ display: flex; flex-flow: row wrap; /* flex-start:与交叉轴的起点对齐。 */ align-content: flex-start; /* flex-end:与交叉轴的终点对齐。 */ align-content: flex-end; /* center:与交叉轴的中点对齐。 */ align-content: center; /* space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。 */ align-content: space-between; /* space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。 */ align-content: space-around; /* stretch(默认值):轴线占满整个交叉轴。 */ align-content: stretch; } .box div { width: 100px; height: 100px; /*align-content: stretch 不设置高度*/ background-color: pink; border: 1px solid red; } .box div:nth-child(1){ flex-grow: 1; } .box div:nth-child(2){ flex-grow: 2; } .box div:nth-child(3){ flex-grow: 1; } </style> </head> <body> <div class="box"> <div>1</div> <div>2</div> <div>3</div> </div> </body> </html>
flex-shrink
flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小
负值对该属性无效
等比例缩小
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { width: 800px; height: 400px; border: 1px solid black; margin: auto; /* box 居中*/ /* 使用弹性布局 */ display: flex; flex-flow: row nowrap; } .box div { width: 400px; height: 100px; background-color: pink; border: 1px solid red; } .box div:nth-child(1) { flex-shrink: 1; } .box div:nth-child(2) { flex-shrink: 1; } .box div:nth-child(3) { flex-shrink: 1; } .box div:nth-child(4) { flex-shrink: 1; } </style> </head> <body> <div class="box"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> </div> </body> </html>
为0的情况
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { width: 800px; height: 400px; border: 1px solid black; margin: auto; /* box 居中*/ /* 使用弹性布局 */ display: flex; flex-flow: row nowrap; } .box div { width: 400px; height: 100px; background-color: pink; border: 1px solid red; } .box div:nth-child(1) { flex-shrink: 1; } .box div:nth-child(2) { flex-shrink: 0; } .box div:nth-child(3) { flex-shrink: 1; } .box div:nth-child(4) { flex-shrink: 1; } </style> </head> <body> <div class="box"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> </div> </body> </html>
flex-basis
flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { width: 800px; height: 400px; border: 1px solid black; margin: auto; /* box 居中*/ /* 使用弹性布局 */ display: flex; flex-flow: row nowrap; } .box div { width: 100px; height: 100px; background-color: pink; border: 1px solid red; } .box div:nth-child(2) { /* 将项目2的宽度设为200px */ flex-basis: 200px; } </style> </head> <body> <div class="box"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> </div> </body> </html>
flex
flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为 0 1 auto。后两个属性可选。
该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
一般情况下flex属性用于将项目平均占满空间
.box div { /* 使所有项目平均占满空间 */ flex: 1; }
align-self
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch
该属性可能取6个值,除了auto,其他都与align-items属性完全一致
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { width: 800px; height: 400px; border: 1px solid black; margin: auto; /* box 居中*/ /* 使用弹性布局 */ display: flex; flex-flow: row nowrap; } .box div { width: 100px; height: 100px; background-color: pink; border: 1px solid red; flex: 1; } .box div:nth-child(2) { /* 使第二个项目在交叉轴上终点对齐 */ align-self: flex-end; } </style> </head> <body> <div class="box"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> </div> </body> </html>
案例
元素垂直居中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { width: 800px; height: 400px; border: 1px solid black; margin: auto; /* box 居中*/ /* 使用弹性布局 */ display: flex; /* 使项目在主轴上中心对齐 */ justify-content: center; /* 使项目在交叉轴上中心对齐 */ align-items: center; } .box div { width: 100px; height: 100px; background-color: pink; border: 1px solid red; } </style> </head> <body> <div class="box"> <div></div> </div> </body> </html>
圣杯布局
中间内容部分优先加载
两侧导航栏宽度固定不变,中间部分自动填充整个区域
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .box { /* 将盒子进行弹性布局 */ display: flex; } .left { width: 100px; height: 200px; background-color: green; /* 将左边导航栏的order设置最小,这样就可以跑到左边 */ order: -1; } .center { background-color: pink; height: 400px; /* 内容区域自动占满剩余空间 */ flex: 1; } .right { width: 200px; height: 200px; background-color: yellow; } </style> </head> <body> <div class="box"> <div class="center"></div> <div class="left"></div> <div class="right"></div> </div> </body> </html>
小米商城案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> body { background-color: #F5F5F5; } .box { width: 1200px; height: 150px; margin: auto; /* box 居中*/ /* 使用弹性布局 */ display: flex; /* row(默认值):主轴为水平方向,起点在左端。 */ flex-flow: row wrap; /* row-reverse column column-reverse */ justify-content: space-between; } .div { width: 300px; height: 160px; } .leftbox { width: 249px; background-color: red; display: flex; flex-flow: row wrap; } .leftc { width: 83px; background-color: #5F5750; display: flex; flex-flow: row wrap; justify-content: center; align-items: center; } .img { height: 160px; width: 300px; } .imgs { height: 40px; width: 40px; } .middiv { display: flex; flex-flow: row wrap; justify-content: center; align-items: center; } .midimg { width: 1200px; height: 120px; } .bottomphone { margin: auto; width: 1200px; display: flex; flex-flow: row wrap; justify-content: flex-start; } .bottomdiv { width: 1200px; height: 500px; margin: auto; display: flex; align-items: stretch; justify-content: space-between; } .bottomleft { width: 240px; } .bottomright { width: 220px; display: flex; flex-flow: column wrap; justify-content: space-between; } .bottomright div { width: 100%; height: 240px; background-color: #fff; } .bottomright div img { width: 100%; height: 180px; } </style> </head> <body> <div class="box"> <div class="leftbox"> <div class="leftc"><img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/82abdba456e8caaea5848a0cddce03db.png?w=48&h=48" alt="" class="imgs"> <span style="color: white;">保障服务</span> </div> <div class="leftc"><img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/806f2dfb2d27978e33fe3815d3851fa3.png?w=48&h=48" alt="" class="imgs"> <span style="color: white;">企业团购</span> </div> <div class="leftc"><img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/eded6fa3b897a058163e2485532c4f10.png?w=48&h=48" alt="" class="imgs"> <span style="color: white;">F码通道</span> </div> <div class="leftc"><img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/43a3195efa6a3cc7662efed8e7abe8bf.png?w=48&h=48" alt="" class="imgs"> <span style="color: white;">米粉卡</span></span> </div> <div class="leftc"><img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/f4846bca6010a0deb9f85464409862af.png?w=48&h=48" alt="" class="imgs"> <span style="color: white;">以旧换新</span> </div> <div class="leftc"><img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/9a76d7636b08e0988efb4fc384ae497b.png?w=48&h=48" alt="" class="imgs"> <span style="color: white;">话费充值</span> </div> </div> <div class="div"><img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/6b67117bc92924fb2ff0e7ad2be86084.png?w=632&h=340" alt="" class="img"></div> <div class="div"><img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/8dede2520f8dfff9c9b690af498cafe8.jpg?w=632&h=340" alt="" class="img"></div> <div class="div"><img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/1ac77590368ff636d0b4f6a988133f55.png?w=632&h=340" alt="" class="img"></div> </div> <br> <div class="middiv"> <img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/a2011078db9b3708d3caae52df7be3cc.png?thumb=1&w=1520&h=149&f=webp&q=90" alt="" class="midimg"> </div> <div class="bottomphone"> <p style="font-size: 30px;">手机</p> </div> <div class="bottomdiv"> <div class="bottomleft"> <img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/dcf9ed8c01a7c3d0bf3ecbca3f22537c.png?thumb=1&w=290&h=761&f=webp&q=90" alt="" style="width: 220px; height:100%;"> </div> <div class="bottomright"> <div><img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/adde6bae41441887017824f46cf31602.png?thumb=1&w=248&h=248&f=webp&q=90" alt=""></div> <div><img src="https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202311281411_fc68b941c011a8bbf67db570d0985d7a.png?thumb=1&w=248&h=248&f=webp&q=90" alt=""></div> </div> <div class="bottomright"> <div><img src="https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202403201526_60b548a0614d956b2d3667a63d513539.png?thumb=1&w=248&h=248&f=webp&q=90" alt=""></div> <div><img src="https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202311281019_bf131f8cb94d59e370cb84cae6ad5e49.png?thumb=1&w=248&h=248&f=webp&q=90" alt=""></div> </div> <div class="bottomright"> <div><img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/f2a277341a09a63bbb7bba12d154c4e6.png?thumb=1&w=248&h=248&f=webp&q=90" alt=""></div> <div><img src="https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202310251928_35fb2880108e9aa56fdcf7f894249f26.png?thumb=1&w=248&h=248&f=webp&q=90" alt=""></div> </div> <div class="bottomright"> <div><img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/2e920ac7e3d197923acbd6388b80cc49.png?thumb=1&w=248&h=248&f=webp&q=90" alt=""></div> <div><img src="https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202310251937_a4ac1ae382a402426beb915f401e50e5.png?thumb=1&w=248&h=248&f=webp&q=90" alt=""></div> </div> </div> </body> </html>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了