寫css,你少不了與margin打交道。你真的瞭解margin嗎?你知道margin有什麼特性嗎?你知道什麼是垂直外邊距合併?margin在塊元素、內聯元素中的區別?何時該用padding而不是margin?你知道負margin嗎?你知道負margin在實際工做中的用途嗎?常見的瀏覽器下margin出現的bug有哪些?……css
CSS 邊距屬性定義元素周圍的空間。經過使用單獨的屬性,能夠對上、右、下、左的外邊距進行設置。也可使用簡寫的外邊距屬性同時改變全部的外邊距。——W3Schoolhtml
邊界,元素周圍生成額外的空白區。「空白區」一般是指其餘元素不能出現且父元素背景可見的區域。——CSS權威指南html5
我比較喜歡使用「外邊距」這個詞來解釋margin(同理padding能夠稱之爲「內邊距」,可是我又偏偏喜歡稱呼padding爲「補白」或者「留白」),咱們能夠很清楚的瞭解到margin的最基本用途就是控制元素周圍空間的間隔,從視覺角度上達到相互隔開的目的。瀏覽器
margin始終是透明的。margin經過使用單獨的屬性,能夠對上、右、下、左的外邊距進行設置。即:margin-top、margin-right、margin-bottom、margin-left。app
外邊距的 margin-width 的值類型有:auto | length | percentage。也可使用簡寫的外邊距屬性同時改變全部的外邊距:margin: top right bottom left;(eg: margin:10px 20px 30px 40px) 記憶方式是元素周圍正上方順時針「上右下左」記憶。ide
而且規範還提供了省略的數值寫法,基本以下:佈局
在實際應用中,我的不推薦使用三個值的margin,一是容易記錯,二是不容易往後修改,一開始若是寫成margin:10px 20px 30px;往後需求改動爲上10px,右30px,下30px,左20px,你不得不仍是得把這個margin拆開爲margin:10px 30px 30px 20px;費力且不討好,不如一開始就老老實實的寫成margin:10px 20px 30px 20px;來的實在,不要爲了如今節省倆個字節而讓往後再次開發的成本上升。性能
別被上面這個名詞給嚇倒了,簡單地說,外邊距合併指的是,當兩個垂直外邊距相遇時,它們將造成一個外邊距。合併後的外邊距的高度等於兩個發生合併的外邊距的高度中的較大者。你能夠查看W3Shool CSS外邊距合併瞭解這個基本知識。學習
實際工做中,垂直外邊距合併問題常見於第一個子元素的margin-top會頂開父元素與父元素相鄰元素的間距,並且只在標準瀏覽器下(FirfFox、Chrome、Opera、Sarfi)產生問題,IE下反而表現良好。例子能夠查看下面代碼(IE下表現「正常」,標準瀏覽器下查看出現「bug」):ui
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>垂直外邊距合併</title> <style> .top{width:160px; height:50px; background:#ccf;} .middle{width:160px; background:#cfc;} .middle .firstChild{margin-top:20px;} </style> </head> <body> <div class="top"></div> <div class="middle"> <div class="firstChild">我其實只是想和個人父元素隔開點距離。</div> <div class="secondChild"></div> </div> </body> </html>
若是按照CSS規範,IE的「良好表現」實際上是一個錯誤的表現,由於IE的hasLayout渲染致使了這個「表現良好」的外觀。而其餘標準瀏覽器則會表現出「有問題」的外觀。好了,若是你讀過了上面W3Shcool的CSS外邊距合併的文章後,就很容易討論這個問題了。這個問題發生的緣由是根據規範,一個盒子若是沒有上補白(padding-top)和上邊框(border-top),那麼這個盒子的上邊距會和其內部文檔流中的第一個子元素的上邊距重疊。
再說了白點就是:父元素的第一個子元素的上邊距margin-top若是碰不到有效的border或者padding.就會不斷一層一層的找本身「領導」(父元素,祖先元素)的麻煩。只要給領導設置個有效的 border或者padding就能夠有效的管制這個目無領導的margin防止它越級,假傳聖旨,把本身的margin當領導的margin執行。
對於垂直外邊距合併的解決方案上面已經解釋了,爲父元素例子中的middle元素增長一個border-top或者padding-top便可解決這個問題。
通常說來這個問題解釋到這裏,大多數文章就不會再深刻下去了,但做爲一名實戰開發者,最求的是知其然知其因此然,本來使用margin-top就是爲了與父元素隔開距離,而按照你這麼一個解法,實際上是一種「修復」,爲了「彌補修復」這個父子垂直外邊距合併這個CSS規範「Bug」,而強制在父元素上使用border-top和padding-top,不舒服,也不容易記住,下次再發生這樣的狀況仍是會忘記這條準則,並且在頁面設計稿裏若是不須要border-top加個上邊框,這麼一加反而多此一舉,爲之後修改留下隱患。
什麼時候應當使用margin:須要在border外側添加空白時。空白處不須要背景(色)時。上下相連的兩個盒子之間的空白,須要相互抵消時。如15px + 20px的margin,將獲得20px的空白。
什麼時候應當時用padding:須要在border內測添加空白時。空白處須要背景(色)時。上下相連的兩個盒子之間的空白,但願等於二者之和時。如15px + 20px的padding,將獲得35px的空白。
我的認爲:margin是用來隔開元素與元素的間距;padding是用來隔開元素與內容的間隔。margin用於佈局分開元素使元素與元素互不相干;padding用於元素與內容之間的間隔,讓內容(文字)與(包裹)元素之間有一段「呼吸距離」。
HTML(這裏說的是html標準,而不是xhtml)裏分兩種基本元素,即block和inline。顧名思義,block元素就是以」塊」表現的元素(block-like elements),inline元素便是以」行」表現的元素(character level elements and text strings)。兩者表現的主要差異在於,在頁面文檔中block元素另起一行開始,並獨佔一行。inline元素則同其餘inline元素共處一行。
block元素(塊元素)大體有:P|H1|H2|H3|H4|H5|H6|UL|OL|PRE| DL | DIV | NOSCRIPT | BLOCKQUOTE | FORM | HR | TABLE | FIELDSET | ADDRESS(隨着html5標準的推動,一些元素將被廢除,而一些新的元素將被引入)注意的是並不是全部的block元素的默認display屬性都是block,像table這種display:table的元素也是block元素。
inline元素(內聯元素)大體有:#PCDATA(即文本)| TT | I | B | BIG | SMALL|EM | STRONG | DFN | CODE |SAMP | KBD | VAR | CITE | ABBR | ACRONYM|A | IMG | OBJECT | BR | SCRIPT | MAP | Q | SUB | SUP | SPAN | BDO|INPUT | SELECT | TEXTAREA | LABEL | BUTTON
其中有類特殊的元素:如img|input|select|textarea|button|label等,他們被稱爲可置換元素(Replaced element)。他們區別通常inline元素(相對而言,稱non-replaced element)是:這些元素擁有內在尺寸(intrinsic dimensions),他們能夠設置width/height屬性。他們的性質同設置了display:inline-block的元素一致。
或許有朋友對非置換元素(non-replaced element)有點疑惑,稍微幫助你們理解一下。非置換元素,W3C 中沒有給出明確的定義,但咱們從字面能夠理解到,非置換元素對應着置換元素(replaced element),也就是說咱們搞懂了置換元素的含義,就懂了非置換元素。置換元素,W3C中給出了定義:「An element that is outside the scope of the CSS formatter, such as an image, embedded document, or applet」
從定義中咱們能夠理解到,置換元素(replaced element)主要是指 img, input, textarea, select, object 等這類默認就有 CSS 格式化外表範圍的元素。進而可知,非置換元素(non-replaced element)就是除了 img, input, textarea, select, object 等置換元素之外的元素。
margin在塊級元素下,他的性能能夠徹底體現,上下左右任你設定。且記住塊級元素的margin的參照基準是前一個元素即相對於自身以前的元素有margin距離。若是元素是第一個元素,則就是相對於父元素的margin距離(但第一個元素相對於父元素margin-top而父元素又沒有設定padding-top/border-top的話要須要印證上面的垂直外邊距合併的知識)
margin也能用於內聯元素,這是規範所容許的,可是margin-top和margin-bottom對內聯元素(對行)的高度沒有影響,而且因爲邊界效果(margin效果)是透明的,他也沒有任何的視覺影響。
這是由於邊界應用於內聯元素時不改變元素的行高度,若是你要改變內聯元素的行高即相似文本的行間距,那麼你只能使用這三個屬性:line-height,fong-size,vertical-align。請記住,這個影響內聯元素高度的是line-height而不是height,由於內聯元素是一行行的,定一個height的話,那這究竟是整段inline元素的高呢?仍是inline元素一行的高呢?這都說不許,因此統一都給每行定一個高,只能是line-height了。
margin-top/margin-bottom對內聯元素沒有多大實際效果,不過margin-left/margin-right仍是可以對內聯元素產生影響的。應用margin:10px 20px 30px 40px;,左邊這個css若是寫在inline元素上,他的效果大體是,上下無效果,左邊離他相鄰元素或者文本距離爲40px,右邊離他相鄰元素或者文本距離爲20px。你能夠自行嘗試一番。
最後在內聯元素中還有上文咱們提到的非可置換inline元素(non-replaced element),這些個元素img|input|select|textarea|button|label雖然是內聯元素,但margin依舊能夠影響到他的上下左右!
總結下來margin 屬性能夠應用於幾乎全部的元素,除了表格顯示類型(不包括 table-caption, table and inline-table)的元素,並且垂直外邊距對非置換內聯元素(non-replaced inline element)不起做用。
在margin全部的實際應用中,負margin技術是我學習css路上最重要一課之一,許多高級應用和頁面上的疑難雜症均可以用負margin技術來實現。margin技術是那麼的有用,限於篇幅我又不想草草了事,因此我決定專門爲他寫一篇文章,詳細的說明他的效果、原理、及其應用。在此以前你能夠先閱讀懌飛寫的由淺入深漫談margin屬性這篇文章,大體瞭解「margin參考線」的概念,以後再來查看負margin技術及其應用這篇文章。
林林總總寫了那麼多,最後總結一些瀏覽器中常見的margin Bug吧,之後遇到margin下的佈局問題能夠查看這裏找到解決的方案,若是你還發現其餘關於瀏覽器下margin的Bug你能夠發表留言,覈對採納後我會及時添加進去,感謝你的分享。
IE6中雙邊距Bug:
IE6中浮動元素3px間隔Bug:
IE6/7負margin隱藏Bug:
IE6/7下ul/ol標記消失bug:
IE6/7下margin與absolute元素重疊bug:
IE6/7/8下auto margin居中bug:
IE8下input[button | submit] 設置margin:auto沒法居中
IE8百分比padding垂直margin bug: