【轉】深刻理解margin

元素盒模型

margin 在中文中咱們翻譯成外邊距或者外補白(本文中引用外邊距)。他是元素盒模型(box model)的基礎屬性。html

1、margin的基本特性chrome

margin 屬性包括 margin-top, margin-right, margin-bottom, margin-left, margin,能夠用來設置 box 的 margin area。屬性 margin 能夠用來同時設置 box 的四邊外邊距,而其餘的 margin 屬性只能設置其自各的外邊距。express

margin 屬性能夠應用於幾乎全部的元素,除了表格顯示類型(不包括 table-caption, table and inline-table)的元素,並且垂直外邊距對非置換內聯元素(non-replaced inline element)不起做用。瀏覽器

或許有朋友對非置換元素(non-replaced element)有點疑惑,稍微幫助你們理解一下。非置換元素,W3C 中沒有給出明確的定義,但咱們從字面能夠理解到,非置換元素對應着置換元素(replaced element),也就是說咱們搞懂了置換元素的含義,就懂了非置換元素。置換元素,W3C中給出了定義:app

「An element that is outside the scope of the CSS formatter, such as an image, embedded document, or applet」less

從定義中咱們能夠理解到,置換元素(replaced element)主要是指 img, input, textarea, select, object 等這類默認就有 CSS 格式化外表範圍的元素。進而可知,非置換元素(non-replaced element)就是除了 img, input, textarea, select, object 等置換元素之外的元素。ide

margin 始終是透明的。佈局

2、margin 的基本寫法post

外邊距的 margin-width 的值類型有:auto | length | percentage

percentage:百分比是由被應用 box 的containing block(注:一個元素的 containing block 是該元素產生的 box(es)在計算位置和大小時參考的一個矩形)的大小所決定。對於 margin-top 和 margin-bottom 也一樣成立。

margin 的默認值爲 0,而且 margin 支持負值。

上面咱們曾提到屬性 margin 能夠用來同時指定 box 的四邊外邊距。若是屬性 margin 有四個值,那麼值將按照上-右-下-左的順序做用於四邊,即從元素的上邊開始,按照順時針的順序圍繞元素。表達式以下:

margintop right bottom left

四個數值中間以空格分隔。效果等同於:

margin-top:value;
margin-right:value;
margin-bottom:value;
margin-left:value;

而且規範還提供了省略的數值寫法,基本原則以下:

  1. 若是沒有 left 值,則使用 right 代替;
  2. 若是沒有 bottom 值,則使用 top 代替;
  3. 若是沒有 right 值,則使用 top 值代替。

根據這些基本原則,咱們能夠有三種省略方式,但無論怎樣省略 margin 的數值都會大於等於一個,而 margin 的默認數值是從 top 開始至 left 結束,那麼對於省略的具體狀況,咱們能夠從 left 反推理回去。

一、若是 margin 只有三個值,按照值的順序爲 margin:top right bottom; 缺乏了 left,根據原則,則 left 的值有 right 來代替。margin:10px 20px 30px; 就等於 margin:10px 20px 30px 20px;

二、若是 margin 只有兩個值,按照值的順序爲 margin:top right; 缺乏了 bottom 和 left,根據原則 left 的值由 right 來代替,bottm 的值由 top 來代替。margin:10px 20px; 就等於 margin:10px 20px 10px 20px;

三、若是 margin 只有一個值,按照值的順序爲 margin:top; 缺乏了 bottom、left 和 right,根據原則 left 的值由 right 來代替,bottom 的值由 top 來代替,right 的值右 top 來代替,也就是說 left 的值也由 top 來代替。margin:10px; 就等於 margin:10px 10px 10px 10px;

3、margin的解析邏輯

目前咱們已經瞭解到了 margin 的基本特性和基本寫法,但對元素 margin 的基本解析邏輯仍是很模糊,到底 margin 的 top、right、bottom、left 都是以什麼爲基準來促使 box model 造成。爲了形象,易懂的對 margin 的邏輯進行說明,下面講解的過程當中,將引入 W3C 上沒有的參考線的說法。何謂參考線?參考線就是 margin 移動的基準點,此基準點相對於 box 是靜止的。而 margin 的數值,就是 box 相對於參考線的位移量。

