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

相关推荐
HelloReader几秒前
Qt 项目构建入门CMake 完全指南(三)
前端
用户908324602737 分钟前
Spring AI + RAG + SSE 实现带搜索来源的智能问答完整方案
前端·后端
GISer_Jing12 分钟前
阿里开源纯前端浏览器自动化 PageAgent,[特殊字符] 浏览器自动化变天啦?
前端·人工智能·自动化·aigc·交互
清风徐来QCQ31 分钟前
js中的模板字符串
开发语言·前端·javascript
成都渲染101云渲染666636 分钟前
Houdini+Blender高效渲染方案(高配算力+全渲染器兼容)
前端·系统架构
SuperEugene1 小时前
Vue3 + Element Plus 表格实战:批量操作、行内编辑、跨页选中逻辑统一|表单与表格规范篇
开发语言·前端·javascript
极梦网络无忧1 小时前
基于 Vite + Vue3 的组件自动注册功能
前端·javascript·vue.js
Predestination王瀞潞1 小时前
5.4.3 通信->WWW万维网内容访问标准(W3C):WWW(World Wide Web) 协议架构(分层)
前端·网络·网络协议·架构·www
爱学习的程序媛2 小时前
【Web前端】优化Core Web Vitals提升用户体验
前端·ui·web·ux·用户体验
zabr2 小时前
花了 100+ 篇笔记,我整理出 了一套 AI Agent 工程完全指南
前端·后端·agent