在开发项目的时候遇到了以下几点需要解决的问题条件:
1.子元素个数不固定
2.父元素宽度不固定
3.子元素自动换行,并且自动撑满一行,但是并不改变子元素的宽度(即元素从最左分布到最右边,注:忽略padding和margin)
先来效果图(请忽略打码):
在解决的时候就想到了使用flex布局中的justify-content属性的space-between,但是当我应用上去的时候发现问题并没有得到解决,效果如下图:
可以看到当元素不够填满一行的时候,space-between会将剩余的空隙平均分成元素个数x - 1份然后进行布局,并不是我们想象中的从左到右排列。
解决的思路:如果子元素个数不够填满一行,则在该行的末尾添加缺少元素个数的空块进行填充即可,代码如下(基于vue):
计算方法如下(300为子元素的宽度,也可自适应宽度):
// 解决space-between布局的问题,添加div填充空位
reCalcPaddingLength () {
let outerLength = this.$refs.listContainer.clientWidth // 外面div的宽度
let listLen = 6 // 子元素总个数,自己调整即可
let lineCapacity = Math.floor(outerLength / 300)
this.paddingLength = listLen % lineCapacity === 0 ? 0 : (lineCapacity - listLen % lineCapacity)
}
调用该方法(需要特别注意的是当页面大小重置的时候,需要重新计算进行填充):
mounted: function () {
let self = this
this.reCalcPaddingLength()
window.onresize = function () { // 如果页面大小变化,也要重新计算
self.reCalcPaddingLength()
}
}
页面js代码:
export default {
data () {
return {
paddingLength: 0
}
},
mounted: function () {
let self = this
this.reCalcPaddingLength()
window.onresize = function () {
self.reCalcPaddingLength()
}
},
methods: {
// 解决space-between布局的问题,添加div填充空位
reCalcPaddingLength () {
let outerLength = this.$refs.listContainer.clientWidth // 外面div的宽度
let listLen = 6 // 子元素个数,自行调整
let lineCapacity = Math.floor(outerLength / 300) // 计算每一行的容量
this.paddingLength = listLen % lineCapacity === 0 ? 0 : (lineCapacity - listLen % lineCapacity) // 得出需要添加的空块
}
}
}
HTML代码:
<div class="kg-list-container" ref="listContainer">
<div v-for="item in 6" class="list-item">
<p class="kg-background"></p>
<p class="item-title">title</p>
</div>
<div v-for="item in paddingLength" class="list-item">
</div>
</div>
CSS代码:
.kg-list-container {
margin-top: 20px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.list-item {
margin: 0px 0px 40px 0px;
width: 300px;
height: 220px;
border: solid 1px inherit;
border-radius: 10px;
overflow:hidden;
}
.kg-background {
background: black;
height: 180px;
margin: 0px;
}
.list-item {
width: 300px;
height: 220px;
}