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

27 篇文章 4 订阅
2 篇文章 0 订阅


前言

在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!

  • 32
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
flex布局中,实现两端对齐的方法有多种。其中一种方式是使用justify-content属性。这个属性可以控制flex容器中的项目在主轴上的对齐方式。通过设置justify-content为space-between,项目会平均分布在主轴上,使得第一个项目与容器的起始端对齐,最后一个项目与容器的结束端对齐,并且项目之间的间距相等。这种方式简单、高效且易于使用。 另一种方式是使用nth-child选择器,结合flex布局实现。通过设置每个项目的margin-right属性来控制项目之间的间距。在第一行中的项目不需要设置右外边距,而其他行中的项目需要设置右外边距。这样就可以实现两端对齐的效果。这种方式需要根据每行的项目数量来调整样式代码,并且在不同屏幕分辨率下可能需要编写多套样式代码来适应不同的情况。 总结起来,使用justify-content属性可以简单地实现flex布局的两端对齐效果,而使用nth-child选择器需要根据项目数量进行调整,并且在不同分辨率下可能需要编写多套样式代码。具体选择哪种方式取决于具体的需求和使用场景。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [flex布局优化(两端对齐,从左至右)](https://blog.csdn.net/glorydx/article/details/129661681)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [flex布局 justify-content 解决最后一排数量不够自动向两端排列问题.doc](https://download.csdn.net/download/qq_34776972/12246011)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值