背景:在我們開(kāi)發(fā)的過(guò)程中,我們很經(jīng)常有碰到這樣的需求,要讓某個(gè)dom元素隨著窗口寬度/高度的變化自適應(yīng)改變其寬度 / 高度,并且始終保持一個(gè)固定的寬高比。
我們先看看最終的方案:padding-bottom實(shí)現(xiàn)普通元素固定寬高比。
首先,我們先明確兩個(gè)結(jié)論:
1.絕對(duì)定位元素的大小是由top、right、 bottom、 left四個(gè)屬性決定的,這四個(gè)屬性是相對(duì)于絕對(duì)定位元素的包含塊來(lái)定位的。
2.垂直方向上的內(nèi)外邊距使用百分比做單位時(shí),是基于包含塊的寬度來(lái)計(jì)算的。
下面我們通過(guò)借助padding-bottom來(lái)實(shí)現(xiàn)一個(gè)寬高比例固定的元素:
<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;
}
通過(guò)這種方式,我們就可以實(shí)現(xiàn)一個(gè)寬高自適應(yīng)并使寬高比保持不變?cè)亓恕?/p>
但在發(fā)現(xiàn)這種解決的辦法前,我也踩過(guò)了不少的坑:
踩坑一:媒體查詢。
提前算好幾個(gè)固定寬高比的寬度與高度,隨著頁(yè)面的寬高變化而切換不同的寬高:
@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;
}
}
此方案較為直觀,容易理解,但自適應(yīng)效果不理想。
踩坑二:直接通過(guò)js計(jì)算。
我們可以將元素的寬度設(shè)置為百分比,在頁(yè)面resize的時(shí)候再通過(guò)js獲取元素的寬度,并根據(jù)寬高比計(jì)算出元素的高度。
此方案簡(jiǎn)單直觀加效果理想,但是嘛,秉著能用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()
我們可以將元素的寬度設(shè)置為固定vw/vh,并通過(guò)calc計(jì)算出對(duì)應(yīng)的高度:
.video{
width:40vw;
height:30vw;
}
簡(jiǎn)單是簡(jiǎn)單,但是有個(gè)比較雞肋的地方,因?yàn)関w/vh是相對(duì)于視窗的寬高的,因?yàn)楫?dāng)窗口上存在滾動(dòng)條的話,他會(huì)把滾動(dòng)條的寬高給計(jì)算上,那么你計(jì)算的時(shí)候就要把滾動(dòng)條的寬高也要考慮上。