做项目的时候需要用到横向瀑布流布局,在实现的过程中还遇到了object-fit兼容性问题,这里记录一下整个过程,想直接复制代码可以直接滚到底部。
在此先上个效果图:
(希望不要吐槽里面的小哥哥)下面正题:
用的框架是vue,v-for一下:
<section> // v-for就是根据imagesList数组去循环下面这个div部分。 <div class="img-wrapper" v-for="(item, index) in imagesList" :key="index"> <img class="img" :src="item.img" /> <div class="info"> <span class="size">helloworld</span> </div> </div> </section>
重点css来了朋友们(这里是scss):
section { display: flex; // 这里用到flex布局 flex-wrap: wrap; // flex中换行的属性 padding: 15px 5px; &::after{ // 用于最后一行最后的位置显示空白 content: ''; flex-grow: 99999;// 放到最大 } .img-wrapper { flex-grow: 1; // 根据比例计算每个图片多长等分剩余空间(好难解释,下面用图解释) margin: 5px; position: relative; overflow: hidden; // 把多余的部分隐藏 .img { height: 170px; min-width: 100%; // 要让左右的图片横向是充满他父级标签的宽度 object-fit: cover; // 让图片不要压缩 } .info{ // 选中时底部提示框 position: absolute; bottom: 4px; color: #ffffff; left: 0; right: 0; background-color: rgba(0,0,0,.3); line-height: 44px; height: 0px; }&:hover .info{ // 选中时底部弹出提示框动画 height: 44px; transition: all 0.5s; } } }
上面是所有代码,复制粘贴可以用啦(注意注意:这个方案存在兼容性问题,ie等一些浏览器不支持object-fit属性),下面做简单解析:
注意:这种方法没用到js的计算,所以有一个缺点 就是有一些图片他其实是有缺失的,
原图:
被迫部分缺失的:
一、此处用到了flex布局:
先了解一波flex,阮一峰老师的flex布局教程(http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html?%5E%25$)
flex-wrap: wrap;
flex-wrap属性定义,如果一条轴线排不下,如何换行
wrap值即是:换行,第一行在上方。
根据比例计算每个图片多长等分剩余空间:
flex-grow: 1;
flex-grow属性定义项目的放大比例,如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。
如果在本项目中撤去这个属性,效果就会像下面这样:
所以这个flex-grow属性是为了等分剩余空间。
二、min-width:100%
这里提一下这个属性的重要性之处,
min-width: 100%; // 要让左右的图片横向是充满他父级标签的宽度
如果这条缺少会呈现这种效果,虽然其父级标签是等分了剩余空间,但是图片的横向没有充满父级标签,所以在这里我们需要用到这个属性来使其充满。
三、object-fit: cover
在上面的充满以后 有些图片是会被压缩的,所要要用到这个属性,保持原有尺寸比例。保证替换内容尺寸一定大于容器尺寸,宽度和高度至少有一个和容器一致。因此,此参数可能会让替换内容(如图片)部分区域不可见。
object-fit: cover; // 让图片不要压缩
如果这条缺少会呈现这种效果,这里是张鑫旭老师一篇关于object-fit的文章(https://www.zhangxinxu.com/wordpress/2015/03/css3-object-position-object-fit/)
这里要注意!!!!!object-fit有部分的浏览器是不兼容他的!!
解决object-fit兼容性问题
两个方案:
1、张鑫旭老师给出了一个决绝这问题的插件,github链接:https://github.com/anselmh/object-fit
2、但我在vue里面使用这个方法没有达到效果,最后我做出使用background-size和background-position替换object-fit:
<section> <div class="img-wrapper" v-for="(item, index) in imagesList" :key="index" @click="clickImage(index)"> <div class="img" :style="'backgroundImage: url('+item.img+');'">// 在这里控制背景图片 <img :src="item.img" alt="" srcset=""> </div> …… </div> </section>
在这里再图片外面加一个div包住它,css改动如下:
.img { // object-fit: cover; background-size: cover; // background-size和background-position替换object-fit background-position: center; img { // 设置本来的img透明,使其显示出来的只是背景,但注意不能把img的src去掉,去掉的话flex-grow就无法等分剩余空间了。 opacity: 0; min-width: 100%; height: 210px; } }
有一个原则:能使用html/css解决的问题就不要使用JS,希望文章能帮助各位解决问题!
重要的几个属性都解释完了,其他的自己领悟哈,妹子喜欢小哥哥希望别介意 ^-^
最后完整代码
不存在兼容性问题的代码如下:
HTML:
<section> <div class="img-wrapper" v-for="(item, index) in imagesList" :key="index" @click="clickImage(index)"> <div class="img" :style="'backgroundImage: url('+item.img+');'"> img :src="item.img" alt="" srcset=""> </div> <div class="info"> <span class="size">500×300</span> <img src="@/assets/images/photoes/save.png" alt="" srcset=""> </div> </div> </section>
css(scss):
section { display: flex; flex-wrap: wrap; padding: 15px 5px; &::after { content: ""; flex-grow: 99999; } .img-wrapper { flex-grow: 1; margin: 5px; position: relative; overflow: hidden; height: 210px; .img { // object-fit: cover; background-size: cover; background-position: center; img { opacity: 0; min-width: 100%; height: 210px; } } .info { position: absolute; bottom: 0px; color: #ffffff; left: 0; right: 0; background-color: rgba(0, 0, 0, 0.3); line-height: 44px; height: 0px; } &:hover .info { height: 44px; transition: all 0.5s; } } }
更多web前端相关知识,请查阅 HTML中文网 !!