
前言:因为项目中使用flex过程中,如果采用
space-between两端对齐,会遇到最后一行难以对齐的问题。本文主要对多行多列这种常见的布局,列出解决方案,方便大家日常开发使用。
话不多说,直接进入正题:

方案一:标签补位
我们都知道,之所以对不齐是因为最后一行的子项目没有达到4个,space-between的对齐方式,自然会把中间空出来。既然如此,何不直接补位,让元素排满4个。
1<!-- 样式 --> 2<style> .list{ 3 display: flex; 4 justify-content: space-between; 5 flex-wrap: wrap; 6 } 7 .item{ 8 /* flex: 0 0 24% 该属性等价于 flex:none;width:24% */ 9 flex: 0 0 24%; 10 height: 100px; 11 background-color: aqua; 12 margin-bottom: 10px; 13 } 14 .item-fill{ 15 flex: 0 0 24%; 16 height:0; 17 } 18 /* 消除最后一行多余边距 */ 19 .list .item:nth-last-child(-n+4){ 20 margin-bottom: 0; 21 }</style> 22 23<!-- html --> 24<div class="list"> 25 <div class="item"></div> 26 <div class="item"></div> 27 <div class="item"></div> 28 <div class="item"></div> 29 <div class="item"></div> 30 <div class="item"></div> 31 32 <div class="item-fill"></div> 33 <div class="item-fill"></div> 34 <div class="item-fill"></div> 35</div> 36
效果如下:

如果子元素个数不是4个怎么办?我们细心观察,不难发现,最后一行的最小值是1个,那么我们只需要补位n-1个即可。如果只有3个,也可以用伪元素::after去补最后一个位置。
方案二:计算剩余空间
如果我们知道最后一行剩余空间的话,完全可以控制最后一个元素的边距或者缩放比例去占满剩下的空间,自然就能左对齐了。要做到这一点,首先得确定宽度和边距,宽度通常是已知的,我们只需要把边距确定下来,就能确认剩余空间。
接上面的的例子,假设一行有4个, 每个占比24%,4个就是24% * 4 = 96% , 那么可以确定总边距是4%,由于一行有4个元素,而最后一个的右边距是多余的,那么可以确定单个的边距为 4% / 3 = 1.333% , 计算出来后就可以开始写代码了:
1<!-- css --> 2<style> .list{ 3 display: flex; 4 justify-content: space-between; 5 flex-wrap: wrap; 6 } 7 .item{ 8 flex: 0 0 24%; 9 height: 100px; 10 background-color: aqua; 11 /* 边距懒得算,css函数代替 */ 12 margin-right: calc(4% / 3); 13 margin-bottom: calc(4% / 3); 14 } 15 /* 去除每行尾的多余边距 */ 16 .item:nth-child(4n){ 17 margin-right: 0; 18 } 19 /* 使最后一个元素的边距填满剩余空间 */ 20 .item:last-child{ 21 margin-right: auto; 22 } 23 /* 也可以给列表增加一个占位元素,自动缩放填满剩余空间 */ 24 /* .list::after{ 25 content: ''; 26 flex: 1; 27 height: 0; 28 } */ 29 .list .item:nth-last-child(-n+4){ 30 margin-bottom: 0; 31 }</style> 32<!-- html --> 33<div class="list"> 34 <div class="item"></div> 35 <div class="item"></div> 36 <div class="item"></div> 37 <div class="item"></div> 38 <div class="item"></div> 39 <div class="item"></div> 40</div> 41
效果如下:

可能有些小伙伴觉得懒得记,那么下面直接给出封装好的sass mixin, 复制即可使用:
1/** 2 * 多列布局 3 * $count 项目数量 4 * $itemWidth 项目宽度,百分比,不含百分号 5 * $itemHeight 项目高度,随意 6 */ 7@mixin grid($count:4, $itemWidth:20, $itemHeight:auto) { 8 $rest: 100 - $itemWidth * $count; // 剩余空间 9 $space: percentage($rest/($count - 1)/100); // 边距 10 display: flex; 11 flex-wrap: wrap; 12 13 /*此处的*号建议替换成具体的布局容器(div,view...),以加快css解析*/ 14 & > * { 15 flex: 0 0 #{$itemWidth + '%'}; 16 height: $itemHeight; 17 margin-right: $space; 18 margin-bottom: $space; 19 box-sizing: border-box; 20 21 &:nth-child(#{$count}n) { 22 margin-right: 0; 23 } 24 25 &:nth-last-child(-n + #{$count}) { 26 margin-bottom: 0; 27 } 28 29 /*为了兼容space-between的布局,占满剩余空间*/ 30 &:last-child { 31 margin-right: auto; 32 } 33 } 34} 35 36/*使用方法*/ 37.list{ 38 /* 一行4项,每项20%宽度 */ 39 @include grid(4,20) 40} 41
以上为flex版本,假如你需要兼容ie浏览器,那么可以用float布局替换,float自动左对齐,也就不需要填充最后的剩余空间了。
方案三:网格布局
网格布局,默认就是左对齐,即使使用space-between。
1<style> .list { 2 display: grid; 3 justify-content: space-between; 4 grid-template-columns: 1fr 1fr 1fr 1fr; /*设置等比列*/ 5 gap: 10px; /*行间距*/ 6 } 7 .item{ 8 background-color: aqua; 9 height: 100px; 10 }</style> 11 12<!-- html --> 13<div class="list"> 14 <div class="item"></div> 15 <div class="item"></div> 16 <div class="item"></div> 17 <div class="item"></div> 18 <div class="item"></div> 19 <div class="item"></div> 20</div> 21
效果如下:

上面的三个方案各有各的好处:
-
方案一的缺点是实现不够优雅,需要增加无用的占位标签。
-
方案二倒没什么缺点,除了写法会复杂点,但只要封装好mixin在sass中使用足够简单,即使需要兼容ie,也只需要换成float即可。
-
方案三,兼容性最差,无法在ie中正常使用,但用法最简单,布局甚至比flex还要强大。
综上,实际使用中,还是推荐使用方案二。
欢迎关注我的公众号「前端历劫之路」
回复关键词「电子书」,即可获取近12本前端热门电子书。
回复关键词「红宝书第4版」,即可获取最新《JavaScript高级程序设计》(第四版)电子书。
你还可以加我微信,我拉拢了很多IT大佬,创建了一个技术交流、文章分享群,欢迎你的加入。
作者:Vam的金豆之路
主要领域:前端开发
我的微信:maomin9761
微信公众号:前端历劫之路
本文转转自微信公众号前端历劫之路原创https://mp.weixin.qq.com/s/WlTru34oqM9QJJaV7CRSWQ,如有侵权,请联系删除。

