從height:100%不支持聊聊CSS中的“死循環”

分類:技術 時間:2016-09-23

這篇文章發布于 2016年09月16日,星期五,17:25,歸類于css相關。 閱讀 12 次, 今日 12 次

byzhangxinxu from http://www.zhangxinxu.com/wordpress/?p=5666

本文全文轉載需購買版權(500yen;),摘要引流則免費,具體參見這里

一、從為何height:100%無效的回答說起

大家應該都知道,如果元素沒有格式化的高度值,子元素的 height 百分比高度是不起作用的,常見的就是height:100%無效,而寬度就沒有此問題,所以,新人經常會提出的一個問題是:“為何我的div設置了height:100%卻沒有效果?”

不知道大家有沒有思考過這樣一個問題。

然后,有同行就提出了這么一個看似很合理的解釋,就是,“假如父元素height:auto且沒有其他格式化高度,子元素支持height:100%,則很可能會出現高度死循環”。

什么意思呢?

例如:一個 lt;divgt; 元素里面有一張 vertical-alignbottom 同時高度為 192 像素的圖片,此時,該 lt;divgt; 高度就是 192 像素,假設此時,插入一個子元素,高度設為 100% ,如果此時 height:100% 可以計算,則子元素應該也是 192 像素。但是啊但是,我們的父元素 height 值是 auto ,豈不是現在高度要從原來的 192 像素變成 384 像素,然后 height:100% 的子元素高度又要變成 384 像素,父元素高度又雙倍……死循環了!

實際上, 這種解釋是錯誤的 ,大家千萬別被誤導。

證據就是寬度也存在類似場景,但并沒有死循環。例如下面這個例子,父元素采用“最大寬度”,然后有個 inline-block 子元素寬度100%:

lt;div class=quot;boxquot;gt;  lt;img src=http://www.tuicool.com/articles/quot;1.jpgquot;gt;  lt;span class=quot;textquot;gt;紅色背景是父級lt;/spangt;lt;/divgt;
.box {  display: inline-block;  white-space: nowrap;  background-color: #cd0000;}.text {  display: inline-block;  width: 100%;  background-color: #34538b;  color: #fff;}

如果按照上面“高度死循環”的解釋,這里也應該“寬度死循環”,因為后面的 inline-block 元素按照我們的理解應該會讓父元素的寬度進一步變大。但是,實際上,并沒有,寬度范圍可能超出你的預期:

父元素的寬度就是圖片加文字內容的寬度之和。

眼見為實,您可以狠狠地點擊這里:寬度死循環不存在demo

二、為什么不會死循環

這需要了解瀏覽器渲染的基本原理。首先,先下載文檔內容,加載頭部的樣式資源(如果有),然后按照從上而下,自外而內的順序渲染DOM內容。套用本例就是,先渲染父元素,后渲染子元素,是有個先后順序的。因此當渲染到父元素的時候,子元素的 width:100% 并沒有渲染,所以,寬度就是圖片加文字內容的寬度;等渲染到文字這個子元素的時候,父元素寬度已經固定,此時的 width:100% 就是已經固定好的父元素的寬度,寬度不夠怎么辦?溢出就好了,overflow屬性就是為此而生的。

同樣的道理,如果 height 支持任意元素 100% ,也是不會死循環的,和寬度類似,靜態渲染,一次到位。

這就引申出另外一個問題, 父選擇器 ,大家有沒有想過如果CSS支持了父選擇器,會有什么后果?

后果之一,就是原先的一次渲染被破壞,子元素能夠影響父元素的渲染,于是乎,“死循環”開始了,頁面渲染會出現各種各樣的死循環,現有的很多CSS規則會被顛覆,無限寬度反復渲染等問題就會出現。這就是為什么父選擇器呼聲那么高,卻遲遲不支持的原因。

其實,在CSS中,不會死循環的例子還有很多,我再舉一個很有意思的!

三、CSS padding百分比、滾動條與“死循環”

CSS的 padding 屬性值如果是百分比值,則無論是水平方向還是垂直方向都相對于寬度計算,這就埋下了一個看似會“死循環”的隱患,我們直接看一個例子。

一個 div 有如下CSS:

.box {  width: 200px;  height: 199px;  overflow: auto;}.child {  padding: 50%;}

容器寬 200px199px ,子元素 padding:50% ,則此時,子元素的寬高應該都是 200px ,但是,如果高度是 200px ,父元素就會出現滾動條,因為父元素高度 199px 不足 200px ,但是,父元素出現滾動條,父元素的 content box 的寬度就要減去滾動條的寬度,例如window 7下都是17像素,此時,子元素自然寬高也要隨之降低,應該是 183px ,但是,變成 183px 后高度又小于了父元素的 199px ,滾動條又會消失,子元素寬度又回到 200px ,于是,一個看上去的死循環開始了……

但是,實際上,最終渲染是一次性的,如果父子元素分別給個背景色,則結果如下:

大家就見到了上圖所示的“神奇的”一幕,也就是 padding:50% 元素的寬度居然不是父元素的 content box 寬度。

結果,父元素寬度還是原來的 200px ,但是,子元素卻是 183px ,右側和下方都留了看上去不能理解的空白間距。

眼見為實,您可以狠狠地點擊這里: CSS padding百分比值“死循環”不存在demo

這就是CSS的一次渲染機制造成的效果。

這個例子也進一步證明了: CSS中,如果單純是靜態渲染,是沒有死循環這種說說法的!

再如我們CSS :hover 某元素,讓其到原理鼠標的地方,按照道理,原理了,應該不執行 :hover 渲染要回到原地,實際上,遠離了就遠離,不會不斷執行渲染的。

四、CSS中的無限循環

實際上,CSS中是有與“死循環”相關的關鍵字的,叫做 infinite ,英菲尼迪,無限的意思,出現在CSS3 animation中,可以讓動畫無限循環,但是,“無限循環”并不等同于“死循環”。

五、結束語

一開始的問題“為何height:100%無效”究竟原因是什么呢?

這個其實可以從規范中找答案,具體是什么呢?我這里賣個關子,大家可以關心我日后的著作,其中會解釋“為何height:100%無效”。

OK,最后一句話總結下本文的中小論點: CSS中沒有死循環的說法

感謝閱讀,歡迎交流!

本文為原創文章,尊重辛勤勞動,可以免費摘要、推薦或聚合,但完整轉載需付費購買版權,詳見轉載協議聲明

本文地址: http://www.zhangxinxu.com/wordpress/?p=5666

(本篇完)


Tags:

文章來源:http://www.zhangxinxu.com/wordpress/2016/09/talkin


ads
ads

相關文章
ads

相關文章

ad