css 实现等宽div均匀分布,超出换行保持均匀分布

前言

在日常开发中经常会遇到 list 列表,一行展示固定等宽的元素、均匀分布、超出自动换行也保持均匀分布的效果。这篇文章记录一下使用不同方式来实现这个效果。

页面dom结构

html 复制代码
<div class="list">
    <div class="item">元素</div>
    <div class="item">元素</div>
    <div class="item">元素</div>
    <div class="item">元素</div>
    <div class="item">元素</div>
    <div class="item">元素</div>
    <div class="item">元素</div>
    <div class="item">元素</div>
    <div class="item">元素</div>
    <!-- ...多个itme -->
</div>

实习方式 1(float)

发现问题

  • 一行显示 4个元素(可自定义),宽度变化时保持 "平均分布",超出部分自动换行保持 "居左" ,
css 复制代码
.list{
   width: 100%;
}
.item{
    float: left;
    width: 24.73%;
    height: 100px;
    margin-right: 10px;
    background-color: #abd3ad;
}
.item:nth-child(4n) {
    margin-right: 0;
}

使用 float + 宽度百分比实现, 一行 4 个, 100 / 4 = 25, 但是 25% 肯定不行,因为每个 item 是有 margin-right: 10px 的。 所以 item 宽度为 24% 时效果如下,右侧有空白:

那一点点加大发现当 width为 24.73%时

  • 浏览器窗口铺满效果

可以看到,当前浏览器窗口完全铺满当前笔记本屏幕的效果是 ok 的,左右边距、基本上符合预期效果。

  • 浏览器窗口宽度缩小

当把浏览器窗口宽度调小后,发现一行展示不下 4个盒子了,导致了换行,且其中部分 item 的边距重叠了,整体样式乱掉。

解决

所以,item 的宽度不能这样直接写死, 应该计算一下: width = 100% - (分布个数4-1) * 间隙值

这里的 4-1 是因为一行要排列 4 个,减 1 是因为最后一个元素是不需要 margin-right: 10px

所以计算为: 100% - 3 * 5px = 100% - 15px, 然后一行是4 个元素 最后除以 4,就是每个 item 的具体宽度,得到的样式为: width: calc((100% - 15px) / 4)

然后查看效果,浏览器窗口宽度撑满屏幕和变小都是保持一行 4 个元素,均匀分布。只不过当窗口宽度变小后 item 的宽度也会被压缩,因为我们的宽度单位是百分比,但 item 布局不会乱掉。

实现方式 2 (flex)

  • 一行显示 3个元素(可自定义),宽度变化时保持 "平均分布",超出部分自动换行保持 "居左"
css 复制代码
<style>
.list {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    /* 替代space-between布局方式 */
    justify-content: flex-start;
}
.item {
    margin: 0 5px 5px 0;
    /* 这里的10px 同上计算方式,可以根据实际的分布个数和间隙区调整 */
    flex: 1;
    width: calc((100% - 10px) / 3);
    height: 120px;
    /* 加入这两个后每个item的宽度生效 */
    min-width: calc((100% - 10px) / 3);
    max-width: calc((100% - 10px) / 3);
    background-color: #cacaca;
}
/* 去除item 第3n个的 margin-right */
.item:nth-child(3n) {
    margin-right: 0;
}
</style>
  • 上述代码关于 flex:1 ,可以简化为:
css 复制代码
<style>
.item {
    margin: 0 5px 5px 0;
    flex: 0 0 calc((100% - 10px) / 3);
    height: 120px;
    background-color: #cacaca;
}
/* 去除item 第3n个的 margin-right */
.item:nth-child(3n) {
    margin-right: 0;
}
</style>
  • 效果

实现方式 3(flex)

css 复制代码
.list {
    display: flex;
    flex-wrap: wrap;
    margin: -5px; /* 调整容器外边距以抵消内部间距 */
}
.item {
    flex: 0 0 calc(33.333% - 10px);
    margin: 5px; /* 统一边距 */
    height: 120px;
    background-color: #cacaca;
}

优点:

  • 统一边距:所有项目都使用相同的边距,避免了特殊处理。
  • 简单明了:减少了对特定子元素样式的需求。

实现方式 4(CSS Grid)

css 复制代码
.list {
    display: grid;
    grid-template-columns: repeat(3, 1 fr);
    gap: 10px; /* 使用 gap 属性设置行列间距 */
}

.item {
    height: 120px;
    background-color: #cacaca;
}

使用 Grid 方式的优点:

  • 简洁:不需要为每个项目指定宽度或处理边缘情况。
  • 响应式:可以通过媒体查询轻松调整列数。
  • 自动处理间距gap 属性会自动处理所有间距问题。

实现方式 5(Tailwind CSS)

html 复制代码
<div class="grid grid-cols-3 gap-4">
   <div class="h-96 bg-gray-300"></div>
   <div class="h-96 bg-gray-300"></div>
   <div class="h-96 bg-gray-300"></div>
   <!-- 更多 .item 元素 -->
</div>

这种方法的优点是:

  • 快速开发:无需编写额外的 CSS,直接在 HTML 中应用类名即可。
  • 一致性和维护性:遵循一致的设计系统,易于维护和扩展。

总结

至此, 使用几种不同方法实现了多元素等宽的列布局。 比较推荐的是使用 CSS Grid ,因为它不仅代码简洁,而且提供了更好的控制力和灵活性。此外,它还更容易进行响应式设计和其他复杂的布局调整。前提是目标浏览器对 CSS Grid 支持良好。

相关推荐
拾光拾趣录5 分钟前
🔥FormData+Ajax组合拳,居然现在还用这种原始方式?💥
前端·面试
不会笑的卡哇伊14 分钟前
新手必看!帮你踩坑h5的微信生态~
前端·javascript
bysking15 分钟前
【28 - 记住上一个页面tab】实现一个记住用户上次点击的tab,上次搜索过的数据 bysking
前端·javascript
Dream耀17 分钟前
跨域问题解析:从同源策略到JSONP与CORS
前端·javascript
前端布鲁伊18 分钟前
【前端高频面试题】面试官: localhost 和 127.0.0.1有什么区别
前端
HANK18 分钟前
Electron + Vue3 桌面应用开发实战指南
前端·vue.js
極光未晚34 分钟前
Vue 前端高效分包指南:从 “卡成 PPT” 到 “丝滑如德芙” 的蜕变
前端·vue.js·性能优化
郝亚军37 分钟前
炫酷圆形按钮调色器
前端·javascript·css
Spider_Man39 分钟前
别再用Express了!用Node.js原生HTTP模块装逼的正确姿势
前端·http·node.js
htt232141 分钟前
前端记录项目中用到的js
前端·ecmascript·es6