前面的話
margin屬性在實際中非常常用,也是平時踩坑較多的地方。margin折疊部分相信不少人都因為這樣那樣的原因中過招。margin負值也是很常用的功能,很多特殊的布局方法都依賴于它。它看似簡單,實際上卻蠻復雜,本文就margin負值作詳細介紹和梳理
表現
雖然margin可以應用到所有元素,但display屬性不同時,表現也不同
【1】block元素可以使用四個方向的margin值
【2】inline元素使用上下方向的margin值無效
【3】inline-block使用上下方向的margin負值看上去無效
[注意]inline-block使用上下方向的margin負值只是看上去無效,這與其默認的vertical-align:baseline有關系,當垂直對齊的屬性值為其他值時,則會顯示不同的視覺效果
重疊
margin負值并不總是后面元素覆蓋前面元素,它與元素display屬性有關系
【1】兩個block元素重疊時,后面元素可以覆蓋前面元素的背景,但無法覆蓋其內容
【2】當兩個inline元素,或兩個line-block元素,或inline與inline-block元素重疊時,后面元素可以覆蓋前面元素的背景和內容
【3】當inline元素(或inline-block元素)與block元素重疊時,inline元素(或inline-block元素)覆蓋block元素的背景,而內容的話, 后面的元素覆蓋前面的元素
綜上所述,個人理解,在普通流布局中,瀏覽器將頁面布局分為內容和背景,內容的層疊顯示始終高于背景。block元素分為內容和背景,而inline元素或inline-block元素,它本身就是內容(包括其背景等樣式設置)
浮動
【1】block元素與浮動元素重疊時,其邊框和背景在該浮動元素之下顯示,而內容在浮動元素之上顯示
【2】inline或inline-block元素與浮動元素重疊時,其邊框、背景和內容都在該浮動元素之上顯示
定位
【1】定位元素(position不為static)覆蓋其他元素的背景和內容
【2】將relative屬性值應用于inline元素,由于無法改變其行內元素的本質,所以其上下margin依然存在問題
應用
【1】水平垂直居中
如果要居中的元素的寬/高是不變的或者說是確定的,比如width/height=100px,那么設置absolute的top/left=50%,然后margin-left/margin-top=-50px即可
如果要居中的元素的寬/高是不確定的,這時margin負值就不能使用具體的px了,可以使用百分比。但由于margin的百分比都是相對于包含塊的寬度,所以這里限制了只能設置寬高相同的居中元素。包含塊的寬度如何獲得呢?利用absolute的包裹性,在需要居中的元素外面套一個空的<div>元素即可
.box{ position:relative; width: 200px; height: 200px; background-color: lightgreen; border: 2px solid black; } .out{ position: absolute; left: 50%; top: 50%; } .in{ height: 100px; width: 100px; background-color: pink; margin-left: -50%; margin-top: -50%; }
<div class="box"> <div class="out"> <div class="in">測試內容</div> </div> </div>
【2】列表項兩端對齊
比如外層元素寬度為200px,內層3個元素,寬度為60px,margin-right為10px。這里,正常流中塊級元素框的水平總和總共為210px,超過了父元素的寬度200px,則第三個元素會被擠下來。當然可以給第三個元素設置margin-right=0。但,這種方法不優雅,為布局而布局,第三個元素并沒有什么特殊的,卻被設置了特殊的樣式
優雅的方法應該是內層元素和外層元素之間包一層元素,設置margin-right=-10px,使塊級元素框的水平總和總共為210px - 10px = 200x ,等于父元素的寬度即可
[注意]設置overflow:hidden用于清除浮動
ul{ margin: 0; padding: 0; list-style:none; } .box{ width: 200px; background-color: pink; } .list{ overflow: hidden; margin-right: -10px; } .in{ float: left; width: 60px; height: 100px; background-color: lightgreen; margin-right: 10px; }
<div class="box"> <ul class="list"> <li class="in">1</li> <li class="in">2</li> <li class="in">3</li> </ul> </div>
【3】三欄自適應布局
中間的主體使用雙層標簽,外層<div>寬度100%顯示,并且浮動,內層<div>為真正的主體內容,含有左右110px的margin值。左欄和右欄都采用margin負值。左欄左浮動,margin-left為-100%,正好使左欄位于頁面左側。右欄左浮動,大小為其本身的寬度100px
html,body{ height: 100%; } body{ margin: 0; } .main{ width: 100%; height: 100%; float: left; } .main .in{ margin: 0 110px; background-color: pink; height: 100%; } .left,.right{ height: 100%; width: 100px; float: left; background-color: lightgreen; } .left{ margin-left: -100%; } .right{ margin-left: -100px; }
<body> <div class="main"> <div class="in"></div> </div> <div class="left"></div> <div class="right"></div> </body>
【4】三欄等高布局
給每欄設置大的底部內邊距,然后用數值相同的負外邊距消除這個高度,然后在外層容器中設置overflow為hidden
body{ margin: 0; overflow: hidden; } ul{ margin: 0; padding: 0; list-style: none; } .list{ overflow: hidden; width: 100%; height: 100%; } .main{ margin: 0 110px; background-color: lightgreen; } .left{ width: 100px; float: left; background-color: pink; } .right{ width: 100px; float: right; background-color: pink; } .main,.left,.right{ margin-bottom: -9999px; padding-bottom: 9999px; }
<ul class="list"> <li class="left">左側文字比較少</li> <li class="right">右側文字比較多右側文字比較多右側文字比較多右側文字比較多右側文字比較多右側文字比較多右側文字比較多右側文字比較多右側文字比較多右側文字比較多右側文字比較多右側文字比較多右側文字比較多右側文字比較多右側文字比較多右側文字比較多</li> <li class="main">中間文字比較少</li> </ul> </body>
文章列表