這次給大家帶來css中的margin屬性詳解,使用css中margin的注意事項有哪些,下面就是實戰案例,一起來看一下。
之前我一直認為margin屬性是一個非常簡單的屬性,但是最近做項目時遇到了一些問題,才發現margin屬性還是有一些“坑”的,下面我會介紹margin的基本知識以及那些“坑”。這篇博文主要分為以下幾個部分:
第一部分:margin--基礎知識
要介紹margin的基礎知識,我們不可迴避地要談到css盒子模型(Box Model),一般而言,css盒子模型是用來設計和布局的。它本質上是一個盒子,包括:外邊距(margin)、邊框(border)、內邊距(padding)以及最中間的內容(content)。即為盒子模型(這裡只談W3C規範的標準盒模型,而不談IE5和IE6在怪異模式中使用的非標準的盒子模型):
我們要介紹的margin在最外層,因為margin(外邊距)一定是透明的,所以它可以用來使得不同的盒子之間留有一定的間隙從而達到布局美觀等效果。從上面的盒子模型中我們可以看到,margin在四周均存在,我們可以使用margin-top、margin-right、margin-bottom、margin-left分別設定這四個方向的margin值。(註:由於這部分知識較為基礎,所以我不再在這部分不做更多介紹)
第二部分:margin--在同級元素(非父子關係)之間應用
這一部分主要介紹水平方向和豎直方向的外邊距的合并問題。
(1)水平方向的外邊距合并
兩個水平方向的盒子相遇,那麼最終兩者之間的距離為左邊盒子的右外邊距和右邊盒子的做外邊距之和。
例1:
代碼如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>水平方向的兩個盒子</title> <style> *{ margin:0; padding:0; border:0; } body{ font-size: 0; } .left{ width: 100px; height: 100px; background: red; display: inline-block; margin-right: 50px; font-size: 20px; } .right{ width: 100px; height: 100px; background: yellow; display: inline-block; margin-left: 50px; font-size: 20px; } </style></head><body> <p class="left">寬為100px,右邊距為50px</p> <p class="right">寬為100px,左邊距為50px</p></body></html>
效果如下:
這時兩者之間的距離剛好為100px。
補充說明:大家可以看到,為了使得兩個p(塊狀元素)脫離正常的文檔流我使用了display:inline-block;屬性,另外,我還把body的font-size設定為0,這樣可以解決inline-block自身的問題,否則兩個p的舉例會大於100px。當然使用float也可以使得兩個p出現在同一行中。
(2)豎直方向的外邊距合并
兩個豎直方向的盒子相遇時,其豎直方向的距離等於上方盒子的下外邊距和下方盒子的上外邊距中較大的一個。
例2:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>水平方向的兩個盒子</title> <style> *{ margin:0; padding:0; border:0; } .top{ width: 100px; height: 100px; margin-bottom: 100px; background: red; } .bottom{ width: 100px; height: 100px; margin-top: 50px; background: green; } </style></head><body> <p class="top">高為100px,下邊距為100px</p> <p class="bottom">高為100px,上邊距為50px</p></body></html>
效果如下:
這時我們肉眼都可以觀察出來,兩者豎直方向的舉例大約為100px(實際就是100px)而非100+50=150px;這正是因為兩個豎直方向的盒子相遇時,其豎直方向的距離等於上方盒子的下外邊距和下方盒子的上外邊距中較大的一個。
另外一個有趣的例子就是:假設有一個元素同時設定了margin-top和margin-bottom,但是內容為空白,那麼這兩個margin值也會疊加,值為兩者最大的一個,它類似與豎直方向上兩個盒子margin值的疊加。代碼如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>水平方向的兩個盒子</title> <style> *{ margin:0; padding:0; } .top{ width: 500px; height: 100px; background: red; } .middle{ margin-top: 100px; margin-bottom:50px; } .footer{ width: 500px; height: 100px; background: green; } </style></head><body> <p class="top">上面的p,高100px</p> <p class="middle"></p> <p class="footer">下面的p,高100px</p></body></html>
最終的效果如下:
我們發現這時在上面的p和在下面的p之間的舉例並不是100+50=150px,而是兩者中的最大者,即100px。
那麼W3C為什麼會設定這樣的標準而不設定和水平方向一樣的標準呢?即margin值的疊加,實際上這也是有一定的道理的。比如我們需要設計一個由若干個段落構成的一個頁面。我們需要設定margin-top和margin-bottom使得第一段和頁面的最上方有一段距離,使得最後一段和最下方有一段距離。下面是不疊加和疊加的:
我們可以看到左邊的頁面沒有重疊,那麼兩個段落之間的舉例就是最上方的兩倍間距了,而右邊的頁面發生了重疊,則所有的間距都是相等的。或許這就是這樣設定標準的目的吧,誰知道呢?
第三部分:margin--在父元素和子項目之間應用(重點)
第二部分介紹了同級元素之間使用margin,而這一部分將要介紹最有意思的父元素和子項目之間margin的應用。這一部分,我們同樣從兩個方面來討論。一方面是子項目設定水平方向上的margin值,另一方面是子項目設定豎直方向的margin值。
(1)在子項目中設定水平方向的margin值
我們可以設定margin-left來控制子項目的左邊框和父元素的左邊框之間的舉例。
例3:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>margin</title> <style> *{padding:0; margin:0; border:0;} .father{ width: 500px; height: 500px; background: red; } .son{ width: 100px; height: 100px; background: green; margin-left: 100px; } </style></head><body> <p class="father"> <p class="son">寬度為100px,margin-left為100px。</p> </p></body></html>
我將子項目的margin-left設定為了100px;效果如下:
即子項目的左邊框和父元素的左邊框之間的距離為100px。與在同級元素之間設定margin不同,因為同級元素之間的margin不會考慮到padding,但是在父元素和子項目就不同了,那麼如果父元素中如果有padding,效果會是什麼樣的呢?請看下面一個例子:
例4:
下面我們在上面例子的基礎上給父元素添加padding值。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>margin</title> <style> *{padding:0; margin:0; border:0;} .father{ width: 500px; height: 500px; padding:100px; background: red; } .son{ width: 100px; height: 100px; background: green; margin-left: 100px; } </style></head><body> <p class="father"> <p class="son">寬度為100px,margin-left為100px。</p> </p></body></html>
上面的代碼給父元素添加了100px的padding值,效果如下:
我們可以看到子項目舉例上方的距離為100px,因為子項目一定是在父元素的content的部分的,這點毫無疑問。
但是經過測量可以發現子項目的左邊框距離父元素的左邊框之間的距離為200px,因為其中還有100px的左padding值,前面的例子因為我沒有設定padding值,所以沒有觀察出來,因此這就說明了在子項目中設定margin-left,其值實際上是子項目的左邊框距離父元素左padding內側的距離。
例5:margin-right的使用和margin-left的使用是相似的,我在這裡只舉一個例子。
這個例子在子項目中設定了margin-right值,如下所示:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>margin</title> <style> *{padding:0; margin:0; border:0;} .father{ width: 500px; height: 500px; padding:100px; background: red; } .son{ float: right; width: 100px; height: 100px; background: green; margin-right: 100px; } </style></head><body> <p class="father"> <p class="son">寬度為100px,margin-right為100px。</p> </p></body></html>
這個例子與例4的區別僅在與子項目的位置不同。效果如下:
通過這個例子可以說明margin-right的值是子項目的右邊框和父元素的右padding內側的距離。只是前面的幾個例子我沒有使用padding,所以無法觀察出來。
(2)在子項目中設定豎直方向的margin值
按照前面的經驗,理論上來說,我們同樣可以通過設定margin-top的值使得子項目的上邊框和父元素的上padding的內側留有一定的距離。那麼我們就試試吧!
例6:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>margin</title> <style> *{padding:0; margin:0; border:0;} .father{ width: 500px; height: 500px; background: red; } .son{ width: 100px; height: 100px; background: green; margin-top: 100px; } </style></head><body> <p class="father"> <p class="son">高度為100px,margin-top為100px。</p> </p></body></html>
這個例子我設定了margin-top為100px,效果如下:
這並不是我們想要的效果啊,我們希望子項目的上部距離父元素的上部為100px,可是我們看到的卻是父元素的上部距離瀏覽器頁面的上部有100px的距離,這是為什麼呢?哪裡出現問題了呢?
實際上這是因為當父元素沒有設定padding值以及border值時,出現了一個bug--父元素的上方與子項目的上方完全重合在了一起,無法分開。所以才會導致上述這種父元素和子項目同時向下的情況。
對於這種問題解決方案有下面幾種:
方法一:給父元素添加padding-top值
方法二:給父元素添加border值
方法三:給父元素添加屬性overflow:hidden;
方法四:給父元素或者子項目聲明浮動float
方法五:使父元素或子項目聲明為絕對位置:position:absolute;
方法六:給父元素添加屬性 overflow:auto; positon:relative;(註:此方法為後續添加,感謝博友@小精靈Pawn提供此方法)
方法一:基於例6,在父元素的css代碼中添加padding-top:1px;效果如下:
方法的唯一缺點就是增加了1px的誤差。
方法二:基於例6,在父元素的css代碼中添加border-top:1px solid transparent;效果如下:
同樣達到了效果, 缺點同方法一。
方法三:基於例6,在父元素的css代碼中添加overflow:hidden;效果如下:
同樣達到了效果,並且沒有任何誤差的存在。堪稱perfect!!!!
方法四:給父元素或者子項目聲明float;基於例6,在子項目css代碼添加float:left;或者在父元素css代碼添加float:left;均達到效果,這裡不再展示相同的圖片。
優點:沒有像素的誤差。 缺點:float有時是不必要的。
方法五:給父元素或者子項目添加position:absolute;屬性。 同樣達到效果。
優點:同方法四。 且只要我們不使用top和left也不會有任何影響,所以這也是一種不錯的方法。
方法六:給父元素添加overflow:auto;和position:relative;同樣達到效果。
第四部分:margin值的單位為%時的幾種情況
之前我舉例子時使用margin,它的值都是以px為單位的,這個理解起來沒有問題。但是如果margin值是以%為單位呢?實際上這時候百分比(%)是相對於該元素的父元素(容器),對於同級元素和父子項目都是如此。(再次感謝 博友@小精靈Pawn 提供的建議!!基於此建議補充這部分內容) 但是在同級元素中使用豎直方向的margin時會出現意想不到的結果,下面舉例說明。
(1)同級元素在水平方向使用值為%的margin
例7:
<head> <meta charset="UTF-8"> <title>margin</title> <style> *{ margin:0; padding:0; } .first{ float: left; width: 200px; height: 200px; background: green; } .second{ float: left; width: 200px; height: 200px; background: red; margin-left: 20%; } </style></head><body> <p class="first">寬為200,無margin</p> <p class="second">寬為200,margin-left為20%;</p></body></html>
這個例子中,設定兩個元素向左浮動,以便於觀察兩者水平方向的margin。其中左邊p無margin,右邊p的margin-left為20%,效果如下:
從可以看出兩個p之間的間距始終為父元素(這裡右邊p的父元素即為body,其寬度為瀏覽器寬度)的20%。
(2)同級元素在豎直方向使用值為%的margin
根據例7的啟發,我們可以猜想,如果在豎直方向上使用margin,且值的單位為%,那麼最終兩者之間的距離將是父元素(上例中為body)的百分數。那麼究竟是不是這樣呢?看下面的例子。
例8
<head> <meta charset="UTF-8"> <title>margin</title> <style> *{ margin:0; padding:0; } .first{ width: 200px; height: 200px; background: green; } .second{ width: 200px; height: 200px; background: red; margin-top: 10%; } </style></head><body> <p class="first">高為200,無margin</p> <p class="second">高為200,margin-top為20%;</p></body></html>
這裡設定上面的p無margin,下面的p的margin-top為10。效果如下:
我們發現,當我在縮小瀏覽器的高度時,豎直方向上的間距並沒有縮小!!! 而當我縮小瀏覽器的寬度時,豎直方向上的距離縮小了!!!
這就說明:統計元素之間在豎直方向上使用margin,當值的單位為%時,它是相對於父元素的寬度。
那麼這裡為什麼不是如我們所希望的那樣相對於瀏覽器的高度呢?知乎上有大神是這樣解釋的:
(3)父子項目使用值為%的margin
對於父子項目,如果在子項目中使用單位為%margin,那麼這個margin值是相對於父元素的寬度和高度(注意:這時的確是相對於父元素的高度!)的。
例9
代碼如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <style> *{ margin:0; padding:0; } .father{ width: 500px; height: 300px; background: red; overflow: hidden; } .son{ width: 100px; height: 100px; background: green; margin-top: 20%; margin-left: 20%; } </style></head><body> <p class="father"> <p class="son"></p> </p></body></html>
在這個例子中,我設定了margin-left的值為20%,margin-top的值為20%,父元素的width為500px,父元素的height為300px。下面看看效果吧。
從可以看出子項目的margin-top值最終同樣是相對與父元素的寬度而非高度。
總結:
這篇博文只介紹了margin的其中一部分知識點,但如果大家讀後能有些許收穫是再好不過的了。由於本人總結倉促,知識不足,錯誤在所難免,希望大家如果發現不妥之初能提出意見,我將非常感激。
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
CSS3的box-sizing屬性圖文教程
在CSS邊界線消失如何處理
三種絕對位置元素的水平垂直置中的辦法