摘要:當一個內(nèi)聯(lián)元素想獲得就要使用這個屬性。下因為導致的浮動元素與普通元素之間產(chǎn)生代碼如下我是浮動元素我是后面的文字,用來測試的正常情況下解決方式加一個的不只是文字,的浮動元素也會和內(nèi)聯(lián)元素產(chǎn)生的值。設置屬性的元素不和任何元素發(fā)生合并。
發(fā)現(xiàn)我好久沒更新博文了=-=這里把我之前在博客園寫過的一篇關于BFC的文章粘貼過來,順便自己也再次做個總結(jié)。
最近看了一篇總結(jié)ie常見bug的文章,里面提到ie多數(shù)的bug源于她的特有屬性:hasLayout。這個屬性以前也了解過一點,但沒有深入去理解,于是查閱了一些相關的資料,現(xiàn)在在此來對這個屬性作一下總結(jié)。
haslayout的普遍定義洋洋灑灑一大篇。這里的內(nèi)容如果覺得不好懂的話建議可以先看看后文提到的BFC屬性。
在ie中,一個元素要么自己對自身的內(nèi)容進行計算大小和組織,要么依賴于父元素來計算尺寸和組織內(nèi)容。為了調(diào)節(jié)這兩個不同的概念,渲染引擎采用了
hasLayout 的屬性,屬性值可以為true或false。當一個元素的
hasLayout屬性值為true時,我們說這個元素有一個布局(layout)。如果它設置成了true,它就不得不去渲染它自己,因此元素不得不擴展去包含它的流出的內(nèi)容。例如浮動或者很長很長的沒有截斷的單詞,如果haslayout沒有被設置成true,那么元素得依靠某個祖先元素來渲染它。這就是很多的ie
bugs誕生的地方。當一個元素有一個布局時,它負責對自己和可能的子孫元素進行尺寸計算和定位。簡單來說,這意味著這個元素需要花更多的代價來維護自身和里面的內(nèi)容,而不是依賴于祖先元素來完成這些工作。因此,一些元素默認會有一個布局。當我們說一個元素“擁有l(wèi)ayout”或 “得到layout,
或者說一個元素“has layout” 的時候,我們的意思是指它的微軟專有屬性 hasLayout 被設為了 true。通過IE Developer Toolbar 可以查看 IE 下 HTML元素是否擁有haslayout,在 IE Developer Toolbar 下,擁有 haslayout的元素,通常顯示為“haslayout = -1”。
值得注意的是,css下是沒有haslayout這一個屬性的,只能通過把某些屬性設置特定值來使ie下的hasLayout屬性觸發(fā)。這個屬性在ie8及以后版本中被拋棄。
激活“haslayout”的方式——調(diào)整下列css屬性:
width:非auto任意值——優(yōu)先考慮
height:非auto任意值——對 IE6 及更早版本來說很常用,該方法被稱為霍莉破解(Holly hack),即設定這個元素的高度為 1% (height:1%;)。但是要注意,當這個元素的 overflow 屬性被設置為 visible 時,這個方法就失效了。
zoom:非normal任意值——該屬性也為ie特有屬性。一般測試的時候用zoom:1。可以避免改變其他屬性破壞布局。
position:absolute——可能引發(fā)新問題。
float:left/right——ie 常見bug很多都因為元素設置了浮動而觸發(fā)haslayout產(chǎn)生的。
display:inline-block——當一個內(nèi)聯(lián)元素想獲得layout就要使用這個屬性。
min-height、max-height(除none)、min-width、max-width(除none)設置任意值——針對ie7。
overflow、overflow-x、overflow-y除visible外任意值——針對ie7。
position:fixed——針對ie7。
重置“haslayout”:需要沒有其他屬性激活haslayout的前提下。
width, height (設為 "auto")
max-width, max-height (設為 "none")(在 IE 7 中)
position (設為 "static")
float (設為 "none")
overflow (設為 "visible") (在 IE 7 中)
zoom (設為 "normal")
writing-mode (從 "tb-rl" 設為 "lr-t")
注意:當用inline-block激活了haslayout 屬性時,就算在一條獨立的規(guī)則中覆蓋這個屬性為block或inline,haslayout 這個標志位也不會被重置為 false。把 min-width, min-height 設為它們的默認值"0"仍然會賦予 hasLayout,但是 IE 7 卻可以接受一個不合法的屬性auto來重置 hasLayout。
BFC是W3C CSS 2.1
規(guī)范中的一個概念,它決定了元素如何對其內(nèi)容進行定位,以及與其他元素的關系和相互作用。當涉及到可視化布局的時候,Block Formatting Context提供了一個環(huán)境,HTML元素在這個環(huán)境中按照一定規(guī)則進行布局。一個環(huán)境中的元素不會影響到其它環(huán)境中的布局。
要更好地理解BFC,要先來談談Box和Formatting Context的概念。我們知道網(wǎng)頁布局是由很多盒子組成的,這些塊就是Box。元素的類型和 display 屬性,決定了這個 Box 的類型。 不同類型的 Box, 會參與不同的 Formatting Context(決定如何渲染文檔的格式結(jié)構(gòu)),因此Box內(nèi)的元素會以不同的方式渲染。
例如:
block-level box: display 屬性為 block, list-item, table 的元素,會生成
block-level box。并且參與 block fomatting context;
inline-level box:display 屬性為 inline, inline-block, inline-table
的元素,會生成 inline-level box。并且參與 inline formatting context;
而Formatting Context是一塊渲染區(qū)域,它決定了其子元素如何定位,以及與其他元素的位置關系。
根據(jù)上述的一些基本概念,我把BFC簡單理解成一種屬性,在具有BFC屬性的容器中,元素按照BFC的規(guī)則實現(xiàn)布局。比如浮動元素會形成BFC,這就是為什么我們看到浮動元素布局跟普通文檔流下的布局有所差別的原因。
BFC的規(guī)則內(nèi)部的Box會在垂直方向,一個接一個地放置。
Box垂直方向的距離由margin決定。屬于同一個BFC的兩個相鄰Box的margin會發(fā)生重疊
每個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對于從左往右的格式化,否則相反)。即使存在浮動也是如此。
BFC的區(qū)域不會與float box重疊。
BFC就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。反之也如此。
計算BFC的高度時,浮動元素也參與計算
哪些元素會形成BFC根元素
float屬性不為none
position為absolute或fixed
display為inline-block, table-cell, table-caption, flex, inline-flex
overflow不為visible
解決兩元素margin重疊的問題
要想兩個相鄰的元素不發(fā)生垂直方向上的margin重疊,需要將他們兩定義在不同的BFC中。解決方法即在其中一個元素外包裹一層元素,再對那層包裹的元素進行BFC觸發(fā)。(這里可以加入上述的css屬性。)
解決由于浮動造成的重疊問題
一般情況下,浮動元素會脫離文檔流,即不占位置。它的兄弟元素會與它在左上角重疊。但是如果兩個相鄰元素都設置了浮動,那么意味著它們都是以BFC的規(guī)則渲染,根據(jù)上述第四條規(guī)則,BFC區(qū)域不會相互重疊,所以便能理解為什么設置浮動后元素能獨占空間了。
解決容器由于擁有浮動元素造成高度塌陷的問題
在普通容器中,如果里面有浮動元素,在不設置高度的情況下,容器是不能被撐起來的,這時候通過設置overflow:hidden把其變?yōu)锽FC,那么就可以包含浮動元素了。
BFC的說明到此就告一段落了,現(xiàn)在回到最初討論的haslayout的問題。ie7及以下ie版本不支持BFC的,但有私有屬性haslayout,于是我們可以通過觸發(fā)元素的haslayout來達成bfc的相似效果。
IE下因為haslayout導致的bug1、浮動元素與普通元素之間產(chǎn)生3px bug
//代碼如下我是浮動元素我是后面的文字,用來測試3px的bug
正常情況:
ie6下:
解決方式:加一個ie6的hack:*margin-right:-3px;
不只是文字,ie6的浮動元素也會和內(nèi)聯(lián)元素產(chǎn)生3px的margin值。
正常情況:
ie6,7下:
解決方式同上。
2、塊級元素與浮動元素不會重疊
我是浮動元素我是浮動元素后面的塊級元素
正常情況:
ie6,7:
可以明顯地發(fā)現(xiàn)ie6,7下塊級元素跟浮動元素不能重疊。為什么會發(fā)生這種情況呢?是因為我在塊級元素上設置了高度。激活了ie下的haslayout屬性。于是ie6把它以BFC類似的方式進行渲染。
解決方式:在塊級元素外再包裹一層DIV。并且把內(nèi)部DIVbackground的屬性寫在外層DIV上。
3、浮動閉合元素
這個問題其實很多人會遇到,上文也提到過,只是可能叫法不同。
我浮動啦!
正常情況:
注意那一條橫線是.test的border,因為浮動元素脫離了文檔流,故.test不能被撐起來。
ie6,7
ie似乎妥妥的。其實很多情況下,我們想要的是ie這種效果。在ie中,一個浮動元素總是隸屬于包含它的容器。是因為.test設置了寬度,激活了haslayout屬性。而在非ie瀏覽器中,我們想要獲得這種效果一般是在父盒子上加一個:after的偽對象來清除浮動,或者設置overflow:hidden來觸發(fā)BFC。
插入提一下閉合浮動的普遍做法:
為需要閉合浮動的父元素加入clearfix的類。
.clearfix::after {content:"";display:block;height:0;clear:both;} .clearfix {zoom: 1;} //兼容ie6,7
4、ie下margin不塌陷
我浮動啦!測試margin-top在ie下是否塌陷
正常情況:
ie6,7
float是浮動元素,她脫離了文檔流,所以第二個DIV的margin-top相對的是其上級.test作用的。但我們只是對第二個DIV設置margin-top。結(jié)果在chrome下,怎么連float也“產(chǎn)生了margin-top”呢。對比ie和chrome下的效果,是不是覺得IE下的 解析會比較合理呢?
但是。別忘了影響margin-top/bottom的一個重要規(guī)則——margin塌陷(margin collapsing)。
提到了margin塌陷,我們來看看margin垂直方向上塌陷的一些條件:
水平margin不會合并。
兩個上下渲染相鄰(不一定是兄弟節(jié)點)的塊狀元素在正常頁面流情況下會發(fā)生 margin 合并。
浮動元素不會和任何元素(包括子孫節(jié)點)發(fā)生 margin 合并。
overflow!=visible的元素不和任何元素發(fā)生margin合并。
絕對定位的元素不和任何元素發(fā)生margin合并。
inline-block 的元素不和任何元素發(fā)生margin合并。
設置 clear 屬性的元素不和任何元素發(fā)生margin合并。
根元素不和任何元素發(fā)生margin合并。
父節(jié)點和第一個子節(jié)點發(fā)生margin-top合并。
如果最后一個子節(jié)點沒有border以及padding,則和其父節(jié)點發(fā)生margin-bottom合并。
注意低版本IE下特別是hasLayout對于margin合并也有影響,從而也造成了包含的絕對定位元素的位置差異。
在現(xiàn)代瀏覽器下.test塊的高度并沒有被子元素第二個DIV的margin-top撐開。反而自身擁有了30px的margin-top。
而浮動塊盡管脫離了文檔流,但還是受其父級限制的(這跟absolute定位的元素層受限于其定義為relative的父級一樣)。所以float還是包含在test之中,這樣在chrome下看起來浮動塊也擁有margin-top,而事實上是因為test高度不撐開的結(jié)果。
這么說,chrome并沒有錯咯,那么IE下又是怎么避開margin塌陷的呢?問題就出在浮動上面,在ie下,元素浮動將觸發(fā)其haslayout。就是這個原因,使得在ie下意外(意外?)的就避開了margin塌陷。
但是奇怪的是,如果給.test加上border,chrome的渲染情況就跟ie一樣了,float沒有擁有與第二個DIV相同的margin-top值。而是緊貼.test的頂部。如下圖:
chrome:
ie6,7:
這個問題的原因還需要研究一下。。。。如果有知道原因的大神麻煩給留個言,,感激!
5、ie下margin-left/right失效
測試失效的margin-left
正常情況:
ie6:
根據(jù)上圖可以發(fā)現(xiàn),ie下我們?yōu)樽覦IV設置的margin失效了。為什么會發(fā)生這種情況,同樣是是因為子DIV設置了高度,激活了haslayout。
解決辦法:不為子DIV設置高度,或者把父盒子的haslayout也激活。
參考資料:
http://cssass.com/blog/2009/147.html
http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html
http://www.cnblogs.com/pigtail/archive/2013/01/23/2871627.html
原文鏈接:
http://www.cnblogs.com/Remix/articles/4777257.html
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/49787.html
摘要:當一個內(nèi)聯(lián)元素想獲得就要使用這個屬性。下因為導致的浮動元素與普通元素之間產(chǎn)生代碼如下我是浮動元素我是后面的文字,用來測試的正常情況下解決方式加一個的不只是文字,的浮動元素也會和內(nèi)聯(lián)元素產(chǎn)生的值。設置屬性的元素不和任何元素發(fā)生合并。 發(fā)現(xiàn)我好久沒更新博文了=-=這里把我之前在博客園寫過的一篇關于BFC的文章粘貼過來,順便自己也再次做個總結(jié)。 最近看了一篇總結(jié)ie常見bug的文章,里面提...
摘要:到底是何方神圣可以簡單看作是中的。和產(chǎn)生新的特性一樣,無法通過屬性直接設置,而是通過某些屬性間接開啟這一特性。不同的是某些屬性是以不可逆方式間接開啟為。因此所引發(fā)的問題,很大程度可以理解為在不應該的或沒有預料到的地方產(chǎn)生新的導致的。 前言 過去一直聽說舊版本IE下很多詭異bug均由一個神秘角色引起的,那就是hasLayout。趁著最近突然發(fā)神經(jīng)打算好好學習CSS,順便解答多年來的疑惑。...
摘要:有不少前端開發(fā)工程師,可能并不清楚下面的部分詞語,但是在實戰(zhàn)中其實都在使用著它們。明確一下這些詞語和概念沒有什么不好一方面能夠讓自己能夠更專業(yè)的談論知識,另一方面,在面試的時候也能夠應對一些愛問前端名詞的面試官是的縮寫,表示的是萬維網(wǎng)聯(lián)盟。 有不少前端開發(fā)工程師,可能并不清楚下面的部分詞語,但是在實戰(zhàn)中其實都在使用著它們。 明確一下這些詞語和概念沒有什么不好~一方面能夠讓自己能夠更專業(yè)...
摘要:有不少前端開發(fā)工程師,可能并不清楚下面的部分詞語,但是在實戰(zhàn)中其實都在使用著它們。明確一下這些詞語和概念沒有什么不好一方面能夠讓自己能夠更專業(yè)的談論知識,另一方面,在面試的時候也能夠應對一些愛問前端名詞的面試官是的縮寫,表示的是萬維網(wǎng)聯(lián)盟。 有不少前端開發(fā)工程師,可能并不清楚下面的部分詞語,但是在實戰(zhàn)中其實都在使用著它們。 明確一下這些詞語和概念沒有什么不好~一方面能夠讓自己能夠更專業(yè)...
閱讀 1697·2021-10-09 09:44
閱讀 3263·2021-09-27 13:36
閱讀 1520·2021-09-22 15:33
閱讀 1274·2021-09-22 15:23
閱讀 1159·2021-09-06 15:02
閱讀 1695·2019-08-29 16:14
閱讀 2901·2019-08-29 15:26
閱讀 2408·2019-08-28 18:08