CSS 实现 flex布局最后一行左对齐的方案「多场景、多方案」

news2024/12/23 1:18:43

目录

  • 前言
  • 解决方案
    • 场景一、子项宽度固定,每一行列数固定
        • 方法一:模拟两端对齐
        • 方法二:根据元素个数最后一个元素动态margin
    • 场景二、子项的宽度不确定
        • 方法一:直接设置最后一项 margin-right:auto
        • 方法二:使用:after(伪元素)来实现最后一行的左对齐
    • 场景三、每一行列数不固定
        • 方法一:使用 Grid 布局【最佳实践】
  • 小结


前言

在CSS flex布局中,使用 justify-content 来控制列表的水平对齐方式,使用 space-around 或者 space-between 对齐时,如果最后一行的列表的个数不满,就会出现最后一行没有完全垂直对齐的问题。

👇 如下示例:

<div class="container">
    <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>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>
.container {
    width: 400px;
    border: 1px solid #000;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    padding: 5px;
}
.item {
    width: 70px;
    height: 70px;
    margin-bottom: 10px;
    background-color: yellowgreen;
}

👇 可以看到最后一行的元素个数不够,不是我们想要的效果
在这里插入图片描述

解决方案

场景一、子项宽度固定,每一行列数固定

每一行的子项宽度固定,所以列数也可固定,实现方案如下。

方法一:模拟两端对齐

👉 原理
使用 margin 模拟 space-between 和元素之间的间隙

👉 计算方式: 已知每一行列数是固定的,比如每一行5(n)列
剩余可使用宽度 = .container容器宽度 - (.item宽度 * 5) 👉 width = 400 - (70 * 5) = 50
设置margin = 剩余可使用宽度 / (5 - 1) 👉 marginRight = 50 / (5 - 1) = 12.5
公示合并 👉 marginRight = (.container容器宽度 - (.item宽度 * n)) / (n-1)

.container {
  	width: 400px;
    border: 1px solid #000;
    display: flex;
    flex-wrap: wrap;
    /* justify-content: space-between; */
    padding: 5px;
}
.item {
    width: 70px;
    height: 70px;
    margin-bottom: 10px;
    background-color: yellowgreen;
}
.item:not(:nth-child(5n)) {
    margin-right: 12.5px;
}

👇 效果如下:
在这里插入图片描述

方法二:根据元素个数最后一个元素动态margin

👉 原理
动态设置margin指的是设置最后一个元素的margin值。
比如我们每一行5个元素,但是最后一行只有4个元素,此时如果我们将最后一行的最后一个元素的右边距设置为元素宽度+间隙宽度,那么是可以实现左对齐效果的。

👉 计算方式: 针对最后一行,分别有一个元素,有两个元素,有三个元素,有四个元素等情况
.item:last-child:nth-child(5n - 1) => 当n为1时,5n-1=4,代表是第四个元素,marginRight 就是第五个元素的 width+1个空隙的宽度
.item:last-child:nth-child(5n - 2) => 当n为1时,5n-2=3,代表是第三个元素,marginRight 就是第四个元素的 width+第五个元素的width+2个空隙的宽度
以此类推…
.item:last-child:nth-child(5n - m),需要之前【方法一】中计算的 _marginRight = (.container容器宽度 - (.itemWidth * n)) / (n-1)
推算公示 👉 marginRight = (.itemWidth * m + _marginRight * m)

.container {
  	width: 400px;
    border: 1px solid #000;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    padding: 5px;
}
.item {
    width: 70px;
    height: 70px;
    margin-bottom: 10px;
    background-color: yellowgreen;
}
/* 当n为1时,5n-1=4,代表是第四个元素,margin-right就是第五个元素的width+1个空隙的宽度 */
.item:last-child:nth-child(5n - 1) {
    margin-right: 82.5px;
}
/* 当n为1时,5n-2=3,代表是第三个元素,margin-right就是第四个元素的width+第五个元素的width+2个空隙的宽度 */
.item:last-child:nth-child(5n - 2) {
    margin-right: 165px;
}
/* 当n为1时,5n-3=2,代表是第二个元素,margin-right就是第三个元素的width+第四个元素的width+第五个元素的width+3个空隙的宽度 */
.item:last-child:nth-child(5n - 3) {
    margin-right: 247.5px;
}

