CSS的margin屬性在頁面布局中的使用攻略

基礎(chǔ)
1.元素containing-box寬高度等于內(nèi)容寬度
HTML
- <div class="wrap">
- <div class="item1"></div>
- <div class="item2"></div>
- </div>
CSS
- .wrap {
- float: left;
- border: 2px solid #000;
- }
- .item1 {
- width: 100px;
- height: 100px;
- background: #fdf;
- margin-left: 10px;
- margin-top: 10px;
- margin-right: 20px;
- margin-bottom: 30px;
- }
- item2 {
- width: 50px;
- height: 50px;
- background: #adf;
- }
能滿足原理1的條件只有一種,元素不設(shè)寬度且不在文檔流中,此時(shí),父元素wrap產(chǎn)生的containing-box的寬高寬度等子元素border-box的寬高度加上外邊距的寬高度,也就是說,子元素的margin值也是其containing-box的一部分。margin一共有兩類參考線,第一類是margin-top與margin-left的參考線,第二類是margin-bottom與margin-right的參考線,第一類margin的參考線是以其所處的containing-box的邊緣線為參考線,如上例所示,當(dāng)調(diào)整元素.item1的margin-top與margin-left的值時(shí),元素.item1所處的containing-box的大小也在發(fā)生變化因此其邊緣線也在不斷變化同時(shí)也就導(dǎo)致.item1元素自身的位置也在發(fā)生變化,看起來就是.item1自身發(fā)生了移動(dòng)。第二類margin的參考線是以元素自身的邊緣線(外邊距的外側(cè)為邊緣線)為參考線,同樣的,調(diào)整上例中的margin-bottom值,.item1的margin-bottom也在不斷的發(fā)生變化,也就是說其自身邊緣線在不斷的移動(dòng),同時(shí)導(dǎo)致了.item2的移動(dòng)。根據(jù)上面的論述,我們可以得出結(jié)論,外邊距的調(diào)整也就等于讓其自身相對(duì)的參考線的位置在發(fā)生移動(dòng),同時(shí)導(dǎo)致相對(duì)于參考線運(yùn)動(dòng)的元素發(fā)生移動(dòng)。元素自身相對(duì)于containing-box的邊緣線移動(dòng)而移動(dòng),與元素自身為兄弟關(guān)系的元素相對(duì)于元素自身的邊緣線移動(dòng)而移動(dòng)。參考線示意圖如圖所示,按箭頭所指方向使參考線變化的margin值都為正值。
綜上,我們可以利用margin對(duì)元素自身進(jìn)行移動(dòng),同時(shí)也可讓其相鄰元素進(jìn)行移動(dòng),移動(dòng)的同時(shí)我們需要知道的是其所處的containing-box的大小也在發(fā)生變化。
綜上,當(dāng)元素寬高度等于內(nèi)容寬高度時(shí),可通過調(diào)整內(nèi)容的margin值來調(diào)整其containing-box的大小,因?yàn)閏ontaining-box的變化也就會(huì)導(dǎo)致元素本身的移動(dòng),也就是說既可以移動(dòng)元素,也可調(diào)整元素與元素之間的間距。
2.元素內(nèi)容寬度等于其containing-box的寬度
- <div class="wrap">
- <div class="wrap-inner"></div>
- </div>
- .wrap {
- width: 100px;
- border: 2px solid #000;
- margin: 0 auto;
- }
- .wrap-inner {
- height: 50px;
- background: #fdf;
- }
上例中,元素wrap-inner的border-box寬度加上margin的大小等于其containing-box的寬度,因此當(dāng)containing-box寬度固定,根據(jù)公式'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block,調(diào)整其自身margin-left或margin-right值,便會(huì)使wrap-inner自身大小發(fā)生變化,margin-left為正值且值逐漸變大,則wrap-inner自身寬度逐漸變小,若margin-left為負(fù)值且逐漸變小,則wrap-inner自身寬度逐漸變大,margin-right同理。一定要注意這里的寬度繼承和width:100%是有本質(zhì)區(qū)別的,因?yàn)閣idth:100%就等于它的containing-box的100%和它的margin,border或者padding都木有關(guān)系,具體可看我的關(guān)于寬度與高度討論的系列文章三里的例子,羅嗦了一點(diǎn),但是這里是容易犯錯(cuò)誤的地方。一定要注意,一定要注意,一定要注意?。。?。重要的事情說三遍。
將margin-left和right調(diào)整為-10px,如圖,根據(jù)計(jì)算,wrap-inner變寬
將margin-left和right調(diào)整為10px,如圖,根據(jù)計(jì)算,wrap-inner變窄
綜上,當(dāng)元素寬或高度等于其containing-box的寬度或高度時(shí),且containing-box的寬度固定我們便可以利用margin對(duì)其進(jìn)行自身寬度大小的調(diào)整。也就是說寬高度和containing-box有關(guān)系時(shí),我們利用margin可進(jìn)行內(nèi)里元素大小的調(diào)整。
不同元素margin的計(jì)算
行內(nèi)級(jí)元素
Inline,非置換元素:如果margin值為auto,則margin-left和margin-right的計(jì)算值也就為0
Inline,置換元素:同上
Inline-block,置換元素在文檔流中:同上
Inline-block,非置換元素在文檔流中:同上
塊級(jí)元素
塊級(jí)非置換元素,在文檔流中
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
下面的情況下,如果margin值為auto
如果width是auto值,那么其他值是auto的值就為0
如果margin-left和margin-right的值為auto,使用的值相等,那么就相對(duì)于包含塊水平居中。
塊級(jí)置換元素,在文檔流中
同塊級(jí)非置換元素一樣。
小結(jié)
行內(nèi)級(jí)置換元素和非置換元素,在margin值為auto時(shí),margin-left和margin-auto的計(jì)算值都為0。
塊級(jí)置換元素和非置換元素:
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
如果width是auto值,那么其他值是auto的值就為0
如果margin-left和margin-right的值為auto,使用的值相等,那么就相對(duì)于包含塊水平居中。
利用Margin進(jìn)行布局
通常在布局中我們會(huì)遇到那些問題呢?下面是我自己實(shí)踐中遇到的一些問題
問題1
當(dāng)我們拿到一份設(shè)計(jì)稿,然后這份設(shè)計(jì)稿有像下面這樣的布局,整體居中,里面元素排一排,當(dāng)然布局的方式會(huì)有很多種,那么如果我們采用浮動(dòng)布局或者display:inline-block進(jìn)行布局會(huì)出現(xiàn)什么問題呢,如圖我們可以看出,若采用上述兩種方式進(jìn)行布局,那么每個(gè)塊的寬度加上間隙,就會(huì)超出包含塊的寬度,當(dāng)然我們也可以將包含塊的寬度進(jìn)行增大以留下足夠的位置供元素?cái)[放,但是這種方法明顯是不可取的,那么如何解決這個(gè)位置不夠的問題呢,可以看下面的栗子1 。
栗子
html
- <div class="container">
- <div class="inner-wrap">
- <div class="inner"></div>
- <div class="inner"></div>
- <div class="inner"></div>
- </div>
- </div>
css
- body {
- margin: 0;
- }
- .container {
- margin: 0 auto;
- width: 980px;
- }
- .inner-wrap {
- margin-left: -10px;
- }
- .inner {
- float: left;
- margin-left: 10px;
- width: 320px;
- height: 200px;
- background: #2df;
- }
此布局便利用了原理2,利用負(fù)margin增加了inner-wrap的寬度,但不改變整體的寬的情況下,實(shí)現(xiàn)效果。如下
問題2
上面的例子僅僅只是實(shí)現(xiàn)了三列固定寬度的布局,這樣的布局當(dāng)屏幕寬度發(fā)生變化的時(shí)候便會(huì)出現(xiàn)問題。因此我們便會(huì)有如下需求。
左右列固定,中間列自適應(yīng)
栗子
html
- <div class="main">
- <div class="main-content"></div>
- </div>
- <div class="left"></div>
- <div class="right"></div>
css
- .main {
- float: left;
- width: 100%;
- }
- .main-content {
- height: 200px;
- background: #2da;
- margin: 0 200px;
- }
- .left,.rightright {
- float: left;
- width: 200px;
- height: 200px;
- background: #ccc;
- }
- .left {
- margin-left: -100%;
- }
- .rightright {
- margin-left: -200px;
- }
效果如下,當(dāng)你縮小屏幕時(shí),中間部分會(huì)隨著屏幕的縮小而縮小,另外兩部分寬度不變,同樣也滿足了主要內(nèi)容優(yōu)先加載的需求,可謂一舉兩得
分析:
可以看出上面的布局利用了原理2,但是這里仍然會(huì)有幾個(gè)為什么要問。
首先,為什么main里面一定要嵌套main-content,為什么不能直接使用單個(gè)main(假設(shè)1)?
其次,為什么main上一定要設(shè)置float:left,可以設(shè)置其他值嗎,如position:absolute(假設(shè)2)?
分析上面的布局之前,我們也要了解到上面的布局滿足了我們的什么需求,這里有兩點(diǎn)1.主要內(nèi)容優(yōu)先加載。2.主要內(nèi)容自適應(yīng)。這里我們可以分析一下,我們是怎樣達(dá)到上述兩個(gè)目的的。首先,要達(dá)到目的1,我們就的把div.main放在前面來寫,因?yàn)闉g覽器是從下到下渲染頁面的,放在前面的也就會(huì)先渲染。且由于div.main為文檔流中的塊級(jí)元素,因此會(huì)獨(dú)占一行,因此我們需要使其脫離文檔流,這樣才能使下面的元素能有機(jī)會(huì)上的來(這里之所以不考慮display:inline-block是因?yàn)閐iv.main的長(zhǎng)度會(huì)獨(dú)占一行,就算設(shè)置display:inline-block也沒有任何作用,下面的元素仍然上不來)。而要達(dá)到目的2,需要用到原理2。同時(shí)在上面提出的兩個(gè)問題中,有兩個(gè)假設(shè)。
假設(shè)1,如果使用單個(gè)main可不可以滿足上述兩個(gè)需求?我們可以試試。
html
- <div class="main"></div>
- <div class="left"></div>
- <div class="right"></div>
css
- body {
- margin:0;
- }
- /*這里注意需要改掉main的流方式,下面的元素才上的來*/
- .main {
- float:left
- margin: 0 210px;
- height: 200px;
- background:#2da;
- }
- .left,.rightright {
- float: left;
- width: 200px;
- height: 200px;
- background: #ccc;
- }
- .left {
- margin-left: -100%;
- }
- .rightright {
- margin-left: -200px;
- }
從中線分開的黃色兩部分為各自為main的左右外邊距
從結(jié)果中,我們可以看出使用單個(gè)main是不行的,因?yàn)樵诓辉O(shè)寬度且元素不在文檔流中時(shí),元素的寬度為0,不能滿足我們的需求,正因?yàn)槲覀兺瑫r(shí)要滿足1.main元素不在文檔流中2.元素不設(shè)寬度且在文檔流中。這兩個(gè)條件當(dāng)然是不能同時(shí)在一個(gè)main元素下能達(dá)到的,因此我們需要再嵌套一個(gè)main-content讓它來滿足條件2。這也就解釋了為什么一定要嵌套一個(gè)main-content。
解決了問題1,現(xiàn)在我們來說問題2。
假設(shè)2,main上的float值可以換為position:absolute嗎?
同樣的,我們?cè)囋?br />html
- <div class="main">
- <div class="main-content"></div>
- </div>
- <div class="left"></div>
- <div class="right"></div>
css
- body {
- margin: 0;
- }
- .main {
- position:absolute;
- width:100%;
- }
- .main-content {
- margin: 0 210px;
- height: 200px;
- background: #2da;
- }
- .left,.rightright {
- width: 200px;
- height: 200px;
- background:#ccc;
- }
- .left {
- float: left;
- }
- .rightright {
- float: rightright;
- }
答案是可以的,只是我們需要改掉一些值,而當(dāng)main為float之所以要給div.left與div.right要設(shè)置margin-left值是因?yàn)楦?dòng)元素浮動(dòng)時(shí),當(dāng)它的外邊緣碰到包含框或者另一個(gè)浮動(dòng)框的邊框?yàn)橹?。而為浮?dòng)元素的div.main占據(jù)了整整一行,因此下面的浮動(dòng)元素div.left與div.right便被擠了下來,而設(shè)置它們的margin-left值便可以把它們移上去,這里便運(yùn)用了原理1。而當(dāng)我們把div.main的float值改為position:absolute時(shí),便不會(huì)存在被擠下來的問題,可直接設(shè)置div.left與div.right的float的值。效果如下。
如若只需要達(dá)到寬度自適應(yīng)的要求,那么,這時(shí)候便可以將div.main放在最后面且不用嵌套div.main-content,具體如何實(shí)現(xiàn),大家可以自己試試。
問題3
如下所示設(shè)計(jì)稿,在我們進(jìn)行布局的過程中,可能會(huì)出現(xiàn)border重合的情況,因?yàn)橐环矫嫖覀冃枰獙?duì)整個(gè)整體加上border,而另一方面我們又需要利用border隔開那三個(gè)小塊。那么如果我們對(duì)每個(gè)小塊都加上右邊框,可以想象,最右邊就會(huì)出現(xiàn)邊框的堆疊而這不是我們希望看到的,所以,要如何解決這個(gè)問題,可以看如下例子給出的答案。
栗子
html
- <ul>
- <li>1</li>
- <li>2</li>
- <li>3</li>
- </ul>
css
- ul {
- position:absolute;
- margin: 0;
- padding:0;
- list-style:none;
- border: 4px solid #c5c5c5;
- }
- li {
- float:left;
- width: 200px;
- height: 50px;
- line-height: 50px;
- text-align: center;
- border-right: 4px solid #c5c5c5;
- }
沒在li上加margin-right:-4px;前,效果如圖,發(fā)生了堆疊。
加了margin-right: -4px后,達(dá)到預(yù)期效果。因?yàn)榧由狭藆l的右邊框發(fā)生了移動(dòng)與第三個(gè)li的右邊框進(jìn)行了重疊。因此效果上來看便符合了預(yù)期,如圖
此布局便利用了原理1,通過元素對(duì)相鄰元素位置的控制來達(dá)到預(yù)期的效果。
而利用原理1也可以實(shí)現(xiàn)元素居中的布局,先讓元素上左各移50%,然后再讓設(shè)置元素的上左margin值設(shè)置為元素自身寬度的一半長(zhǎng)度,以對(duì)元素本身進(jìn)行移動(dòng)。便可達(dá)到元素居中放置的目的。
總結(jié)
1.元素寬度等于containing-box寬度時(shí)。
可以通過調(diào)整margin的值來調(diào)整元素的寬度。
2.元素寬度與containing-box無關(guān)時(shí)。
可以通過調(diào)整margin的值來移動(dòng)元素的位置。
相關(guān)文章
- 下面小編就為大家?guī)硪黄獪\談css margin重疊。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-07-19
- 下面小編就為大家?guī)硪黄狢SS 之margin知識(shí)點(diǎn)(必看)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-07-10
css布局之負(fù)margin妙用及其他實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了css布局之負(fù)margin妙用及其他實(shí)現(xiàn)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07- 這篇文章和大家詳細(xì)說一說CSS中margin屬性的使用,重點(diǎn)描述了關(guān)于margin,我們?nèi)粘2惶菀装l(fā)現(xiàn)的“坑,感興趣的小伙伴們可以參考一下2016-02-25
- 這篇文章主要介紹了CSS中的margin屬性的使用,margin是元素盒模型(box model)的基礎(chǔ)屬性,常被用來設(shè)置外邊距,實(shí)際用途非常廣泛,需要的朋友可以參考下2016-02-02
CSS中使用負(fù)margin值來調(diào)整居中位置
這篇文章主要介紹了CSS中使用負(fù)margin值來調(diào)整居中位置的方法,文中同時(shí)提到了這種常用方法的一些值得注意的地方,需要的朋友可以參考下2015-07-15- margin 簡(jiǎn)寫屬性在一個(gè)聲明中設(shè)置所有外邊距屬性。該屬性可以有 1 到 4 個(gè)值。這個(gè)簡(jiǎn)寫屬性設(shè)置一個(gè)元素所有外邊距的寬度,或者設(shè)置各邊上外邊距的寬度。塊級(jí)元素的垂直相2014-10-22
- 這篇文章主要介紹了解決margin 外邊距合并問題 ,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-03