如何解決外邊距疊加的問題?
上面div的margin-bottom:10px;
下面div的margin-top:10px;這樣他們的外邊距疊加了,有什麼方法解決,最好不要轉換成padding<div style="width:100px; background:#930; height:100px; margin-bottom:10px;"></div><div style="width:100px; background:#f30; height:100px; margin-top:10px;"></div>
為了不誤導大家,如果克軍指的是觸發上下&元素的BFC,必須指出克軍的答案是錯誤的,這樣的margin還是會摺疊的。
collapsing-margin的W3C官方介紹:http://www.w3.org/TR/CSS2/box.html#collapsing-margins
一、首先你要知道什麼情況下會觸發:兩個或多個毗鄰的普通流中的塊元素垂直方向上的 margin 會摺疊
1.兩個或多個 說明其數量必須是大於一個,又說明,摺疊是元素與元素間相互的行為,不存在 A 和 B 摺疊,B 沒有和 A 摺疊的現象。2.毗鄰
是指沒有被非空內容、padding、border 或 clear 分隔開,說明其位置關係。
注意一點,在沒有被分隔開的情況下,一個元素的 margin-top 會和它普通流中的第一個子元素(非浮動元素等)的 margin-top 相鄰; 只有在一個元素的 height 是 "auto" 的情況下,它的 margin-bottom 才會和它普通流中的最後一個子元素(非浮動元素等)的 margin-bottom 相鄰。3.垂直方向
是指具體的方位,只有垂直方向的 margin 才會摺疊,也就是說,水平方向的 margin 不會發生摺疊的現象。二、那麼如何使元素上下margin不摺疊呢?
1.浮動元素、inline-block 元素、絕對定位元素的 margin 不會和垂直方向上其他元素的 margin 摺疊(注意這裡指的是上下相鄰的元素)
2.創建了塊級格式化上下文的元素,不和它的子元素髮生 margin 摺疊(注意這裡指的是創建了BFC的元素和它的子元素不會發生摺疊) 我們都知道觸發BFC的因素是float(除了none)、overflow(除了visible)、display(table-cell/table-caption/inline-block)、position(除了static/relative)很明顯大家可以看出來相鄰元素不發生摺疊的因素是觸發BFC因素的子集,也就是說如果我為上下相鄰的元素設置了overflow:hidden,雖然觸發了BFC,但是上下元素的上下margin還是會發生摺疊 這個問題其實和BFC並沒有太大的關係,希望大家不要濫用BFC,要知道BFC不是全能,創建BFC的初衷只是為了讓元素本身(包括它的子元素)能夠正確的計算自己的寬高。http://www.yuiblog.com/blog/2010/05/19/css-101-block-formatting-contexts
不發生摺疊的觸發因素是浮動元素、inline-block 元素、絕對定位元素,這個只是創建BFC因素的子集,但並不能說明創建了BFC的元素就不會發生摺疊,因為BFC還可以用overflow:hidden來創建。相反如果父元素觸發了BFC,那麼他的塊級子元素反而會發生摺疊。
這裡我寫了一個DEMO來說明這個問題:http://whycss.com/demo/collspan_demo.html 創建BFC的三種情況都提到了,結果是子元素的上下margin都會發生摺疊 。
克軍提到的最後一個zoom,這是IE瀏覽器最初支持的縮放屬性,到現在只有最新的webkit核心的瀏覽器也支持。但只是在IE8以下的瀏覽器下才可成功觸發hasLayout,對於非IE瀏覽器也是沒有效果的,所以還是需要同樣的去創建BFC。關於hasLayout與BFC的介紹可參見本人博客的文章http://www.smallni.com/?p=174
關於最終如何解決這樣的問題,我的建議是在寫的時候盡量用同一方向的margin,比如都設置為top或者bottom,因為你在實踐的時候有時不需要為每個元素設置浮動、inline-block或者absolute 。
我希望大家明白的一點是:即使是再牛逼的大牛,也不可能每個細節都是非常清楚的,前端是一個涉足很深的職業,一個標籤或者一個屬性都可以引申出很多的東西。
我想說,這其實並不(只)是一個技術問題,而是一個設計問題。你應該去問一下,為什麼這裡上下是margin?設計師在這裡表達的是什麼?是否真的應該用margin而不是padding或者border?
規範如此,不是問題@丁小倪 說的對知乎贊同最多的往往只是大家臆想的答案,而不是客觀事實
PS:我最近喜歡看摺疊
生成 BFC 的元素不會和在流中的子元素髮生空白邊摺疊。 不管毗鄰的兄弟的。毗鄰兄弟元素不摺疊由
- Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
- Margins of absolutely positioned boxes do not collapse (not even with their in-flow children).
- Margins of inline-block boxes do not collapse (not even with their in-flow children).
它們決定。
話說,http://w3help.org 都放出來 2 年多了吧,咋就沒啥前端去好好看呢,貌似裡面有些明顯的錯誤也沒人提過。可以採用同一方向的margin值。比如都margin-bottom
觸發block formatting context即可,觸發的方法:1. float不為none2. overflow不為visible3. display設為『table-cell』, 『table-caption』, 或『inline-block』4. position既不是static也不是relative5. zoom:1, IE的hasLayout特性會建立一個新的block formatting context
外邊距疊加其實很正常,主要需要解決的是父層div受到子元素的外邊距的影響,導致子元素的外邊距變成了父元素的外邊距,這個比較煩人,我一般的解決辦法是給父元素加padding-top: 1px;這樣就可以解決了。
老版ie促發layout(zoom:1就ok),其他的塊級格式化(overflow:hidden)
根據 BFC 的定義,兩個元素只有在同一 BFC 內,才有可能發生垂直外邊距的重疊,包括相鄰元素、嵌套元素。要解決 margin
重疊問題,只要讓它們不在同一個 BFC 內就行。對於相鄰元素,只要給它們加上 BFC 的外殼,就能使它們的 margin
不重疊;對於嵌套元素,只要讓父級元素觸發 BFC,就能使父級 margin 和當前元素的 margin 不重疊。在上面的例子中,為了使紅框和綠框的外邊距不重疊,就在它們外部包裹一層 container,並觸發 BFC。
最近也在重溫相關標準.
## 先說解決方法:
把這兩個 & 分別放進兩個建立了 BFC (IE7- 觸發 hasLayout)的父級容器里.demo小倪 和 克軍 說的都沒錯,不過有一點需要明確:需要建立 BFC 的不是這兩個 & 而是它們所在的父級容器.
## 再看看標準(自己翻譯的版本):
邊距疊加條件兩個外邊距僅在以下情況下疊加:- 都屬於常規文檔流(in-flow)中的 block-level boxes,而且處於同一個 BFC
- 沒有 line boxs 、clearance、padding 或者 border 將其分隔(certain zero-height line boxes 除外)
- 都屬於垂直方向上相鄰的盒子的相鄰外邊距,例如:
- 某盒的上邊距 和 其首個在常規文檔流中的子元素的上邊距
- 某盒的下邊距 和 其下個在常規文檔流中的兄弟元素的上邊距
- height 為 auto 的父級元素的下邊距 和 其最後一個在常規文檔流中的子元素的下邊距
- 某盒子沒有建立新 BFC、min-height 為 0、height 為 auto 或 0、沒有常規文檔流子元素,其上下邊距
- 浮動元素和絕對定位元素
- 非塊級盒子的塊級容器(例如 inline-blocks, table-cells, 和 table-captions)
- overflow 屬性不為「visiable」的塊級盒
## 自己的理解:
根據標準給出的建立 BFC 的方法,demo 中的 ein 盒和 zwei 盒(為它們的內容)建立了新的BFC,因此分別處於兩個 BFC 中的 box-a 和 box-b 不滿足邊距疊加條件,邊距不疊加.而drei 盒 和 vier 盒 出現了外邊距疊加. 根據標準中的邊距疊加條件,兩盒需要在同一個BFC中.## 那麼問題來了(很遺憾,這裡沒有挖掘機):
它們處在哪一個 BFC 中呢?最初的猜想是它們處於同一個由 & 元素創建的 BFC 中.
原因是 & 元素默認具有 overflow:auto,滿足建立 BFC 的條件.可惜暫時沒有在標準中找到相關內容.
於是在 stackoverflow 上問了個問題: Does the initial containing block establish a block formatting context(BFC)?回復中有人說:Google到一篇中文博客:CSS BFC和IE Haslayout介紹裡面寫到:The html element is located in the initial containing block which always establishes a block formatting context.
從上面的定義我們可以看到Document顯示HTML元素的方式和BFC的定義很像,其實我們可以認為Document就是最大的一個擁有BFC的元素了。
暫時引用 stackoverflow 上 BoltClock 的說法作為結論:
initial containing block 建立了一個 BFC ,使其中的盒產生了邊距疊加.待完善,繼續查標準..
* 專業知識有限,標準中不確定標準中文名稱的專有名詞未翻譯、並給出鏈接,以防謬誤.這個問題也困擾了我很長時間,反覆找了很多資料看都沒真正明白,包括在知乎的這道問題里的答案還是沒能讓我真正理解原因。直到看到這篇博客中的內容讓我真正明白了外邊距疊加問題,尤其是包含關係下的外邊距疊加。特搬運來此,可能您的問題已經早已解決,但希望其他不太懂的人能看到這個回答從而真正解決困惑。原文地址:CSS概念 - 可視化格式模型(一) 盒模型與外邊距疊加1、相鄰元素疊加
- 這個比較好理解, 相鄰的兩個元素, 如果它們的上下邊距相遇,即會產生疊加。
2、包含(父子)元素疊加
- 包含元素的外邊距隔著父元素的內邊距和邊框, 當這兩項都不存在的時候, 父子元素垂直外邊距相鄰, 產生疊加。 添加任何一項即會取消疊加。(說白了,就是只要有「東西」阻隔斷子父外邊距,那麼就不會產生邊距的疊加問題,這個東西可能是父標籤中的內容、邊框或者內邊距)
- 只有普通文檔流中塊框的垂直外邊距才會發生外邊距疊加。 行內框、 浮動框或絕對定位框之間的外邊距不會疊加。
第一個元素設置:display: inline-block;即可
上下兩個盒子結構,只給其中一個盒子加外邊距,比如給上盒子加margin-bottom,或者給下盒子加margin-top 父級結構,給父盒子加overflow:hidden最近剛學的前端,如果寫的回答有錯誤請指正
加一個父元素,再讓父元素變成BFC太麻煩。外邊距重疊有道理,那麼BFC不重疊不是一樣有道理?還有為什麼只是垂直重疊,沒有水平重疊?
你這裡是兩個非浮動的塊級元素,每個塊級元素佔一行。只有兩個非浮動的塊級元素上下毗鄰,才會垂直邊距重疊。
我的理解:margin垂直重疊的意思大概是每行之間可以設置外邊距,但外邊距就是表示該行與其他行邊界的距離,兩行都有外邊距,那就取其中的最大值。針對的是行,也就是非浮動的塊級元素。而行與行之間只有垂直的邊距關係。
至於行內元素,或是浮動元素,它們的任何邊距都不會重疊。
那麼,兩個元素其中之一設置為inline-block就不會重疊了。但這種做法可能不太符合設計思想。最好是用padding,或者inline-block元素寬度100%,或者避免margin相向。
最好的解決方法就是只用上或只用下邊距。父元素和子元素的外邊距疊加就觸發bfc。
外邊疊加是正確的渲染方式,如果覺得外邊疊加是錯的說明你的layout是錯誤的
最好的方法是少用和不用padding,padding在ie6下問題很多
推薦閱讀:
※自學前端開發1個半月, 在我現在基礎的前提下,如何在7月份離職的時候能找到一份前端的實習機會」。 ?
※如何刪除多餘無用的css?
※用CSS固定footer在底部的疑問?
※有沒有前端性能優化知識推薦,包括css和js?