【CSS黑科技】CSS百分比實現高度占位自適應(margin/padding)


基本知識點

本文依賴於一個基礎卻又容易混淆的css知識點:當padding/margin取形式為百分比的值時,無論是left/right,還是top/bottom,都是以父元素的width為參照物的!

哈,top/left以父元素的width為參照物還好理解,但top/bottom不是以height更符合我們的預期嗎?有疑惑很簡單,看官方解釋

 

 

 

舉個栗子

我們有個頁面,如下圖,如果是在PC端好辦,容器的寬高都寫死是多少px,這樣即使圖片加載不出來容器都不會變型。但是在移動端,由於各機型分辨率相差太大,寫死px是絕對不可能的,終究還得靠百分比來實現的:

 

 

  1. 一行2列的容器寬度設個50%吧,這樣一行放倆容器,各占屏幕寬度一半,沒問題。
  2. 圖片寬度設個100%取容器的寬度,沒問題。
  3. 容器高度沒法設置啊,因為容器寬高的參照物不一樣,而且需求是高度與寬度一致,所以無法通過為容器高度設置百分比來達成,那就只能靠內容高度撐開了。
  4. 容器的內容高度就是圖片的高度,若圖片是正方形,則圖片高度與圖片寬度一致,也即與容器寬度一致,看起來沒問題是吧?實際上,在瀏覽器把圖片加載出來以前,圖片的高度是零,那可就沒辦法把容器撐開了,如下圖所示:

 

 

這樣一來,即使圖片加載速度再快,也會有個高度撐開的過程,如果圖片沒有加載成功,那更慘,整個頁面的結構都有可能會有問題,這肯定會被測試同學報bug的啦

現在問題很明顯了,就是怎么不用圖片可以撐開容器高度,而且是高度可控,比如寬高比是個1:2什么的

給容器設置padding-top/bottom

啦啦啦,上文說的padding-top/bottom的百分比值,是依賴父容器寬度的,這樣容器的寬度和高度都可以統一同一個參照物了(父元素的寬度)

舉個例子,圖片寬高比是1:1,一行放2個容器

視覺結果如下:

 

容器的盒子模型如下:

 

 

從盒子模型可以看出,雖然容器的內容高度為0,但由於有了跟內容寬度一致的padding,因此整體視覺效果上像是被撐開了。我們達成了最初的夢想

此方案瀏覽器兼容性很不錯,唯一的缺陷是無法給容器設置max-height屬性了,因為max-height只能限制內容高度,而不能限制padding!!如下這個項目:

 

 

這個頭圖是按寬高比設置的大小,但是還需要考慮橫屏的情況,如下圖:

 

 

我們是不會輕易的狗帶的!!

給子元素/偽元素設置margin/padding撐開容器

從上面的方案的盒模型看出max-height失效的原因是容器的高度本來就是padding撐的,而內容高度為0,max-height無法起作用。那想要優化這一點,唯一的方法就是利用內容高度來撐開而非padding,這個方案跟消除浮動所用的方案非常相似:給容器添加一個子元素/偽元素,並把子元素/偽元素的pading/margin設為100%,使其實際高度相當於容器的寬度,如此一來,便能把容器的高度撐至與寬度達成我們預想的寬高比(1:1)了。由於添加子元素與HTML語義化相悖,因此更推薦使用偽元素:after來實現此方案。

我們再來看看此時的盒子模型:

 

 

完美,可以看出,此時容器的內容高度與內容寬度一致,媽媽再也不用擔心我無法通過max-height來限制容器高度了。

上面那個項目也是這樣解決了不能設置max-height的痛點

 

 

 

另外,使用margin的話需要考慮margin折疊的問題(參考代碼BFC相關),padding則無此煩惱。

哈,容器就給你了,要往容器內添加內容,但不能添加額外高度,那只能是使用position:absolute啦~

 

最后,奉上sass如下:

position: relative;
    @if $type == true {
        &#{$ele}{
            content: '';
            display: block;
            width: 100%;
            padding-top: percentage($arg);
        }
    }@else{
        padding-top: percentage($arg);
    }   
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM