過去一直據說舊版本IE下不少詭異bug均由一個神祕角色引發的,那就是hasLayout。趁着最近忽然發神經打算好好學習CSS,順便解答多年來的疑惑。html
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特性。segmentfault
到這裏咱們應該瞭解到若要理解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 :app
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-block
或min-width:0
或min-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致使的。flex
僅當一個元素即在 IE 早期版本中觸發了 hasLayout,又在其餘瀏覽器中建立了 block formatting context 時,才能避免上述問題的發生。即同時啓用上述二者以保證各瀏覽器的兼容,或者相反,二者皆不啓用。code
使元素即生成了 block formatting context,又觸發了 hasLayout
對於觸發 hasLayout 的元素,經過 CSS 設置,使它產生 block formatting context;orm
生成 block formatting context 可是沒有觸發 hasLayout 的元素,經過設置 'zoom:1',使其觸發 hasLayout。htm
使元素即沒有觸發 hasLayout,又沒有建立 block formatting context。
雖然我如今已經不用再適配IE5.5/6/7了,但理解hasLayout仍是頗有必要的。其實能夠理解爲從另外一個角度學習BFC吧!
尊重原創,轉載請註明來自:肥仔john^_^
談談BFC與ie特有屬性hasLayout
RM8002: 不能同時在 IE6 IE7 IE8(Q) 中觸發 hasLayout 並在其餘瀏覽器中建立 Block Formatting Context 的元素在各瀏覽器中的表現會有差別