首頁  >  文章  >  web前端  >  CSS魔法堂:hasLayout原來是這樣!

CSS魔法堂:hasLayout原來是這樣!

巴扎黑
巴扎黑原創
2017-06-28 11:13:041141瀏覽

前言

過去一直聽說舊版IE下很多詭異bug均由一個神秘角色引起的,那就是hasLayout。趁著最近突然發神經打算好好學習CSS,順便解答多年來的疑惑。

hasLayout到底是何方神聖?

hasLayout可以簡單看作是IE5.5/6/7中的BFC(Block Formatting Context)。也就是一個元素要麼自己對自身內容進行組織和尺寸計算(即可透過width/height來設定自身的寬高),要麼由其containing block來組織和尺寸計算。 而IFC(即沒有擁有佈局)而言,則是元素無法對自身內容進行組織和尺寸計算,而是由自身內容來決定其尺寸(即僅能通過line-height 設定內容行距,透過行距來支撐元素的高度;也無法透過width設定元素寬度,僅能由內容來決定而已)
當hasLayout為true時(就是所謂的"擁有佈局" ),相當於元素產生新BFC,元素自己對自身內容進行組織與尺寸計算;
當hasLayout為false時(就是所謂的"不擁有佈局"),相當於元素不產生新BFC,元素由其所屬的containing block進行組織和尺寸計算。
和產生新BFC的特性一樣,hasLayout無法透過CSS屬性直接設置,而是透過某些CSS屬性間接開啟此特性。不同的是某些CSS屬性是以不可逆方式間接開啟hasLayout為true。且預設產生新BFC的只有html元素,而預設hasLayout為true的元素就不只有html元素了。
另外我們可以透過object.currentStyle.hasLayout屬性來判斷元素是否開啟了hasLayout特性。

到這裡我們應該了解到若要理解hasLayout則必須理解BFC,因此這裡可參考CSS魔法堂:重新認識Box Model、IFC、BFC和Collapsing margins

#預設 hasLayout==true的元素


<html>, <body><table>, <tr>, <th>, <td><img>,<hr><input>, <button>, <select>, <textarea>, <fieldset>, <legend><iframe>, <embed>, <object>, <applet>,<marquee>

觸發hasLayout==true的方式

display: inline-block
height: (除 auto 外任何值)
width: (除 auto 外任何值)
float: (left 或 right)
position: absolute
writing-mode: tb-rl
zoom: (除 normal 外任意值)

IE7 還有一些額外的屬性(不完全列表)可以觸發hasLayout :

min-height: (任意值)
min-width: (任意值)
max-height: (除 none 外任意值)
max-width: (除 none 外任意值)
overflow: (除 visible 外任意值,仅用于块级元素)
overflow-x: (除 visible 外任意值,仅用于块级元素)
overflow-y: (除 visible 外任意值,仅用于块级元素)
position: fixed

IE6 以前的版本(也包括IE6 及以後所有版本的混雜模式,其實這種混雜模式在渲染方面就相當於IE 5.5), 透過設定任何元素的'width' 或'height'(非auto)都可以觸發hasLayout ; 但在IE6 和IE7 的標準模式中的行內元素上卻不行,設定'display:inline-block' 才可以。

其中透過display:inline-blockmin-width:0min-height:0將不可逆地啟用hasLayout特性。而在沒有其他屬性啟用hasLayout時,可透過以下方式關閉hasLayout

max-width, max-height (设为 "none")(在IE7中)
position (设为 "static")
float (设为 "none")
overflow (设为 "visible") (在IE7中)
zoom (设为 "normal")
writing-mode (从 "tb-rl" 设为 "lr-t")

而產生新BFC的CSS屬性

position:absolute/fixed
float:left/right
display:inline-block/table-cell/table-caption/flex/inline-flex
overflow:(除visible外任意值)

可以看到導致產生新BFC的方式和觸發 hasLayout==true的方式不完全重疊。因此hasLayout==true所引發的問題,很大程度上可以理解為在不應該的或沒有預料到的地方產生新的BFC所導致的。

如何相容?

只有當一個元素即在 IE 早期版本中觸發了 hasLayout,又在其他瀏覽器中創建了 block formatting context 時,才能避免上述問題的發生。即同時啟用上述兩者以確保各瀏覽器的相容,或相反,兩者皆不啟用。

  1. 使元素即產生了block formatting context,又觸發了hasLayout
    1.1 對於觸發hasLayout 的元素,透過CSS 設置,使它產生block formatting context;
    1.2產生block formatting context 但是沒有觸發hasLayout 的元素,透過設定'zoom:1',使其觸發hasLayout。

  2. 讓元素即沒有觸發 hasLayout,又沒有建立 block formatting context。

總結

雖然我現在已經不用再適合IE5.5/6/7了,但理解hasLayout還是很有必要的。其實可以理解為從另一個角度學習BFC吧!
尊重原創,轉載請註明來自:http://www.cnblogs.com/fsjohnhuang/p/5291166.html肥仔john^_^

感謝

#談談BFC與ie特有屬性hasLayout
RM8002: 不能同時在IE6 IE7 IE8(Q) 中觸發hasLayout 並在其他瀏覽器中創建Block Formatting Context 的元素在各瀏覽器中的表現會有差異

以上是CSS魔法堂:hasLayout原來是這樣!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn