最近在做一个类似于京东商城首页 banner 图下面分类图标展示效果, 一行四个,分两行展示. 通常情况下如果数量固定,本来是很简单的flex布局即可搞定。却高的很麻烦。
jd 使用了float属性 来布局。
实际UI效果要求(不上图了,涉及公司隐私)
- 每行最多四个,四个元素,中间距离一样,两端对齐,就是
justify-content:space-between
效果,
- 数量不固定, 可能是 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
| * { 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
| .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> </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> </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> </ul> </div>
|
第三种方式,配合 nth-child
选择器,不用考虑数量问题,任意都可以,保持两端左对齐,但是需要根据实际需求去调整 css 属性列数
即可。
对于容器两边距离固定, 又要保持子元素两端对齐的方式,也是一种解决方式。
如果你有更好的,欢迎交流