效果:
原理:
1.利用css的自定义变量以及var函数
2.css里0除以0的结果是null,而且css运算式中只要出现null的结果就一定是null
缺点:
1.给定网格之间的间隙大小=m时,头尾的网格和中间的网格尺寸差1/4m(如果等分数为3,那么会差1/2m)
2.本人是在vue项目里使用,很方便,当然我还是更推荐使用第三方网格插件
3.兼容性未知
CSS:
<!-- 父元素 -->
.qiuGrid {
position: relative;
<!-- 父元素默认3行3列,间隔15px,通过style属性修改 -->
--num-w: 3;
--num-h: 3;
--pad-around: 15px;
}
<!-- 子元素 -->
.qiuGrid .grid-each {
<!-- 改子元素占用的左上点和右下点位置 -->
--pos1-x: 0;
--pos1-y: 0;
--pos2-x: 1;
--pos2-y: 0;
position: absolute;
left: calc(100% / var(--num-w) * var(--pos1-x));
top: calc(100% / var(--num-h) * var(--pos1-y));
width: calc(100% / var(--num-w) * (var(--pos2-x) - var(--pos1-x) + 1));
height: calc(100% / var(--num-h) * (var(--pos2-y) - var(--pos1-y) + 1));
box-sizing: border-box;
padding-left: calc((var(--pos1-x) / var(--pos1-x)) * (var(--pad-around) / 2));
padding-top: calc((var(--pos1-y) / var(--pos1-y)) * (var(--pad-around) / 2));
padding-right: calc(((var(--num-w) - 1 - var(--pos2-x)) / (var(--num-w) - 1 - var(--pos2-x))) * (var(--pad-around) / 2));
padding-bottom: calc(((var(--num-h) - 1 - var(--pos2-y)) / (var(--num-h) - 1 - var(--pos2-y))) * (var(--pad-around) / 2));
}
使用例子:
下面的代码关心带qiuGrid的父元素和带grid-each的子元素就好了
顺嘴一提,下面这几个是为了在不同尺寸的电脑上不至于发生宽高比变化给的样式:
--ratio: 设置盒子宽高比
qiu-fix-ratio-shell:固定盒子宽高比的父盒子样式
qiu-fix-ratio-box:固定盒子宽高比的子盒子样式
<!-- 下面的代码关心带qiuGrid的父元素和带grid-each的子元素就好了 -->
<!--
--ratio: 设置盒子宽高比
qiu-fix-ratio-shell:固定盒子宽高比的父盒子样式
qiu-fix-ratio-box:固定盒子宽高比的子盒子样式
-->
<template>
<div class="box">
<div class="page-w">
<div class="head">
<Header></Header>
</div>
<div class="main">
<div :style="{'--ratio': 2/5}" class="col qiu-fix-ratio-shell">
<div class="qiu-fix-ratio-box">
<div class="list qiuGrid" :style="displaySize">
<div :style="setPosStyle(displayLine1)[0]" class="item grid-each classification">
<div class="item-box">
<div class="classification-list no-scrollbar">
<div :class="{'active':activeIndex==index}" @click="activeIndex=index" v-for="(site,index) in classificationList" class="classification-item">{{site}}</div>
</div>
</div>
</div>
<div v-if="activeIndex>=0" :style="setPosStyle(displayLine1)[n]" class="item grid-each" v-for="n in 5">
<router-link tag="div" :to="{ name: 'ProductDetail' }" class="item-box">
<img class="image" src="../Home/image/test_product.png" alt="">
</router-link>
</div>
<div v-if="activeIndex<0" :style="setPosStyle(displayLine1_adv)[1]" class="item grid-each">
<router-link tag="div" :to="{ name: 'ProductDetail' }" class="item-box">
<img class="image" src="../Home/image/test_product.png" alt="">
</router-link>
</div>
</div>
</div>
</div>
<div v-for="n in 3" :style="{'--ratio': 2/5}" class="col qiu-fix-ratio-shell">
<div class="qiu-fix-ratio-box">
<div class="list qiuGrid" :style="displaySize">
<div :style="setPosStyle(displayLine2[n%2])[m-1]" class="item grid-each" v-for="m in 7">
<router-link tag="div" :to="{ name: 'ProductDetail' }" class="item-box">
<img class="image" src="../Home/image/test_product.png" alt="">
</router-link>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<!-- 邱的私用样式 -->
<style scoped src="@/assets/styles/qiu.css"></style>
<script>
export default {
data () {
return {
//网格划分
displaySize: {
'--num-w':5,
'--num-h':2,
'--pad-around': '30px'
},
//显示广告的布局
displayLine1_adv: [
[0,0,0,1],
[1,0,4,1]
],
//不显示广告的布局
displayLine1: [
[0,0,0,1],
[1,0,1,0],
[2,0,2,0],
[1,1,1,1],
[2,1,2,1],
[3,0,4,1],
],
//第二行开始的布局
displayLine2: [
[
[0,0,0,0],
[0,1,0,1],
[1,0,1,0],
[1,1,1,1],
[2,0,2,0],
[2,1,2,1],
[3,0,4,1],
],
[
[0,0,1,1],
[2,0,2,0],
[2,1,2,1],
[3,0,3,0],
[4,0,4,0],
[3,1,3,1],
[4,1,4,1],
]
],
//是否选中了分类
classificationList: [
"米食",
"雜糧",
"乾貨",
"麵食",
"飲品/沖泡",
"休閒食品",
"食材醬料",
"茶",
"低溫生鮮",
],
}
}
}
</script>
<style lang="less" scoped>
.main {
.col {
margin-bottom: 30px;
.list {
width: 100%;
height: 100%;
.item-box {
height: 100%;
background-color: #fff;
box-sizing: border-box;
border-radius: 10px;
overflow: hidden;
cursor: pointer;
.image {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.classification {
.item-box {
border-radius: 3px;
padding: 20px 0px;
box-sizing: border-box;
.classification-list {
height: 100%;
overflow: auto;
.classification-item {
padding: 0px 20px;
font-size: 25px;
line-height: 50px;
color: #000;
cursor: pointer;
box-sizing: border-box;
}
.classification-item.active,.classification-item:hover {
background-color: rgba(153,221,211,0.5);
}
}
}
}
}
}
}
</style>
优点:
仅仅提供一个css使用的新思路,特别是远离里的第2点,我是觉得挺好用的。
为什么不用弹性盒子:
主要看上面的效果图,用弹性盒子实现的话,我需要再加一层子盒子(父+子+子)(ps:可能是我水平不够,想不到啥更好的方法),在第三层添加padding属性来实现间距。但是头尾的padding值还是不一样,也就是还是要通过上面的原理2来实现。
当然,如果只是等分并固定死了子盒子的大小,那当我没说,弹性盒子还是好用的很。
PS:
1.还是推荐使用第三方的网格插件,虽然我没用过,但是总比我这好。
2.如果觉得我的这方案太麻烦了,有啥好方法的,麻烦私信或评论告诉我,么么哒😙。
3.如果对那个固定宽高比有兴趣或者有更好方法的也麻烦私信告诉我