👇 效果如下:

在这里插入图片描述

场景二、子项的宽度不确定

当每一个子元素宽度不固定时,此时的元素间隙的大小也不固定,所以相对来说处理更简单。

方法一:直接设置最后一项 margin-right:auto

👉 原理
让最后一个元素的右边距自动适应,从而实现左对齐的效果

👇 style

.container {
    width: 400px;
    border: 1px solid #000;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    padding: 5px;
}

.item {
    width: 70px;
    height: 70px;
    margin: 10px;
    background-color: yellowgreen;
}
.item:last-child {
    margin-right: auto;
}

👇 html 改造

<div class="container">
   	<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>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>
<script>
	// 动态随机设置 .item 宽度
    let itemDiv = document.querySelectorAll(".container .item");
    for (var i = itemDiv.length - 1; i >= 0; i--) {
        itemDiv[i].style.width = rand(70, 40) + "px";
    }
    function rand(max, min) {
        return Math.floor( Math.random() * (max - min + 1) + min);
    }
</script>

👇 效果如下(容器尺寸不变的情况下):
在这里插入图片描述
👇 效果2如下(容器尺寸变的情况下):
在这里插入图片描述

方法二:使用:after(伪元素)来实现最后一行的左对齐

👉 原理
使用css中的 :after(伪元素) 给 父容器 设置 flex:autoflex:1 来实现最后一行的左对齐,使用伪元素进行占位

👇 style 改造

.container {
    width: 400px;
    border: 1px solid #000;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    padding: 5px;
}

.item {
    width: 70px;
    height: 70px;
    margin: 10px;
    background-color: yellowgreen;
}
.container::after {
   	content: '';
    flex: auto;    
    /* 或者flex: 1 */
}

👉 html 改造同【方法一】中的html

👉 效果与【方法一】中实现效果相同

场景三、每一行列数不固定

每一行的列数不固定,那么上面的那些方法均不适用,请看如下方案

当我们布局的列表个数不固定,这个时候我们不妨可以换一种思维,试试使用 Grid 布局。

方法一:使用 Grid 布局【最佳实践】

👉 原理
Grid 布局天然有 gap 间隙,且格子对齐排布,因此,实现最后一行左对齐可以认为是最佳效果。
👇 代码解释:
display: grid 指定一个容器采用网格布局
grid-template-columns 属性定义每一列的列宽
grid-gap 属性定义网格布局中行与列之间间隙的尺寸,它是 grid-row-gap & grid-column-gap 属性的简写

其实起来非常简单,且代码简明,请见如下代码 👇

.container {
    width: 400px;
    border: 1px solid #000;
    padding: 5px;
    display: grid;
    justify-content: space-between;
    grid-template-columns: repeat(auto-fill, 80px);
    grid-gap: 10px;
}

.item {
    width: 70px;
    height: 70px;
    margin: 10px;
    background-color: yellowgreen;
}

👇 效果如下(容器尺寸不变的情况下):

在这里插入图片描述

👇 效果2如下(容器尺寸变的情况下):

在这里插入图片描述

小结

综上可见,最后一行左对齐的布局需求更适合使用 CSS grid 布局来实现,但是,repeat() 函数兼容性有些要求,IE浏览器并不支持。如果项目需要兼容IE,则此方法有待商榷。

使用上面的提供的几种方案:动态计算margin、模拟两端对齐、根据列表的个数动态控制最后一个列表元素的margin值均可正确实现左对齐效果。

