css中的負邊距(negative margin)是佈局中的一個經常使用技巧,只要運用得合理經常會有意想不到的效果。不少特殊的css佈局方法都依賴於負邊距,因此掌握它的用法對於前端的同窗來講,那是必須的。本文很是基礎,老鳥能夠略過。css
負邊距在普通文檔流中的做用和效果html
那些沒有脫離文檔流的元素(指不是浮動元素也不是絕對定位、固定定位的元素等),其在頁面中的位置是跟隨者文檔流的變化而變化的。看下面這幅圖:前端
負邊距對這些由文檔流控制的元素的做用是,會使它們在文檔流中的位置發生偏移,但這種偏移不一樣於相對定位,經過相對定位偏移後,其仍然會堅守着它原來佔據的空間,不會讓文檔流的其它元素乘虛而入。而經過負邊距進行偏移的元素,它會放棄偏移前佔據的空間,這樣它後面文檔流中的其它元素就會「流」過來填充這部分空間。仍是經過例子來講明吧。如今咱們把上圖中的塊狀元素、行內元素以及inline-block元素都設一個負邊距 margin:-10px; 看看會發生什麼:瀏覽器
咱們看到,黑灰色的塊狀元素好像向左和向上都分別嵌入了瀏覽器窗口的邊界裏10px,而後塊狀元素下面的文字也爬到了它身上,行內元素向左移動蓋住了它前面的一個字,它後面的文字也有一部分覆蓋在了它身上,inline-block的位置變化也很明顯。佈局
好了,這點相信你們早就心知肚明瞭,就是負的邊距好像能減少元素在文檔流中的尺寸同樣,但事實上,它的尺寸大小並沒變,只是文檔流在計算元素位置的時候,會認爲負邊距把元素的尺寸減少了,由於位置也就發生變化了。這只是打個很形象的比喻,幫助你們理解一下。還要注意的是,文檔流只能是後面的流向前面的,即文檔流只能向左或向上流動,不能向下或向右移動。spa
因此,一切只要是由文檔流決定的東西,負邊距就能起做用了。3d
好比,一個沒有設定高度的塊狀元素,其高度是自動的,具體來講就是由它裏面的文檔流最後的位置決定的。假設它裏面有一個出於文檔流中的子元素,高度爲100px;那這時這個父元素的高度就等於子元素的高度100px了,若是子元素繼續增高,那麼父元素也會跟着增高。但是若是這時子元素設一個負的margin-bottom,好比-20px,由於負邊距會影響到文檔流,原本文檔流的高度是從父元素的最頂端到子元素的最底端這段高度,如今子元素有一個margin-bottom:-20px;就至關於文檔流要向上退後20px,這樣整個文檔流的高度就減小了20px了,那麼父元素的高度也會跟着減小20px。在IE8+以及那些標準瀏覽器中,這還須要父元素擁有一個overflow:hidden的屬性,由於父元素的高度變了,但子元素的高度並無變,因此須要使子元素超出隱藏,但即便不設置overflow:hidden,父元素的高度也是變小了的,只不過這時子元素的高度會超出父元素。在IE6中則不須要,但須要觸發它的hasLayout屬性。因此之前所說的多列等高佈局就是利用這個原理來實現的。code
總之一句話,在文檔流中,元素的最終邊界是由margin決定的,margin爲負的時候就至關於元素的邊界向裏收,文檔流認的只是這個邊界,不會管你實際的尺寸是多少。xml
左和右的負邊距對元素寬度的影響htm
負邊距不只能影響元素在文檔流中的位置,還能增長元素的寬度!
這個做用能實現的前提是:該元素沒有設定width屬性(固然width:auto是能夠的)。
好比下圖的黑灰色部分是一個塊狀元素,它沒有設定寬度。它被包裹在一個寬度爲400px,且水平居中的父元素中。
如今給這個元素的設一個margin-right:-100px;
咱們看到它的寬度的確變長100px;而後再給它設一個margin-left:-100px;
咱們看到它變得更寬了。
負的margin會改變元素的寬度,這的確很讓人費解,若是說負邊距會改變元素在文檔流中的位置仍是很好理解的話,那改變寬度這種現象還真的蠻讓人難以想象的。
那這貨有什麼用途呢?我就舉一個例子吧。
想要建立上圖中黑框內的幾個元素按順序排下來,中間帶些間隔的佈局要怎麼作?,固然最簡單省事的方法就是利用浮動了。咱們把黑框裏面的子元素向左浮動,而後設一個合適的margin-right,是否是就辦到了呢?但由於外邊黑框的寬度是固定的,就是裏面四個子元素的寬度加上三列間隔的寬度,因此靠近右邊邊界的子元素就不該該有正向的margin-right了,不然這一行就只能容納三個子元素了。有人說那這還不簡單,給靠近右邊界的那些子元素加一個class,把它的margin-right設爲0不就好了。這固然能夠,但若是這些子元素是在模板中經過循環動態輸出的,那在循環的時候還得判斷哪些子元素是靠近右邊邊界的,若是是就加上一個class。這樣作的話是否是就有點麻煩了?因此解決辦法是加大子元素的父容器的寬度,讓它可以容納一行中有四個子元素加上四列間隔的寬度,而後最外面的的黑框的那個容器設一個overflow:hidden就好了。上面說了負的左右邊距能加大元素的寬度,因此給子元素的父容器設一個合適的負的margin-right就能夠了。固然你也能夠直接在css中把子元素的父容器的寬度設寬一些,舉這個例子只是爲了說明負邊距也是一種方法。看下完整的代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<
style
>
body,ul,li{ padding:0; margin:0;}
ul,li{ list-style:none;}
.container{ height:210px; width:460px; border:5px solid #000;}
ul{ height:210px; overflow:hidden; margin-right:-20px;}/*一個負的margin-right,至關於把ul的寬度增長了20px*/
li{ height:100px; width:100px; background:#09F; float:left; margin-right:20px; margin-bottom:10px;}
</
style
>
<
div
class="container">
<
ul
>
<
li
>子元素1</
li
>
<
li
>子元素2</
li
>
<
li
>子元素3</
li
>
<
li
>子元素4</
li
>
<
li
>子元素5</
li
>
<
li
>子元素6</
li
>
<
li
>子元素7</
li
>
<
li
>子元素8</
li
>
</
ul
>
</
div
>
|
負邊距對浮動元素的影響
負邊距對浮動元素的影響與負邊距對文檔流中元素的影響實際上是差很少的。文檔流中元素的位置由文檔流的走向決定,浮動的元素也能夠當作有一個「浮動流」存在,不過浮動流既能夠向左,也能夠向右。
好比下圖是三個向左浮動的元素,寬高都是100px:
如今把它們都設一個margin-right:-50px; 而後會變成這樣子:
咱們看到後面的元素疊到了前面的元素上。
再看下面的圖:
咱們把瀏覽器縮小了,而後由於寬度不夠,元素3掉下來了。咱們給元素3設一個margin-left:-80px;看看會怎麼樣
這時咱們看到元素3上去了,並且還覆蓋了元素2的一部分。繼續元素3設爲margin-left:-100px
這時元素3徹底覆蓋住了元素2,當元素3設爲:margin-left:-200px時:
咱們看到元素3繼續向左移動並覆蓋住了元素1。
如今想必你們都明白了負邊距對浮動元素位置的影響了吧。因此那些說得很好聽的什麼聖盃佈局、雙飛翼佈局啊什麼的,都是利用這個原理實現的。就是某個元素雖然是寫在了後面,但能夠經過負邊距讓它在瀏覽器顯示的時候是在前面的。這個之後能夠再慢慢講。
負邊距對絕對定位元素的影響
絕對定位的元素定義的top、right、bottom、left等值是元素自身的邊界到最近的已定位的祖先元素的距離,這個元素自身的邊界指的就是margin定義的邊界,因此,若是margin爲正的時候,那它的邊界是向外擴的,若是margin爲負的時候,則它的邊界是向裏收的。利用這點,就有了經典的利用絕對定位來居中的方法:
看下效果:
但該方法的缺點是必需要知道要居中元素的高度和寬度。
總結:
1.經過負邊距進行偏移的元素,它會放棄偏移前佔據的空間,其它元素會流進去補充偏移的控件,而經過相對定位position:relative則不會放棄偏移前佔據的空間。
2.在文檔流中,元素的最終邊界是由margin決定的,且文檔流只能向左或向上流動,不能向下或向右移動。
3.能夠利用邊距調整元素的寬度、將其居中等。