问题的产生
使用Flex布局,设置justify-content: space-between;
让元素在主轴上两队对齐。
<div class="box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
</div>
.box {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
width: 500px;
border: 1px solid red;
}
.item {
width: 120px;
height: 100px;
margin-bottom: 10px;
background-color: aquamarine;
}
假如一行显示4个元素,最后一行在不够4个元素的时候,按照两端对齐显示,效果显得不好,我们希望假如最后一行不足4个元素的时候,默认从左向右排列。
解决方法
这个问题有很多的解决方法,先说最简单也是最常用,兼容性最好的一种。
1. 使用i
或者span
补齐
假如我们这里一行最多显示4个元素,我们就再列表项的末尾补充4个i
元素。
<div class="box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<!-- 补充4个i元素 -->
<i></i><i></i><i></i><i></i>
</div>
同时设置css
样式:
.box {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
width: 500px;
border: 1px solid red;
}
.item {
width: 120px;
height: 100px;
margin-bottom: 10px;
background-color: aquamarine;
}
/* 针对i元素的样式 */
.box i {
width: 120px;
height: 0;
}
显示效果为:
这种方式的原理是:
首先末尾的4
个元素宽度和列表项一致,但是高度为0
,我们先设置高度不为0
看下效果:
/* 针对i元素的样式 */
.box i {
width: 120px;
height: 30px;
background-color: brown;
}
四个元素其中一个充当了之前最后一行的末尾元素,剩下的3个元素按照两端对齐,显示在下一行,此时高度设置为0
,元素不显示,也不会多占据一行,但是可以在主轴方向上填补之前的空白区域。
为什么需要4个,当然是为了考虑到最后一行可能剩2,3的情况。
如果最后一行剩一个元素,默认会左对齐,如果剩4个元素,那就是正好两端对齐,所以我们需要考虑的就是剩2个或者3个的情况,但是为了统一,直接放置4个在末尾,高度为0,也不会占据高度,只是会额外的创建html
元素。
2. 使用Css选择器
还是使用flex
布局,使用justify-content: space-between;
,不额外创建html元素。我们假设一行只显示4个元素,根据上一节,我们只需要考虑处理剩2个或者3个元素的情况。
这里我们的每个列表项的宽度使用%
单位、
<div class="box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
</div>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
list-style: none;
}
.box {
width: 500px;
/* 父元素设置高度,子元素会默认拉伸 */
display: flex;
flex-wrap: wrap;
justify-content: space-between;
background-color: lightslategray;
}
.item {
width: 24%;
height: 100px;
margin-bottom: 5px;
background-color: bisque;
}
我们通过css选择器,选中最后一个元素,设置他的margin-right,
/*
一行4个元素,4n就是选中第4,8,12个元素...,n从0开始,
相当于选中每一行的第4个,
但是我们要选中的是每一行的第3个,所以就有了4n-1
但是考虑到只针对最后一行,就有了下面的选择器
是最后一个元素的同时 还是每一行中的第三个
*/
.item:last-child:nth-child(4n - 1) {
margin-right: calc(24% + 4% / 3);
}
宽度:由于每一个item元素没有设置margin,item宽度为24%,一行4个,就是96%,还剩4%的空白空间,这4%的空白空间平均分成了3分,才有了下面的间距
针对最后一行的最后一个元素即7号,它应该和3号元素对齐:
24%是一个元素的空间,再加上原本的间距
margin-right: calc(24% + 4% / 3);
同样针对剩2个元素的情况,可以有如下的选择器:
.item:last-child:nth-child(4n - 2) {
margin-right: calc(48% + 8% / 3);
}
6号和2号对齐,右侧的空间是24% * 2 + 4% / 3 * 2
,即48% + 8% / 3
所以我们有了下面的代码
<div class="box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
</div>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
list-style: none;
}
.box {
width: 500px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
background-color: lightslategray;
}
.item {
width: 24%;
height: 100px;
margin-bottom: 5px;
background-color: bisque;
}
.item:last-child:nth-child(4n - 2) {
margin-right: calc(48% + 8% / 3);
}
.item:last-child:nth-child(4n - 1) {
margin-right: calc(24% + 4% / 3);
}
不使用justify-content:space-between
在模拟两端对齐效果,中间的gap间隙我们使用margin
进行控制。
<div class="box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
</div>
.box {
display: flex;
flex-wrap: wrap;
width: 500px;
border: 1px solid red;
}
.item {
width: 120px;
height: 100px;
/*先统一设置mr*/
margin-right: calc(20px / 3);
margin-bottom: 10px;
background-color: aquamarine;
}
/*每行的最后一个不设置mr*/
.item:nth-child(4n) {
margin-right: 0;
}
或者直接选中除了每一行最后一个元素外的其他元素:
.item {
width: 120px;
height: 100px;
margin-bottom: 10px;
background-color: aquamarine;
}
/*选择每一行非第4个元素,设置外边距
但是外边距的值需要计算出来,或者使用%单位
*/
.item:not(:nth-child(4n)) {
margin-right: calc((500px - 120px * 4) / 3);
}
每一行的最后一个元素是没有外边距的
还有很多其他方法,或者使用grid
布局,最简单容易得应该就是在末尾补充元素,够用就行。