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