2017-07-20: 關於外邊距摺疊, 推薦問題: https://segmentfault.com/q/10...css
URL: http://www.w3.org/TR/CSS2/box...html
Translator : HaoyCnsegmentfault
Date: 15th of Aug, 2015app
譯者注:本譯文僅擇精要部分翻譯了規範,主要描述了盒模型結構,以及重點分析外邊距摺疊。我的水平有限,歡迎指正!佈局
CSS盒模型所描述的矩形盒由文檔樹內的元素生成,根據視覺格式化模型佈局。ui
每一個盒都有一個內容區域 Content
(如,文本,圖片等)以及可選的圍繞在周圍的內邊距、邊框和外邊距區域;每一個區域的大小由本文後述的屬性指定。下圖展現了這些區域的關聯以及用於描述外邊距、邊框和內邊距的各部分的術語。spa
外邊距、邊框和內邊距能夠被分解到上、右、下、左各部分(如,在上圖中, LM
表示左外邊距, RP
表示右內邊距, TB
表示上邊框等)。翻譯
四種區域(內容、內邊距、邊框、外邊距)的邊界被稱做一個「邊緣 Edge
」,所以每一個盒有四種邊緣:代理
內容邊緣 Content Edge
或內邊緣 Inner Edge
code
內容邊緣圍繞着由盒的寬和高所指定的矩形,該矩形一般由元素的已渲染內容 Rendered Content
所決定。四個內容邊緣規定了盒的內容盒 Content Box
。
內邊距邊緣
內邊距邊緣圍繞着盒的內邊距。若是內邊距寬度爲0,則內邊距邊緣便是內容邊緣。四個內邊距邊緣規定了盒的內邊距盒 Padding Box
。
邊框邊緣
邊框邊緣圍繞着盒的邊框。若是邊框寬度爲0,則邊框邊緣便是內邊距邊緣。四個邊框邊緣規定了盒的邊框盒 Border Box
。
外邊距邊緣或外邊緣
外邊距邊緣圍繞着盒的外邊距。若是外邊距寬度爲0,則外邊距邊緣即邊框邊緣。四個外邊距邊緣規定了盒的外邊距盒 Margin Box
。
每一個邊緣均可以被分解成上、右、下、左邊緣。
盒內容區域的尺寸——即內容寬度 Content Width
和內容高度 Content Width
——由這些因素所決定:生成盒的元素是否設置了 width
和 height
屬性;盒是否包含了文本或其餘盒;盒是否爲表格;等等。盒的寬度和高度將在視覺格式化模型詳述一章中討論。
盒的內容、內邊距以及邊框區域的背景樣式由生成盒的元素的 background
屬性所規定。外邊距的背景始終爲透明。
下例展現了外邊距、內邊距和邊框如何交互。HTML文檔:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html> <head> <title>Examples of margins, padding, and borders<title> <style type="text/css"> ul { background: yellow; margin: 12px 12px 12px 12px; padding: 3px 3px 3px 3px; /* 未設置邊框 */ } li { color: white;/* 文本顏色爲白色 */ background: blue;/* 內容和內邊距背景爲藍色 */ margin: 12px 12px 12px 12px; padding: 12px 0px 12px 12px; /* 注意右內邊距爲0 */ list-style: none/* 列表前沒有符號 */ /* 未設置邊框 */ } li.withborder { border-style: dashed; border-width: medium;/* 各邊均設置邊框 */ border-color: lime; } </style> </head> <body> <ul> <li>First element of list</li> <li class="withborder">Second element of list is a bit longer to illustrate wrapping.</li> </ul> </body> </html>
該文檔結果爲文檔樹中(省略其餘關係)一個 ul
元素及其兩個 li
子元素。
下面的第一圖展現了例子的結果。第二圖展現了 ul
元素及其 li
子元素的外邊距、內邊距和邊框之間的關係。(圖片不成比例)
注意:
每一個 li
盒的內容寬度是從上到下計算的;全部 li
盒的包含塊由 ul
元素建立。
每一個 li
盒的外邊距盒高度由其內容高度加上上下內邊距、邊框、外邊距所決定。須要留意的是 li
盒間的垂直外邊距發生了摺疊。
li
盒的右內邊距寬度被設爲零( padding
屬性)。效果如第二圖所示。
li
盒的外邊距是透明的——外邊距總爲透明——因此 ul
的內邊距和內容區域的背景顏色(黃)穿透外邊距顯示了出來。
第二個 li
元素指定了虛線邊框( border-style
屬性)。
外邊距的各屬性規定了盒的外邊距區域的寬度。 margin
設置全部四個方向的外邊距,而其餘外邊距屬性則只設置各自方向寬度。這些屬性應用於全部元素,但垂直外邊距在非替代行內元素上無效。
譯者注:此處以及下文的各屬性介紹均略,可查CSS手冊
在CSS中,兩個及以上的(不必定是同胞)盒的相鄰外邊距可能合併爲一個單獨的外邊距。以這種方式的合併的外邊距被稱爲摺疊 Collapse
,合併後的外邊距被稱爲摺疊外邊距 Collapsed Margin
。
相鄰垂直外邊距發生摺疊,除了:
根元素的盒的外邊距不折疊
若是一個有空隙的元素的上下外邊距相鄰,其外邊距將同其後同胞的相鄰外邊距摺疊,但不一樣父塊的下外邊距摺疊。
水平外邊距不重疊。
兩個外邊距爲相鄰關係,當且僅當:
是同屬一個塊格式化上下文的文檔流內塊級盒
沒有行盒、空隙、內邊距和邊框分隔它們(注意某些零高度行盒會所以而被忽略(見9.4.2章))
盒邊緣垂直相鄰,也就是說,知足如下形式之一:
盒上外邊距及其第一個文檔流內子盒的上外邊距
盒下外邊距及下一個文檔流內的同胞盒的上外邊距
若是父盒的高度計算值爲 auto
,其最後一個文檔流內子盒的下外邊距及父盒的下外邊距
若是一個盒不創建新的塊格式化上下文、 min-height
計算值爲零、 height
計算值爲零或 auto
、沒有在文檔流內的子盒,其上下外邊距
若是一個摺疊外邊距與另外一外邊距的任何一邊相鄰,則視兩者相鄰。
注意:不是同胞或祖先關係的元素也能夠產生相鄰外邊距。
注意:上述規則代表了:
浮動盒的外邊距不一樣其餘任何盒摺疊(甚至浮動及其文檔流內的子元素也不折疊)
建立了新的塊格式化上下文的元素(如浮動、 overflow
不爲 visible
的元素)的外邊距不一樣其在文檔流內的子元素外邊距摺疊
絕對定位盒的外邊距不一樣其餘任何盒摺疊(甚至不一樣其文檔流內的子元素摺疊)
行內塊盒的外邊距不一樣其餘任何盒摺疊(甚至不一樣其文檔流內的子元素摺疊)
文檔流內塊級元素的下外邊距始終同其下一個文檔流內的塊級同胞的上外邊距摺疊,除非該對同胞之間有空隙。
文檔流內塊元素若是沒有上邊框和上內邊距,其第一個文檔流內塊級子元素沒有空隙,兩者的上外邊距摺疊。
文檔流內 height
爲 auto
、 min-height
爲零、沒有下內邊距和下邊框的塊盒,若是其最後一個文檔流內塊級子盒的下外邊距沒有同一個有空隙的上外邊距摺疊,兩者下外邊距摺疊。
若是某盒的 min-height
屬性爲零、沒有上下邊框和上下內邊距、其 height
爲0或 auto
、沒有包含行盒、其全部的文檔流內子元素外邊距(若是有)摺疊,則摺疊其外邊距。
當兩個及以上外邊距摺疊,合併後的外邊距寬度是發生摺疊的外邊距中的最大寬度。若是發生摺疊的外邊距中有負數,則爲最大正數相鄰外邊距減去最小負數相鄰外邊距的絕對值。若是不存在正數外邊距,則爲零減去最小負數相鄰外邊距的絕對值。
若是一個盒的上下外邊距相鄰,則外邊距可能穿過盒而摺疊 Collapse Through It
。這種狀況下,元素的定位取決於它同其餘外邊距摺疊的元素的關係。
若是該元素的外邊距同其父元素的上外邊距摺疊,則該盒的上邊框邊緣同其父元盒的上邊框邊緣相同。
不然,要麼該元素的父元素的外邊距不折疊,要麼只有父元素的下外邊距摺疊。上邊框邊緣位置是假定該元素下邊框非零時的位置。
須要注意的是,被摺疊穿過的元素的定位對與以外邊距摺疊的其餘元素的定位無影響;其上邊框邊緣的定位僅用於佈局其後代元素。
對每一個行盒而言,用戶代理必須按視覺順序(而非邏輯順序)渲染其生成的行內盒的外邊距、邊框和內邊距。
當元素 direction
屬性值爲 ltr
,元素呈現的第一個行盒的最左生成盒擁有左外邊距、左邊框和左內邊距,而元素呈現的最後一個行盒的最右生成盒擁有右內邊距、右邊框和右外邊距。
當元素 direction
屬性值爲 rtl
,元素呈現的第一個行盒的最右生成盒擁有右外邊距、右邊框和右內邊距,而元素呈現的最後一個行盒的最左生成盒擁有左內邊距、左邊框和左外邊距。
譯者讀畢此文,細心揣摩,將經驗和疑問總結以下:
本章節描述了W3C的標準盒模型,同時還存在IE6在怪異模式 Quicks Mode
的另外一種盒模型。此處簡述兩者的區別以下——
W3C標準下:盒總寬/高度 = width/height + padding + border + margin
怪異模式下:盒總寬/高度 = width/height + margin = 內容寬/高度 + padding + border + margin
CSS3中, box-sizing
默認爲 content-box
,即採用W3C標準盒模型,若取值 border-box
則採用怪異模式盒模型。
CSS規範道:
盒的內容、內邊距以及邊框區域的背景樣式由生成盒的元素的
background
屬性所規定。外邊距的背景始終爲透明。
但在根元素 html
上設置了外邊距,並規定了背景,該背景仍鋪滿全屏。
以下CSS:
html { margin: 50px; background: #000; }
body
同此理。譯者暫不知其因。歡迎讀者指教。
外邊距摺疊中,不少地方敘述了「有空隙的元素」,這是什麼意思呢?其意義便是說,該元素清除了浮動。
在翻譯視覺格式化模型一章中,W3C給出了清除浮動以及計算空隙寬度的的案例,譯者建議讀者認真閱讀該部分,尤爲關注:當空隙爲負值時取消外邊距摺疊的情形。
點此閱讀:http://segmentfault.com/a/119...。
若是讀者已經掌握清除浮動和空隙的知識,那就讓咱們來看一個有空隙的情景。
若是一個有空隙的元素的上下外邊距相鄰,其外邊距將同其後同胞的相鄰外邊距摺疊,但不一樣父塊的下外邊距摺疊。
如下代碼中, B
是浮動塊,爲清除其浮動, C
引入了空隙。
共同CSS:
html,body{padding:0;margin:0;} /*橫線,直觀對比摺疊狀況*/ .line{height:50px;background:red;} .mt{margin-top:50px;} .mb{margin-bottom:50px;} #B{float:left;width:1px;height:1px;} #C{clear:both;}
其外邊距將同其後同胞的相鄰外邊距摺疊:
HTML:
<body> <div id="A"> <div id="B"></div> <div id="C" class="mb"></div> <div id="D" class="mb"></div> <div class="line"></div> </div> </body>
渲染結果是, C
和 D
的外邊距摺疊。
不一樣父塊的下外邊距摺疊
HTML:
<body> <div id="A" class="mb"> <div id="B"></div> <div id="C" class="mb"></div> </div> <div class="line"></div> </body>
渲染結果是, C
的外邊距不一樣其父元素 A
的外邊距摺疊。
若是一個盒不創建新的塊格式化上下文、
min-height
計算值爲零、height
計算值爲零或auto
、沒有在文檔流內的子盒,其上下外邊距
由此能夠得出幾種避免盒自身上下外邊距摺疊的辦法,簡單列舉以下:
創建新塊格式化上下文,如 overflow: hidden
設置 min-height
設置固定高 height
添加文檔流內(即非浮動、非絕對定位)子盒
須要注意最後一種辦法,子盒要麼有邊框或內邊距,要麼有內容,不然父盒的自身垂直外邊距一樣會摺疊。而若是子盒只有垂直外邊距,該垂直外邊距將同父盒的垂直外邊距摺疊,而不會阻止父盒自身垂直邊距摺疊。