1. 程式人生 > >margin為負值產生的影響和常見佈局應用

margin為負值產生的影響和常見佈局應用

所以今天整理些margin:負數會對哪些元素或者定位產生影響、margin為負值在web佈局中的應用做下總結。(不能說最全,我已經盡力收集整理)

一、margin為負值產生的影響

對於自身的影響

當元素不存在width屬性或者(width:auto)的時候,負margin會增加元素的寬度,看下下面的例子

<div class="container">
  <div class="box1">
         I dont have the width
    </div>
</div>
.container{
        margin:0 auto
; width: 500px; border: 1px #ccc solid; margin-bottom: 20px; }
.box1{ margin-left: -20px; }

Paste_Image.png


可以看到box1增加了20px寬度,margin-left和margin-right都是可以增加寬度,

注意:
margin-top為負值不會增加高度,只會產生向上位移
margin-bottom為負值不會產生位移,會減少自身的供css讀取的高度

為什麼是供css讀取的高度
我們再來做個實驗

    <style>
    #box
{ width: 50%; margin-bottom: -25px; background-color: rgba(90, 243, 151, 0.8); height: 50px; }
</style> <div id="box"> box </div> <script src="http://cdn.bootcss.com/jquery/2.1.1/jquery.js"></script> <script> var
x = $('#box').height() console.log(x);
</script>

Paste_Image.png


下文的應用段落就會利用這個特點做一個多列等高佈局。

對文件流的影響

元素如果用了margin-left:-20px;毋庸置疑的自身會向左偏移20px和定位(position:relative)有點不一樣的是,在其後面的元素會補位,也就是後面的行內元素會緊貼在此元素的之後。總結,不脫離文件流不使用float的話,負margin元素是不會破壞頁面的文件流。


對文件流的影響

所以如果你使用負margin上移一個元素,所有跟隨的元素都會被上移。

對浮動元素的影響

先定義3個box

<div class="container">
    <div class="flb flbox1">box1</div>
    <div class="flb flbox2">box2</div>
    <div class="flb flbox3">box3</div>
</div>
.flb{
    float: left;
    width: 100px;
    height: 100px;
}
.flbox1{background-color: rgba(33, 114, 214, 0.8);}
.flbox2{background-color: rgba(255, 82, 0, 0.8);}
.flbox3{background-color: rgba(90, 243, 151, 0.8);}

Paste_Image.png

demo1,給他們都加上margin-left:-25px;

.flb{
    float: left;
    width: 100px;
    height: 100px;
    margin-left: -25px;
}
.flbox1{background-color: rgba(33, 114, 214, 0.8);}
.flbox2{background-color: rgba(255, 82, 0, 0.8);}
.flbox3{background-color: rgba(90, 243, 151, 0.8);}

margin-left: -25px;


可以看出3個盒子都向左移動25px;
box1自身向左移動了25px,box2又覆蓋了其25px,所以我們就看到了“寬度”為50px的box1
box2,box3以此類推!

讓我再看看margin-left: -50px;的情況


margin-left: -50px

如果只給box3設定margin-left:-200px;

.flb{
    float: left;
    width: 100px;
    height: 100px;

}
.flbox1{background-color: rgba(33, 114, 214, 0.8);}
.flbox2{background-color: rgba(255, 82, 0, 0.8);}
.flbox3{background-color: rgba(90, 243, 151, 0.8);
    margin-left: -200px;}

.flbox3{margin-left: -200px;}


看一看到box3,向左偏移了200px,完全將box1覆蓋了,box3下面還能隱約的看到了box1。

總結:

負margin會改變浮動元素的顯示位置,即使我的元素寫在DOM的後面,我也能讓它顯示在最前面。聖盃佈局、雙飛翼佈局啊什麼的,都是利用這個原理實現的。(下文有詳細)

對絕對定位影響

<div class="absolute"></div>
.absolute{
    position: absolute;
    top:50%;
    left:50%;
    height: 200px;
    width: 200px;
    background-color: #ccc;
    margin-top: -100px;
    margin-left: -100px;
}

一個居中的box


對於絕對定位元素,負margin會基於其絕對定位座標再偏移,
唯有的缺點就是你必須知道這個覺得定位元素寬度的和高度才能並設定負margin值使其居中瀏覽器視窗,
若對於不確定寬度和高度可以用

transform: translate3d(-50%,-50%,0);

使用translate3d可以開啟GPU加速,就不用cpu去從新計算所有點素位置,開啟GPU加速後,GPU自動將這個元素放在一個新的“層”,直接偏移這個“層”來提高渲染速度(個人理解,若有錯誤歡迎指正)。

二、margin為負值的常見佈局應用

左右固定,中間自適應(雙飛翼)

雙飛翼的好處:
1.可以讓主要內容出現在dom結構的前面,現將主要內容渲染
2.中間只適應,兩邊固定寬度的效果


雙飛翼
<div class="main">
            <div class="main-content">main content</div>
</div>
<div class="left">left</div>
<div class="right">right</div>
    *{
        margin:0;
        padding: 0
    }
    .main{
        float: left;
        width: 100%;

    }
    .main .main-content{
        margin: 0 210px;
        background-color: rgba(33, 114, 214, 0.8);
        height: 500px
    }
    .left{
        width: 200px;
        float: left;
        background-color: rgba(255, 82, 0, 0.8);
        margin-left: -100%;
        height: 200px

    }
    .right{
        width: 200px;
        height: 200px;
        margin-left: -200px;
        float: left;
        background-color: rgba(90, 243, 151, 0.8);
    }

去除列表右邊框

利用負margin增加寬度的特點,舉個在實際中應用例子��

對於圖片列表,我會常常設計成兩邊對齊,中間元素平均分佈,類似下面的佈局


慕課網截圖


想讓每一排最後一個對齊父元素的右邊框,一般都兩種處理,第一種會在給個迴圈體內的最後一個新增一個float:right屬性或者做特殊處理,但這樣還需要後端配合,我們自己能解決的就儘量自己解決。還有就是用css3的flexbox佈局能解決這個兩邊對齊,但是這種佈局相容性不好,你的使用者用IE的話,不推薦!
so,負margin就能發揮其增加元素寬度的特點,完美的解決這個問題!

<div class="container">
    <ul class="list">
        <li>我是一個列表</li>
        <li>我是一個列表</li>
        <li>我是一個列表</li>
        <li>我是一個列表</li>
        <li>我是一個列表</li>
        <li>我是一個列表</li>
        <li>我是一個列表</li>
        <li>我是一個列表</li>
        <li>我是一個列表</li>
        <li>我是一個列表</li>
    </ul>
</div>
.container{
        margin:0 auto;
        width: 500px;
        border: 1px #ccc solid;
        margin-bottom: 20px;
}
.list{
    overflow: hidden;
    margin-right: -10px;

}
.list li{
    width:92px;
    height: 92px;
    background-color: #ccc;
    margin-bottom: 20px;
    float: left;
    margin-right: 10px;
}

圖片列表

計算公式:
假設一橫列展示的數量為x,元素見的間距為y,父距寬度z
則元素的寬度=(z-y(x-1))/x
本例中li的寬度為(500-10(5-1))/5=92

負邊距+定位:水平垂直居中

上面已經舉例,用了負margin會向對應方向偏移的特點!

去除列表最後一個li元素的border-bottom

很多情況下,我們會用li標籤來模擬表格,再給li標籤新增下邊距的時候,最後一個li標籤表格會和父元素的邊框靠在一起,會顯得整個“table”的底部邊框會比其他的邊粗一些!

    <style>
    ul.table{
        border:1px #ccc solid;
        margin-top:100px;
    }
    ul.table li{
        border-bottom: 1px #ccc solid;
        list-style: none;
    }
    </style>
    <ul class="table"> 
        <li>I am li</li>
        <li>I am li</li>
        <li>I am li</li>
        <li>I am li</li>
        <li>I am li</li>
    </ul>

沒有設定margin-bottom:-1px


下面新增一個margin-bottom:-1px;的屬性,就可以使其看起來更完美

    <style>
    ul.table{
        border:1px #ccc solid;
        margin-top:100px;
    }
    ul.table li{
        border-bottom: 1px #ccc solid;
        list-style: none;
        margin-bottom: -1px;
    }
    </style>
    <ul class="table"> 
        <li>I am li</li>
        <li>I am li</li>
        <li>I am li</li>
        <li>I am li</li>
        <li>I am li</li>
    </ul>

設定margin-bottom:-1px

多列等高

利用margin-bottom為負值會減少css讀取元素高度的特性,加上padding-bottom和overflow:hidden,就能做一個未知高度的多列等高佈局(當然也可以用table)

<style>
    .container{
        margin:0 auto;
        width: 100%;
        overflow: hidden;
    }
    .left{
        height: 50px;
        width: 33.33%;
        margin-bottom: -5000px;
        padding-bottom: 5000px;
        float: left;
        background-color: rgba(33, 114, 214, 0.8);
    }
    .main{
        height:100px;
        margin-bottom: -5000px;
        width: 33.33%;
        float: left;
        padding-bottom: 5000px;
        background-color: rgba(255, 82, 0, 0.8);
    }
    .right{
        width: 33.33%;
        float: left;
        margin-bottom: -5000px;
        padding-bottom: 5000px;
        background-color: rgba(90, 243, 151, 0.8)
    }
</style>
<div class="container">
    <div class="left"> height:50px</div>
    <div class="main">height:100px</div>
    <div class="right">height:30px</div>
</div>

多列等高


雖然設定了5000的內邊距,但是我用-5000的外邊距去抵消掉,所以對於父元素來說(上文所說的css能讀取的高度),他還是原來的高度(但其自身實際高度為5000p x+本來高度),然後父元素在加上overflow:hidden;以最高的高度進行裁切,所以就有了看起來“等高”的3個div。

今天整理和實驗了下負margin的原理和應用,希望你看了文章有所收穫,歡迎交流!



參考資料