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 支持良好。

相关推荐
网络点点滴9 小时前
前端与后端的区别与联系
前端
EnCi Zheng10 小时前
M5-markconv自定义CSS样式指南 [特殊字符]
前端·css·python
kyriewen10 小时前
你的网页慢,用户不说直接走——前端性能监控教你“读心术”
前端·性能优化·监控
广州华水科技10 小时前
北斗GNSS变形监测在大坝安全监测中的应用与优势分析
前端
前端老石人10 小时前
前端开发中的 URL 完全指南
开发语言·前端·javascript·css·html
CAE虚拟与现实10 小时前
五一假期闲来无事,来个前段、后端的说明吧
前端·后端·vtk·three.js·前后端
Sarvartha10 小时前
三目运算符
linux·服务器·前端
晓晨的博客10 小时前
ROS1录制的bag包转换为ROS2格式
前端·chrome
Wect10 小时前
LeetCode 72. 编辑距离:动态规划经典题解
前端·算法·typescript
donecoding10 小时前
别再让 pnpm 跟着 nvm 跑了!独立安装终极指南
前端·node.js·前端工程化