如何用Flexbox实现多div横向排列,按自身宽度显示并适配移动端
问题描述
需要借助Flexbox实现以下效果:
- 多个宽度为50px的div拼接成一条长线条,奇数里程标记位于线条上方,偶数里程标记位于线条下方,里程数量由服务端动态返回
- 适配桌面端与移动端:
- 桌面端:每个div宽度固定为50px,页面首次加载时线条不拉伸至浏览器全屏(如仅4个里程标记,只占用对应宽度)
- 移动端:若里程数量超出屏幕宽度,所有div等比例收缩并保持在一行显示
当前代码在桌面端加载时线条会被拉伸至浏览器最大宽度,尝试组合flex-shrink与flex-basis未解决问题,附原代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vertical Align Text Inside Flexbox</title> <style> .flex-container { padding: 0; margin: 0; list-style: none; -ms-box-orient: horizontal; display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -moz-flex; display: -webkit-flex; display: flex; width: 100%; align-items: flex-start; flex-basis: 0%; justify-content: start; } .flex-item-title { padding: 10px; text-align: left; font-weight: bold; font-family: Verdana, Helvetica, Sans-serif; font-size: 10pt; flex-basis: 100px; display: inline-block; flex: 1 1 auto; } .line_miles_red { padding: 10px; border-top: 3px solid red; height: 7px; font-weight: bold; font-size: 2em; text-align: center; width: 50px; flex: 1 1 auto; } .line_miles_blue { border-top: 3px solid blue; height: 7px; font-weight: bold; font-size: 2em; text-align: center; width: 50px; display: inline-block; flex: 1 1 auto; } .flex-item { padding: 10px; width: 50px; font-family: Verdana, Helvetica, Sans-serif; font-size: 8pt; font-weight: normal; text-align: center; flex: 1 1 auto; } /* .flex1 { flex: 1 1 2em; } .flex2 { flex: 1 1 2em; } */ </style> </head> <body> <div style="width: 50px; background-color: orange; height: 5px"></div> <br/> <div class="flex-container"> <div class="flex-item-title">Distance</div> <div class="flex-item">1 mile</div> <div class="flex-item"></div> <div class="flex-item">3 mile</div> <div class="flex-item"></div> <div class="flex-item">5 mile</div> <div class="flex-item"></div> <div class="flex-item">7 mile</div> <div class="flex-item"></div> <div class="flex-item">9 Mile</div> <div class="flex-item"></div> </div> <div class="flex-container"> <div class="flex-item-title"> </div> <div class="line_miles_blue flex2"></div> <div class="line_miles_red flex2"></div> <div class="line_miles_blue flex2"></div> <div class="line_miles_red flex2"></div> <div class="line_miles_blue flex2"></div> <div class="line_miles_red flex2"></div> <div class="line_miles_blue flex2"></div> <div class="line_miles_red flex2"></div> <div class="line_miles_blue flex2"></div> <div class="line_miles_red flex2"></div> </div> <div class="flex-container"> <div class="flex-item-title">Bottom Row</div> <div class="flex-item"></div> <div class="flex-item">Mile 2</div> <div class="flex-item"></div> <div class="flex-item">4 Mile</div> <div class="flex-item"></div> <div class="flex-item">6 Mile</div> <div class="flex-item"></div> <div class="flex-item">8 Mile</div> <div class="flex-item"></div> <div class="flex-item">10 Mile</div> </div> <br/> <br/> </body> </html>
解决方案
核心修改点
调整Flex容器属性
- 移除
width:100%,改用display: inline-flex让容器宽度由内部内容决定,避免强制拉伸至全屏 - 添加
flex-wrap: nowrap确保所有元素始终在一行显示 - 添加
min-width: 0解除移动端Flex项的收缩限制,确保空间不足时能正常收缩
- 移除
修正Flex项的伸缩规则
- 给所有里程相关的Flex项设置
flex: 0 1 50px:flex-grow:0禁止桌面端拉伸,flex-shrink:1允许移动端收缩,flex-basis:50px定义基础宽度 - 给标题项
flex-item-title设置flex: 0 0 100px:固定宽度,不参与伸缩
- 给所有里程相关的Flex项设置
统一盒模型
- 添加
box-sizing: border-box让padding包含在元素宽度内,避免额外宽度导致布局错位
- 添加
修改后的完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vertical Align Text Inside Flexbox</title> <style> /* 统一盒模型 */ * { box-sizing: border-box; margin: 0; padding: 0; } .flex-container { list-style: none; display: inline-flex; /* 容器宽度由内容决定 */ flex-wrap: nowrap; /* 强制一行显示 */ align-items: flex-start; justify-content: start; min-width: 0; /* 解除收缩限制 */ } .flex-item-title { padding: 10px; text-align: left; font-weight: bold; font-family: Verdana, Helvetica, Sans-serif; font-size: 10pt; flex: 0 0 100px; /* 固定宽度,不伸缩 */ } .line_miles_red { padding: 10px; border-top: 3px solid red; height: 7px; text-align: center; flex: 0 1 50px; /* 基础50px,不拉伸可收缩 */ } .line_miles_blue { padding: 10px; border-top: 3px solid blue; height: 7px; text-align: center; flex: 0 1 50px; /* 基础50px,不拉伸可收缩 */ } .flex-item { padding: 10px; font-family: Verdana, Helvetica, Sans-serif; font-size: 8pt; font-weight: normal; text-align: center; flex: 0 1 50px; /* 基础50px,不拉伸可收缩 */ } </style> </head> <body> <div style="width: 50px; background-color: orange; height: 5px"></div> <br/> <div class="flex-container"> <div class="flex-item-title">Distance</div> <div class="flex-item">1 mile</div> <div class="flex-item"></div> <div class="flex-item">3 mile</div> <div class="flex-item"></div> <div class="flex-item">5 mile</div> <div class="flex-item"></div> <div class="flex-item">7 mile</div> <div class="flex-item"></div> <div class="flex-item">9 Mile</div> <div class="flex-item"></div> </div> <div class="flex-container"> <div class="flex-item-title"> </div> <div class="line_miles_blue"></div> <div class="line_miles_red"></div> <div class="line_miles_blue"></div> <div class="line_miles_red"></div> <div class="line_miles_blue"></div> <div class="line_miles_red"></div> <div class="line_miles_blue"></div> <div class="line_miles_red"></div> <div class="line_miles_blue"></div> <div class="line_miles_red"></div> </div> <div class="flex-container"> <div class="flex-item-title">Bottom Row</div> <div class="flex-item"></div> <div class="flex-item">Mile 2</div> <div class="flex-item"></div> <div class="flex-item">4 Mile</div> <div class="flex-item"></div> <div class="flex-item">6 Mile</div> <div class="flex-item"></div> <div class="flex-item">8 Mile</div> <div class="flex-item"></div> <div class="flex-item">10 Mile</div> </div> <br/> <br/> </body> </html>
内容的提问来源于stack exchange,提问作者KV MC
相关产品推荐
相关产品推荐