所有方案各有利弊,大家还得根据自己的实际场景,选择适合当前项目的合适的方法。

如果你有其他更好的实现解决方案,欢迎评论区留言讨论,大家一起学习进步~

希望上面的内容对你的工作学习有所帮助!欢迎各位一键三连哦~

Happy coding!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1409506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IDEA插件(MyBatis Log Free)

引言 在Java开发中&#xff0c;MyBatis 是一款广泛使用的持久层框架&#xff0c;它简化了SQL映射并提供了强大的数据访问能力。为了更好地调试和优化MyBatis应用中的SQL语句执行&#xff0c;一款名为 MyBatis Log Free 的 IntelliJ IDEA 插件应运而生。这款插件旨在帮助开发者…

P4769 [NOI2018] 冒泡排序 洛谷黑题题解附源码

[NOI2018] 冒泡排序 题目背景 请注意&#xff0c;题目中存在 n 0 n0 n0 的数据。 题目描述 最近&#xff0c;小 S 对冒泡排序产生了浓厚的兴趣。为了问题简单&#xff0c;小 S 只研究对 1 1 1 到 n n n 的排列的冒泡排序。 下面是对冒泡排序的算法描述。 输入&#x…

光环云与跨境智算云网实验室联合发布“数据全链路安全与合规解决方案”

1月19日&#xff0c;国际数据经济产业创新大会在上海临港新片区召开&#xff0c;光环云受邀出席。会上&#xff0c;光环云与“上海国际数据港创新实验室——跨境智算云网实验室”联合发布“数据全链路安全与合规解决方案”&#xff0c;助力企业数据跨境流动更加便捷、安全、高效…

数据结构之二叉树的遍历

数据结构是程序设计的重要基础&#xff0c;它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发&#xff0c;分析和研究计算机加工的数据的特性&#xff0c;以便为应用所涉及的数据选择适当的逻辑结构、存储结构及其相应的操作方法…

BPM、低代码和人工智能:实现灵活、创新与转型的关键结合

随着零售业格局的不断演变&#xff0c;零售商正被迫在一个日益活跃、竞争日益激烈的客户驱动型市场中展开竞争。随着互联网上产品信息和评论的出现&#xff0c;消费者的态度发生了巨大的变化——购物者不再依赖销售人员来获取信息。他们现在知道的和许多零售销售人员一样多&…

解决 BeanUtil.copyProperties 不同属性直接的复制

1、引入hutool <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version> </dependency> hutool官网 2、直接上例子 对象&#xff1a;User.java Data public class User {p…

一文了解Ceph原理以及常见ceph指令

一、Ceph介绍 什么是分布式存储&#xff1f; 与集中式存储相反&#xff0c;分布式存储通常采用存储单元集群的形式。并且具有在集群节点之间进行数据同步和协调的机制。其目的是为了通过服务器解决大规模&#xff0c;高并发情况下的Web访问问题。 Ceph是一个统一的、分布式的存…

2017年认证杯SPSSPRO杯数学建模D题(第二阶段)教室的合理设计全过程文档及程序

2017年认证杯SPSSPRO杯数学建模 D题 教室的合理设计 原题再现&#xff1a; 某培训机构租用了一块如图&#xff08;见附件&#xff09;所示的场地&#xff0c;由于该机构开设了多种门类的课程&#xff0c;所以需要将这块场地通过加入一些隔墙来分割为多个独立的教室和活动区。…

数据目录驱动测试——深入探讨Pytest插件 pytest-datadir

在软件测试中,有效管理测试数据对于编写全面的测试用例至关重要。Pytest插件 pytest-datadir 提供了一种优雅的解决方案,使得数据目录驱动测试变得更加简单而灵活。本文将深入介绍 pytest-datadir 插件的基本用法和实际案例,助你更好地组织和利用测试数据。 什么是pytest-da…

分布式锁实现(mysql,以及redis)以及分布式的概念(续)redsync包使用