在 margin 中 top、right、bottom、left 的參考線並不一致爲一類,而是分爲了兩類參考線,top 和 left 的參考線屬於一類,right 和bottom 的參考線屬於另外一類。那他們到底各以什麼爲參考線呢?top 以 containing block 的 content 上邊或者垂直上方相連元素 margin 的下邊爲參考線垂直向下位移;left 以 containing block 的 content 左邊或者水平左方相連元素 margin 的右邊爲參考線水平向右位移。right 以元素自己的 border 右邊爲參考線水平向右位移;bottom 以元素自己的border 下邊爲參考線垂直向下位移。從上咱們能夠看到 top 和 left 都是之外元素爲參考,而 right 和 bottom 以本元素爲參考。上面的位移方向是指 margin 數值爲正值時候的情形,若是是負值則位移方向相反。

margin的移動示例圖

或許理論聽起來比較枯燥,咱們舉例說明一下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>無標題文檔</title>
<style type="text/css">
div {
        width:200px;
        height:200px;
        background:#ccc;
}
</style>
</head>    

<body>
        <div>外邊距的margin-width的值類型有:auto | length | percentage</div>
</body>
</html>

如上代碼,很簡單,爲了方便咱們看到效果,咱們給 div 設置了寬度和高度以及背景色。

如今咱們給 div 的樣式加上 margin 屬性,好比:

margin:-10px 20px -30px 40px;

這時候 margin 的解析邏輯是怎樣的呢?首先咱們要搞清 div 的和周邊元素的關係,div 沒有相連元素,而此時 div 的 containing block 是 body 產生的 block box。則根據上面介紹的參考線原理,div 的左外邊距以 containing block 的 content 左邊爲參考線,及此時以 body 的 content 左邊爲參考線進行水平向右位移,位移的大小爲 40px,同理,上邊距以 body 的 content 上邊爲參考線進行垂直向上位移 10px(負值和正值的方向相反),下邊距依照如今 div 的 borer 下邊(此時的 div 已經通過上邊距位移過了)垂直向上位移 30px(此時,margin 不會改變 box 的 border 內的物理大小,但會改變 box 的邏輯大小,即:以此 box 的 margin 的下邊爲參考的元素,不是從 box 的物理位置開始的,而是從邏輯位置開始),右邊距依照如今 div 的 borer 右邊(此時的 div 已經通過左邊距位移過了)水平向右位移 20px。或許有朋友問你分析的順序怎麼和 margin 表達式中出現的順序不同?若是按照 margin 表達式中出現的順序來分析,結果是同樣的,只是爲了更好的方便你們的理解而沒有按照表達式的順序來分析。

margin的詳解

用 margin 最後的實際顯示大小的究竟是怎麼樣呢,或許有朋友也比較疑惑,我暫時用邏輯大小和物理大小來區分(其實上面已用到此概念),到底什麼是邏輯大小,什麼是物理大小呢?!具體能夠看圖,物理大小指的是除去 margin,也就是包含 border 之內的 box 大小,而邏輯大小,則是 box 經過 margin 解析規則解析後獲得的大小(這或許能夠解釋爲何IE5會錯誤解析盒模型)。在上圖中,box 的實際顯示的寬度等於 box 的邏輯大小,而 box 實際顯示的高度等於 box 的物理大小,這說明 box 實際顯示的大小多是 box 的邏輯大小,也多是 box的 物理大小,規則究竟是怎樣的——

box 的實際大小 = box 的物理大小 + 正的 margin

這僅對元素自己有效,對於其後面的相關元素,他們則只以 margin 的邏輯大小爲準則,進行佈局。

有朋友反應,聽得很迷糊,越看越不懂,若是你對具體的理解過程不感興趣的話,那記住下面我總結的結論就能夠了,XD

結論:

box 最後的顯示大小等於 box 的 border 及 border 內的大小加上正的 margin 值。而負的 margin 值不會影響 box 的實際大小,若是是負的 top 或 left 值會引發 box 的向上或向左位置移動,若是是 bottom 或 right 只會影響下面 box 的顯示的參考線。

相關文章
相關標籤/搜索