假设:有一个产品展示模块,图片尺寸为
200 * 200
,所以你把宽度与高度设置为固定值
200px
<style>
div { width: 200px; height: 200px; border: 10px solid #000; margin: 10px; float: left; }
img { width: 100%; height: 100%; }
</style>
<div><img src="images/350a8f0c766f5460.png" alt=""></div>
<div><img src="images/350a8f0c766f5460.png" alt=""></div>
<div><img src="images/350a8f0c766f5460.png" alt=""></div>
</body>
有一天,客户上传了一张 3000 * 1000 的产品图:
网页效果图
“我靠,怎么搞的,把我产品图都挤成正方形了?!”客户生气的看着眼前的网页。
于是他找到了产品经理并大骂了他一顿。产品经理也找到了你,把你大骂了一顿。你愁眉苦脸的开始寻找解决办法:
既然上面是固定了宽度和高度才导致图片被严重挤压的,那我就不设置宽度和高度,让图片自适应呗!
你欢呼雀跃地敲起了代码:
<style>
div { width: auto; height: auto; border: 10px solid #000; float: left; margin: 10px; }
img { width: 100%; height: 100%; }
</style>
<div><img src="images/3000_1000.jpg" alt=""></div>
<div><img src="images/350a8f0c766f5460.png" alt=""></div>
<div><img src="images/350a8f0c766f5460.png" alt=""></div>
</body>
“不设置宽高的话,这一整个 div 都占了一整行啊”
“一行我可不止要放一个产品图,这可怎么办啊!”眼看着布局结构都被打乱,你开始焦虑起来。
“算了,继续固定吧,记得有个属性 object-fit:cover; 可以保持纵横比缩放图片。”
<style>
div { width: 200px; height: 200px; border: 10px solid #000; float: left; margin: 10px; }
img { width: 100%; height: 100%; object-fit:cover; }
</style>
<div><img src="images/3000_1000.jpg" alt=""></div>
<div><img src="images/350a8f0c766f5460.png" alt=""></div>
<div><img src="images/350a8f0c766f5460.png" alt=""></div>
</body>
反正就一张图片没看到完整内容,就这样吧!
几天后,产品经理又噼里啪啦数落了你一通,就像客户数落他那样:
“怎么回事,到了手机上看怎么成这鸟样了!给了你们这么长时间,连响应式都没有!再这样下去就没必要合作了!!”
“响应式……”,你低头沉思了一会,决定
将每个 div 宽度设置为25%,这样3个 div 都能容纳在一行里,div宽度还能随着视口宽度的变化而变化。
你美美的想着竟然笑出了声,连忙控制了一下面部表情。
<style>
div { width: 25%; height: 200px; border: 10px solid #000; float: left; margin: 10px; }
img { width: 100%; height: 100%; object-fit:cover; }
</style>
<div><img src="images/3000_1000.jpg" alt=""></div>
<div><img src="images/350a8f0c766f5460.png" alt=""></div>
<div><img src="images/350a8f0c766f5460.png" alt=""></div>
</body>
这下不用客户挑毛病,你也能看出来哪里不对劲了。虽然图片都没变形,但没有一张图片显示完整,你坐不住了。
“高度……高度!高度自适应一定能解决”,你双目怒睁望道。
<style>
div { width: 25%; height: auto; border: 10px solid #000; float: left; margin: 10px; }
img { width: 100%; height: 100%; object-fit:cover; }
</style>
<div><img src="images/3000_1000.jpg" alt=""></div>
<div><img src="images/350a8f0c766f5460.png" alt=""></div>
<div><img src="images/350a8f0c766f5460.png" alt=""></div>
</body>
“一行内比例差这么多。完了,这下彻底完了。”你心灰意冷地背起行李,决定提桶跑路。
忽然,脑子里突然有一个声音,似乎在远程指导你:
首先,我们得固定图片的比例,保证用户上传图片的宽高多奇葩 布局都不会变。
图片大小为 1013px * 776px
。先固定一个宽度为25%,宽度相对于父元素(body、html),这样无论视口宽度怎么变化,宽度永远是视口的25%。
接着,我们来计算高度的百分比。只要计算出宽度与px的换算比例,就能计算出高度。
宽度等于25%,那么就用 1013px / 25 = 40.52px
40.52像素等于1个百分比,那么776个像素呢?再用图片高度 776px / 40.52px = 19.15103652517275%(19.15%)取小数点两位足矣。
好了,我们得到 宽度 = 25%,高度 = 19.15%
你跟着迷迷糊糊地按下回车键:
~ 哦豁,忘记告诉你了。屏幕宽度会有变化,是因为不同设备之间的差距,但是高度却几乎不会有变化。
在电脑上:
宽度25% = 1013px像素,高度19.15% = 776像素(等比例)
在手机上:
宽度25% = 93.75px ( 375 / 100 = 3.75 * 25 = 93.75 )
高度19.15% = 127.73px ( 667 / 100 = 6.67 * 19.15 = 127.7305 )
别说等比例了,反比例都给整出来了。
通过高度百分比来达到图片等比例缩放效果,是不可能的!
那么有没有一种东西,能获取 元素宽度的变化 呢?我知道你想说JS,用这个 Api 获取那个 DOM ……但别急,还要更好的方法—— padding
平时我们都习惯了 padding 属性的单位 px 做各种各样的间距。可很少有人注意到:
padding的百分比单位是相对于父元素的宽度。
已知:father宽度300px
<style>
.container { width: 300px; height: auto; background: #bfa; }
</style>
<div class="father">
<div class="son"></div>
</div>
</body>
求:不固定高度如何能得到 1:1 的正方形?
<style>
.father { width: 300px; height: auto; background: #bfa; }
.son { padding-bottom: 100%; }
</style>
<div class="father">
<div class="son"></div>
</div>
</body>
答:只需要添加一句css属性 padding-bottom:100% 即可。
看明白了吗?反正 padding 单位 % 是相对于父元素的的宽度。当父元素的宽度也设置为 % 时,它有300px,子元素就有300px,它有800px,子元素就有800px。
明白了原理后,我们也可以推断出,padding-top同样有如此效果。
回归正题,把 height设置为 auto ,再在 img 的外边添加一个类名为 pb 的容器:
<style>
.box { width: 25%; height: auto; border: 10px solid #000; float: left; margin: 10px; }
.pb { padding-bottom: 100%; }
img { width: 100%; height: 100%;}
</style>
<div class="box">
<div class="pb">
<img src="images/3000_1000.jpg" alt="">
</div>
</div>
<div class="box">
<div class="pb">
<img src="images/350a8f0c766f5460.png" alt="">
</div>
</div>
<div class="box">
<div class="pb">
<img src="images/350a8f0c766f5460.png" alt="">
</div>
</div>
</body>
为什么看不见图片?因为此时的高度是padding撑起来的 pb 实际上也没有高度。
千万不要给 pb 高度,因为pb的作用就是用来获取父元素宽度变化的。(如果你头铁硬要给,你会发现陷入了奇怪的场景)
pb设置 height:100% 后
怎么解释,这是什么情况?让我们先分析第一个box
从img开始看:
宽度100%,相对于父元素 pb 宽度默认100%,再相对于它的父元素 box 的 25% = 600px
高度100%,相对于父元素 pb 高度 100%,在相对于它的父元素 box 的 auto ,算起来高度还是自己给的 = 200px
宽度100%,相对于父元素 box 的宽度25% = 600px
高度100%,相对于父元素 box 的 高度 auto = 0
padding-bottom:100%,相对于父元素 box 的宽度 25% = 600px
宽度25%,相对于当前视口宽度 = 600px
高度auto,被 pb 的子元素撑起来 = 0
边框 10px(会应用到计算)
容器宽度 = box宽度、边框 = 620px
容器高度 = img的高度 + pb的padding + box的border = 820px
经过上面复杂的计算,相信你已经头晕眼花的勉强搞懂了刚刚为什么会出现这种情况。也明白了给 pb height:100% 是不可取的!让我们去掉它,又恢复到了白色内容正方形边框的场景。
既然 img 的宽高相对于 pb 没有用,为何我们不直接让它脱离文本流,去相对于 box ?没错,就是定位!
给 img 的套一层容器 ab,让它带着我们的 img 飞起来
<style>
.box { width: 25%; height: auto;border: 10px solid #000; float: left; margin:10px; }
.pb { padding-bottom: 100%; }
.ab { width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 2 }
img { width: 100%; height: 100%;}
</style>
<div class="box">
<div class="pb">
<div class="ab">
<img src="images/3000_1000.jpg" alt="">
</div>
</div>
</div>
<div class="box">
<div class="pb">
<div class="ab">
<img src="images/350a8f0c766f5460.png" alt="">
</div>
</div>
</div>
<div class="box">
<div class="pb">
<div class="ab">
<img src="images/350a8f0c766f5460.png" alt="">
</div>
</div>
</div>
</body>
完美自适应宽高变化!可是我们这张图片的比例好像不是1:1的正方形哎,如何计算出高度的比例的呢?
图片高度 / 图片宽度 = 高度比例(取百分比)
以第一张图片的比例为准,3000px * 1000px
1000/3000=0.3333333333333333(取百分比)=33.33
由此得知高度百分比是 33.33%,但是我们不能直接给高度,前文也提到高度几乎没什么变化。(当然应该给 padding-bottom 呀)
顺便给img标签加一个 object-fit: cover; 防止变形
<style>
.box { width: 25%; height: auto; border: 10px solid #000; float: left; margin:10px; }
.pb { padding-bottom: 33.33%; }
.ab { width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 2; }
img { width: 100%; height: 100%; object-fit: cover; }
</style>
<div class="box">
<div class="pb">
<div class="ab">
<img src="images/3000_1000.jpg" alt="">
</div>
</div>
</div>
<div class="box">
<div class="pb">
<div class="ab">
<img src="images/350a8f0c766f5460.png" alt="">
</div>
</div>
</div>
<div class="box">
<div class="pb">
<div class="ab">
<img src="images/350a8f0c766f5460.png" alt="">
</div>
</div>
</div>
</body>
粉丝