1、百分比介紹
一般元素的寬度用百分比值表示時,元素的總寬度包括外邊距取決於父元素的width,這樣可能得到“流式”頁面,即元素的外邊距會擴大或縮小以適應父元素的實際大小。如果對這個文件設定該樣式,使其子元素使用百分數外邊距,當使用者修改瀏覽視窗的寬度時,外邊距會隨之擴大或縮小。
margin-right
/margin-left
的百分比值是相對於父元素的寬度來計算的,這很好理解;而margin-top
/margin-bottom
為什麼也是以父元素的width為參照物的呢?
2、為什麼呢?
CSS權威指南中的解釋:若是相對於父元素的高度計算會形成死迴圈。
“我們認為,正常流中的大多數元素都會足夠高以包含其後代元素(包括外邊距),如果一個元素的上下外邊距是父元素的height的百分數,就可能導致一個無限迴圈,父元素的height會增加,以適應後代元素上下外邊距的增加,而相應的,上下外邊距因為父元素height的增加也會增加,形成無限迴圈。”
還有一種說法是根本原因並不是因為死迴圈。例如zhangxinxu認為相對於 height 計算,大多數情況下計算值都是 0,跟擺設沒什麼 區別,還不如相對寬度計算,因為 CSS 預設的是水平流,計算值一直會有效,而且我們還可以 利用這一特性實現一些有意思的佈局效果。也就是面向場景和需求設計,這種設計可以讓我們輕鬆實現自適應的等比例矩形效果。
Anyway,總而言之就是:
在預設的水平文件流方向下,CSS margin和padding屬性的垂直方向的百分比值都是相對於父元素寬度計算的。
3、小栗子
<div style="width:100px; border: 1px solid gray;" id="box">
<div id="container">1</div>
</div>
#container{
padding-top: 50%; // margin-top: 50%;
background-color: pink;
}
div中沒有內容時,實現的是一個寬高為1:2的小矩形。padding-top: 50%;
表示元素的高度為寬度的一半。padding-top: 100%; 可實現寬高為1:1的小矩形。(改為
padding: 50%`,實現的是一個寬高1:1的小矩形,因為50%+50%=100%;)
從盒子模型可以看出,雖然容器的內容高度為0,但由於有了跟內容寬度一致的padding,因此整體視覺效果上像是被撐開了。
使用方法: padding-top用來設定元素的寬高比例;該元素在父元素寬度變化的過程中將保持自身固定的寬高比。
4、應用
對於絕大多數都佈局,我們並不要求非要比例固定,但是有一種情況例外,那就是圖片,因為圖片原始尺寸它是固定的。在傳統的固定寬度的佈局下,我們會通過給圖片設定具體的寬度和高度值,來保證我們的圖片佔據區域穩固;但是在移動端或者在響應式開發情況下,圖片最終展現的寬度很可能是不確定的。
此時需要的不是對圖片進行固定尺寸設定,而是比例設定。為了維持圖片的寬高比固定,即保持原來的尺寸比不變,要做到元素高度隨著元素的進行自適應變化。
對於複雜佈局,如果圖片的寬度是不固定的自適應的,我們通常會想到這麼一個取巧的做法,就是隻設定圖片的寬度例如img { width: 100%; }
,圖片的高度不進行限定,由圖片的內容去撐開,這樣會出現圖片佔據的高度有一個從0到計算高度的圖片變化,視覺上會有明顯的元素跳動,程式碼層面會有佈局重計算。即使圖片載入速度很快,容器在圖片載入前後都會有一個變型的過程,也就是俗稱的“閃爍”,而如果圖片載入不出來,整體佈局就更是難看了。
所以對圖片高寬都進行限定還是有必要的,但是同時要保證寬度自適應。
給子元素/偽元素設定margin/padding撐開容器
由於新增子元素與HTML語義化相悖,因此更推薦使用偽元素(:after)來實現此方案。
<div style="width:100px; border: 1px solid gray;overflow:hidden;">
<div id="container" class="placeholder"></div>
</div>
#container {
position: relative;
background-color: pink;
overflow: hidden; // 當使用margin-top需要觸發BFC消除與其他元素可能發生margin摺疊的問題
}
.placeholder:after {
content: ` `;
display: block;
margin-top: 100%;
}
容器內部如何新增內容
那麼,在撐開容器後,如何給容器新增內容(圖片、文字等)呢?
利用position: absolute;
<div id="container" class="placeholder">
<img src="xxx.jpg" />
</div>
#container {
position: relative;
background-color: pink;
overflow: hidden;
}
.placeholder:after {
content: ` `;
display: block;
margin-top: 100%;
}
img {
position: absolute;
top: 0;
width: 100%;
}
References
CSS百分比padding實現比例固定圖片自適應佈局
巧用margin/padding的百分比值實現高度自適應(多用於佔位,避免閃爍)