flex布局应用案例-左对齐

最近在做一个类似于京东商城首页 banner 图下面分类图标展示效果, 一行四个,分两行展示. 通常情况下如果数量固定,本来是很简单的flex布局即可搞定。却高的很麻烦。

jd 使用了float属性 来布局。

实际UI效果要求(不上图了,涉及公司隐私)

  1. 每行最多四个,四个元素,中间距离一样,两端对齐,就是 justify-content:space-between 效果,
  2. 数量不固定, 可能是 1 - 12个。例如:只有两个的时候, 也要保持两端对齐的情况下,前两个元素同样的位置

使用flex布局, 不考虑两端对齐

这个是最常见的情况,使用 flex布局, 子元素固定宽度之后,会自动平铺换行。但是这种不一定会符合UI,也就是说,无法两端对齐。 对于不需要两端对齐的情况下,非常方便。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/* 公共css */
* {
margin: 0;
padding: 0;
}
ul,
li {
list-style: none;
}

.page {
padding: 0 20px;
}

.page h5{
margin-top: 10px;
margin-bottom: 10px;
}

.wrap {
background-color: #f3f4f8;
border-radius: 7px;
margin-bottom: 18px;
padding-bottom: 20px;
}

.icon {
width: 27px;
height: 27px;
object-fit: cover;
line-height: 0;
font-size: 0;
}
.name {
font-size: 12px;
font-weight: 500;
margin-top: 10px;
}

.item {
text-align: center;
margin-top: 20px;
}
1
2
3
4
5
6
7
8
9
/* 第一种方式 v1 */
.list {
display: flex;
flex-wrap: wrap;
}

.list .item {
flex: 0 0 25%;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div class="page">
<div class="wrap">
<ul class="list">
<li class="item">
<img
src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg"
class="icon">
<p class="name">
测试
</p>
</li>
<!-- 省略其余7个 li -->
</ul>
</div>
</div>

效果图:

问题点:容器两侧保留空间太大,与UI不符合,

使用flex ,两端对齐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 第二种方式 */
.list2 {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}

.list2 .item {
flex: 0 0 25%;
}
.list2 .item-inner{
width: 30px;
margin: 0 auto;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="wrap">
<ul class="list2">
<li class="item">
<div class="item-inner">
<img src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" class="icon">
<p class="name">
测试
</p>
</div>
</li>
<!-- 省略其余7个 li -->
</ul>
</div>

方式2中,多了一层div,效果和1 一样,但是 方式2 有一个弊端: 如果数量无法保持 4n 的话,最后一行就无法左对齐。也没有实现两端对齐。

flex 动态计算 marginleft

这个是看完 软老师 博客学习,一般很少使用calc这个属性,相比较性能差点。而且做的大部分功能偏后台的,不太用得着。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.list3 {
display: flex;
flex-wrap: wrap;
padding: 0 22px;
}

.list3 .item {
flex: 0 0 30px;
}
.list3 .item:nth-child(4n+1) {
margin-left: 0;
}
.list3 .item:not(:nth-child(4n+1)) {
margin-left: calc((100% - 120px) / 3);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="wrap">
<ul class="list3">
<li class="item">
<div class="item-inner">
<img src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" class="icon">
<p class="name">
测试
</p>
</div>
</li>
<!-- 省略其余7个 li -->
</ul>
</div>

第三种方式,配合 nth-child 选择器,不用考虑数量问题,任意都可以,保持两端左对齐,但是需要根据实际需求去调整 css 属性列数 即可。

对于容器两边距离固定, 又要保持子元素两端对齐的方式,也是一种解决方式。

如果你有更好的,欢迎交流

作者

Fat Dong

发布于

2023-04-06

更新于

2023-04-06

许可协议