道生一&#xff0c;一生二&#xff0c;二生三&#xff0c;三生万物 这张尽量结合上一章进行使用&#xff1a;上一章 这章主要是讲如何通过redis实现分布式锁的 redis实现 这里我用redis去实现&#xff1a; 技术&#xff1a;golang&#xff0c;redis&#xff0c;数据结构 …

github 推送报错 ssh: connect to host github.com port 22: Connection timed out 解决

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

未来已来:概念车展漫游可视化的震撼之旅

随着科技的飞速发展&#xff0c;汽车行业正经历着前所未有的变革。而在这场变革中&#xff0c;概念车展无疑是一个引领潮流、展望未来的重要舞台。 想象一下&#xff0c;你站在一个巨大的展厅中&#xff0c;四周陈列着各式各样的概念车。它们有的造型独特&#xff0c;有的功能先…

[BJDCTF2020]ZJCTF,不过如此(特详解)

php特性 1.先看代码&#xff0c;提示了next.php&#xff0c;绕过题目的要求去回显next.php 2.可以看到要求存在text内容而且text内容强等于后面的字符串&#xff0c;而且先通过这个if才能执行下面的file参数。 3.看到用的是file_get_contents()函数打开text。想到用data://协…

真心话大冒险!关于自动驾驶的现状和未来,Mobileye的回答是?

过去的十年&#xff0c;可以说是从主动安全、辅助驾驶到自动驾驶快速演进的周期。这其中&#xff0c;无论是技术迭代&#xff0c;还是成本优化&#xff0c;以及技术和商业化路线的争论&#xff0c;备受行业关注。 同时&#xff0c;市场上的声音&#xff0c;也很多。有激进、谨慎…

详细Nginx和PHP-FPM的进程间通信使用

工作中考虑到PHP-FPM效率&#xff0c;发现PHP-FPM和NGINX的进程通信不止配置端口这一种方式:bowtie: Nginx和PHP-FPM的进程间通信有两种方式,一种是TCP,一种是UNIX Domain Socket. 其中TCP是IP加端口,可以跨服务器.而UNIX Domain Socket不经过网络,只能用于Nginx跟PHP-FPM都在同…

基于YOLOv8的摔倒行为检测系统(Python源码+Pyqt6界面+数据集)

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文主要内容:通过实战基于YOLOv8的摔倒行为检测算法&#xff0c;从数据集制作到模型训练&#xff0c;最后设计成为检测UI界面 人体行为分析AI算法&#xff0c;是一种利用人工智能技术对人体行为进行检测、跟踪和分析的方法。通过计算…

linux基础指令【中篇】

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 补充上篇的细节1.sta…

C#~Winform代码调整快捷键

右移 选中要移动的代码 -> Tab 结果&#xff1a; 左移 选中要移动的代码 -> ShiftTab 结果&#xff1a; 自动调整 选中需要调整的代码 -> CtrlKD 调整后&#xff1a;

论文解读--Wideband 120 GHz to 140 GHz MIMO Radar:System Design and Imaging Results

120~140GHz宽带MIMO雷达&#xff1a;系统设计和成像结果 摘要 本文提出了一种工作频率在120 GHz ~ 140 GHz之间的宽带FMCW MIMO雷达传感器。该传感器基于SiGe技术制造的雷达芯片组&#xff0c;并使用MIMO方法来提高角度分辨率。MIMO操作通过发射机的时域复用实现。该雷达能够通…

[蓝桥杯]真题讲解:冶炼金属(暴力+二分)

蓝桥杯真题视频讲解&#xff1a;冶炼金属&#xff08;暴力做法与二分做法&#xff09; 一、视频讲解二、暴力代码三、正解代码 一、视频讲解 视频讲解 二、暴力代码 //暴力代码 #include<bits/stdc.h> #define endl \n #define deb(x) cout << #x << &qu…