需求
我们在做web页面的时候,经常会有一些图片列表,例如下图的视频列表以及表情列表:
需求要求:
1. 列表是responsive的,在不同宽度的浏览器下面,图片要自适应容器宽度
2. 图片在自适应的过程中,图片的长宽比要保持不变
常规解决方案
在container宽度固定的需求中(比如PC版页面),我们直接设置图片容器或者图片为固定的宽高就好了,比如:
1 img{ 2 width:330px; 3 height:180px; 4 }
但是这个不能满足需求,为了满足上面的需求两点,通常我们会想到通过设置图片的宽度为百分比来满足第1点,不设置高度来满足到第2点(容器的height不能根据width设置百分比),简单代码如下:
1 ul{ 2 list-style:none; 3 } 4 ul li{ 5 float:left; 6 width:100%; 7 padding:5px; 8 } 9 ul li img{ 10 width:100%; 11 }
视频时间的代码就不写出来了,通过绝对定位来做即可。
存在的问题
上面的解决方案虽然可行,但是条件又点苛刻,并且体验不好,为什么呢?
1. 为了做到完美显示,运营同学在配置图片的时候必须做到图片的长宽比完全一致,不能有一个像素的差别,否则会出现如下图情况:
上图中第一张图比其他三张图高一个像素,由于不能设置图片容器的高度,所以对图片大小就必须要严格控制。
2. 体验不好。当网络不佳,图片还没有加载出来的情况下,你可能看到如下图:
由于图片没有加载出来,图片没有占位,当图片加载出来后,再把容器撑高,这样的体验非常不好(特别是图片内容在首屏的时候)。
有人可能会说,使用默认图片来占位,但是有时候,在网络情况恶劣的情况下,默认图片都可能加载不出来。
优化方案
为了解决上面两个存在的问题,我想到了一种使用图片容器进行占位的方法。首先我们要了解一个css的知识点,块级元素(如div,p)的padding设置为百分比的时候,是按照容器的宽度来定的,那么我们可以按照图片的比例来设置容器的高度(使用padding-top/padding-bottom),图片则使用绝对定位显示在容器的下层。
html:
1 <div class="section-video"> 2 <ul class="list"> 3 <li> 4 <a href="https://www.youtube.com/embed/vCS_Nl4R9W8"> 5 <div class="img"> 6 <img class="" src="http://down2.9apps.com:7080/group1/M00/76/E4/pYYBAFdlMBaAAKvkAAA0HBzaV9E798.jpg" alt="logo"> 7 <span class="time">07:12</span> 8 </div> 9 <span class="title">ЕВРО 2016 - ЖЕСТЬ! ТРЕНЕР СБОРНОЙ ГЕРМАНИИ ОПОЗОРИЛСЯ НА ВЕСЬ МИР</span> 10 </a> 11 </li> 12 <li> 13 <a href="https://www.youtube.com/embed/8H2VfEO4n1k"> 14 <div class="img"> 15 <img class="" src="http://down2.9apps.com:7080/group1/M00/B0/71/qIYBAFdlMBWARAEqAAArw8xAvK8090.jpg" alt="logo"> 16 <span class="time">04:58</span> 17 </div> 18 <span class="title">ЧЕХИЯ - ХОРВАТИЯ 2:2 ОБЗОР МАТЧА </span> 19 </a> 20 </li> 21 <li> 22 <a href="https://www.youtube.com/embed/R5kRrJuolak"> 23 <div class="img"> 24 <img class="" src="http://down2.9apps.com:7080/group1/M01/76/E4/poYBAFdlMBmAKGmxAAA7r722CEs285.jpg" alt="logo"> 25 <span class="time">03:54</span> 26 </div> 27 <span class="title">ИСПАНИЯ - ТУРЦИЯ 3:0 ОБЗОР МАТЧА </span> 28 </a> 29 </li> 30 <li> 31 <a href="https://www.youtube.com/embed/zjKbunbkU78"> 32 <div class="img"> 33 <img class="" src="http://down2.9apps.com:7080/group1/M00/76/E4/pYYBAFdlMBuAO13wAAA-uPs5iqo997.jpg" alt="logo"> 34 <span class="time">03:14</span> 35 </div> 36 <span class="title">ИТАЛИЯ - ШВЕЦИЯ 1:0 ОБЗОР </span> 37 </a> 38 </li> 39 </ul> 40 </div>
css:
1 * { 2 box-sizing: border-box; 3 } 4 5 .section-video ul.list { 6 padding: 5px; 7 width: 100%; 8 font-size: 12px; 9 background-color: #0363b5; 10 list-style: none; 11 overflow: hidden; 12 } 13 14 .section-video ul.list li { 15 display: inline-block; 16 width: 50%; 17 padding: 5px; 18 float: left 19 } 20 21 .section-video ul.list li a { 22 display: block; 23 width: 100%; 24 color: #fff; 25 text-decoration: none; 26 } 27 28 .section-video ul.list li .img { 29 width: 100%; 30 position: relative; // 使用相对定位 31 height: 0; // 高度设置为0,使用padding来设置高度 32 overflow: hidden; 33 padding-bottom: 54.545454%; // 使用padding-top也可,使用padding来撑高容器,高度为宽度的 54.545454% 34 } 35 36 .section-video ul.list li .img img { 37 position: absolute; // 使用绝对定位 38 width: 100%; // 宽高为容器的宽高 39 height: 100%; 40 top: 0; 41 left: 0 42 } 43 44 .section-video ul.list li .img .time { 45 position: absolute; 46 display: inline-block; 47 right: 0; 48 bottom: 15px; 49 font-size: 12px; 50 line-height: 18px; 51 background-color: rgba(0, 0, 0, .48); 52 border-top-left-radius: 8px; 53 border-bottom-left-radius: 8px; 54 padding: 0 10px 55 } 56 57 .section-video ul.list li .title { 58 display: block; 59 line-height: 18px; 60 padding: 4px 0; 61 height: 40px; 62 overflow: hidden; 63 text-overflow: ellipsis 64 }
这种情况及时配置的图片有点小误差,我们也可以忽略。
使用优化方案后,当图片加载不出来的时候,容器的位置不会消失,如下图:
那么对于体验上来说,整个页面不会在图片加载的时候出现撑高的情况。
解决方案代码演示:https://jsfiddle.net/boxiang_hbx/wrf4xshn/3/
当前两张图没有load出来的时候,代码演示:https://jsfiddle.net/boxiang_hbx/wrf4xshn/4/
改优化方案可以巧妙地用于其他布局的地方,不限于图片,有问题,欢迎讨论!
尊重版权,转载请说明出处!