背景:在我们开发的过程中,我们很经常有碰到这样的需求,要让某个dom元素随着窗口宽度/高度的变化自适应改变其宽度 / 高度,并且始终保持一个固定的宽高比。
我们先看看最终的方案:padding-bottom实现普通元素固定宽高比。
首先,我们先明确两个结论:
1.绝对定位元素的大小是由top、right、 bottom、 left四个属性决定的,这四个属性是相对于绝对定位元素的包含块来定位的。
2.垂直方向上的内外边距使用百分比做单位时,是基于包含块的宽度来计算的。
下面我们通过借助padding-bottom来实现一个宽高比例固定的元素:
<div class="video-wrapper">
<div class="video"></div>
</div>
.video-wrapper {
position: relative;
width: 100%;
height: 0;
padding: 0;
padding-bottom: 75%;
}
.video{
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
通过这种方式,我们就可以实现一个宽高自适应并使宽高比保持不变元素了。
但在发现这种解决的办法前,我也踩过了不少的坑:
踩坑一:媒体查询。
提前算好几个固定宽高比的宽度与高度,随着页面的宽高变化而切换不同的宽高:
@media (max-width: 1365px) {
.video {
width: 400px;
height: 300px;
}
}
@media (min-width: 1366px) and (max-width: 1679px) {
.video {
width: 600px;
height: 450px;
}
}
@media (min-width: 1680px) and (max-width: 1919px) {
.video {
width: 800px;
height: 600px;
}
}
@media (min-width: 1920px) {
.video {
width: 1000px;
height: 750px;
}
}
此方案较为直观,容易理解,但自适应效果不理想。
踩坑二:直接通过js计算。
我们可以将元素的宽度设置为百分比,在页面resize的时候再通过js获取元素的宽度,并根据宽高比计算出元素的高度。
此方案简单直观加效果理想,但是嘛,秉着能用css解决的事情就不要用js的观念,我还是不太能接受这种方式。
踩坑三:使用vh/vw + calc。
不了解vh/vw和calc的可以去看看下面的文章文档
vh/vw:https://www.zhangxinxu.com/wordpress/2012/09/new-viewport-relative-units-vw-vh-vm-vmin/
calc:https://developer.mozilla.org/zh-CN/docs/Web/CSS/calc()
我们可以将元素的宽度设置为固定vw/vh,并通过calc计算出对应的高度:
.video{
width:40vw;
height:30vw;
}
简单是简单,但是有个比较鸡肋的地方,因为vw/vh是相对于视窗的宽高的,因为当窗口上存在滚动条的话,他会把滚动条的宽高给计算上,那么你计算的时候就要把滚动条的宽高也要考虑上。