1.引言
开篇前需声明一点:本人前端的菜鸟一枚,也是在自学的过程中碰到了负边距(Negative Margin)布局问题,所以花了近一天的时间去找资料写Demo测试,文章是我综合其他大牛的思路而成,目的并不在于向诸位“传道”,而主要是为了方便自己以后查阅复习,当然如果能够帮到你那就更好了。文中若有错误,欢迎指正,不必留情。
2.负外边距的表现
有人说div+css布局方式主要有三种:
- 浮动(float:left;float:right)
- 定位(绝对定位:absolute;相对定位:relative)
- 负边距(margin:-100px);
这种说法我也不知道对不对(毕竟是菜鸟),但是可以肯定的是既然有这种说法,足见负外边距对于布局的影响还是挺大的,或者在某些特定的布局中需要依仗它。下面将从两个方面通过代码示例来说明负外边距的表现:
2.1 对于静态元素的影响
这里所谓的静态元素指的的没有脱离文档流的元素,它在页面位置是跟随文档流变化而变化的。不妨看看下面这个示例:
<div class="container">
<div class="top"></div>
<span class="behind">君不见,黄河之水天上来,奔流到海不复回。君不见,高堂明镜悲白发,朝如青丝暮成雪。人生得意须尽欢,莫使金樽空对月。天生我材必有用,千金散尽还复来。烹羊宰牛且为乐,会须一饮三百杯。<span class="inner">岑夫子,丹丘生,将进酒,杯莫停。</span>与君歌一曲,请君为我倾耳听。钟鼓馔玉不足贵,但愿长醉不复醒。古来圣贤皆寂寞,惟有饮者留其名。陈王昔时宴平乐,斗酒十千恣欢谑。主人何为言少钱,径须沽取对君酌。五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。</span>
</div>
<style type="text/css">
body,div,p{
margin: 0;
padding: 0;
}
.container{
width: 500px;
height: 400px;
margin: 100px auto;
font-size: 18px;
border: 1px solid #0094ff;
}
.top{
width: 500px;
height: 100px;
background-color: yellowgreen;
/*
margin-top: -50px;
margin-left: -50px;
margin-right: -50px;
margin-bottom: -50px;
*/
}
/*
.inner{
display: inline-block;
width: 100px;
height: 100px;
background-color: royalblue;
color: white;
margin-right: -50px;
margin-bottom: -50px;
}
*/
</style>
如果给上面的黄绿色div块(.top)分别加上负外边距看看有什么效果:
(1)margin-top: -50px; 很显然div块往上挪动了50px,后面的span标签里面的文字流也跟着往上挪动50px。
(2)margin-left: -50px;div块往左边挪动了50px,后面的span标签内容与位置没有发生变化
(3)margin-right: -50px;直接加似乎看不出效果,如果把上面的div块改成display: inline-block;就可以看出效果,div的位置和大小都没有发生变化,但是后面的“文字流”顶上去了。
(4)margin-bottom: -50px;“文字流”整体上挪,但是div块的大小和位置依然没变
说明:上面4种负边距的设置,个人认为margin-top和margin-left负边距好理解,就是把元素向上和向左移动,但是margin-right和margin-bottom负边距并不是把元素向右和向下移动,因为文档流只能向上或者向左流动。我对于margin-right和margin-bottom负边距的理解就是它会把元素的文档流边界向左或者向上挪动,而元素的位置和大小不变(见下图),这也解释了为什么margin-right: -50px和margin-bottom: -50px;的文档流都向左和向上流动从而压盖住了原有的div块。
此外,对于没有设置宽度(width:auto也可以)的元素,margin-left和margin-righ的负边距会增加元素的宽度。
<div class="container">
<div class="content"></div>
</div>
.container{
width: 400px;
height: 200px;
margin: 100px auto;
border: 1px solid salmon;
}
.content{
height: 100px;
background-color: seagreen;
margin-left: -100px;
margin-right: -150px;
}
2.2 对于浮动元素的影响
实际上负边距对于浮动元素的影响和静态元素是类似的,可以想象浮动的元素也会有一个“浮动流”,类似文档流,四个方向的负边距的影响和静态元素是一样的,看下面的示例:
<div class="container">
<div class="div-one">div1</div>
<div class="div-two">div2</div>
<div class="div-three">div3</div>
</div>
.div-one,.div-two,.div-three{
width: 200px;
height: 200px;
float: left;
color: white;
font-size: 18px;
}
.container{
width: 900px;
height: 600px;
margin: 100px auto;
border: 1px solid salmon;
}
.div-one{
background-color: seagreen;
margin-left: -50px;
margin-top: -50px;
}
.div-two{
background-color: slateblue;
margin-right: -50px;
}
.div-three{
background-color:saddlebrown;
}
div1块向上和向左挪动,后面的“浮动流”跟上,而div2的浮动流边界向左收缩,所有div3不管div2的实际大小,直接压盖上来。
说到负边距浮动布局,这里有小小的Demo:
<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>
<li>9</li>
</ul>
</div>
父元素的宽度和每个li的宽度是固定的,常规操作全部浮动,通过计算给定每个li一个margin-right值,第3,6,9个元素会被相应的“挤下来”,这里或者js代码计算一下,选出3,6,9元素去掉margin-right值,就可以达到效果。实际上呢,完全可以通过负边距来给li的无宽父元素增加一个margin-right负边距使得3,6,9“正位”,然后把超出的部分隐藏。
ul,li{
list-style: none;
}
.container{
height: 320px;
width: 320px;
margin: 100px auto;
border: 1px solid #0094ff;
}
ul{
height: 320px;
overflow: hidden;
margin-right: -10px;
/*对于无宽的父元素margin-right:-10px会使得父元素向右伸展10px,从而有足够的空间容纳3,6,9元素*/
}
li{
height: 100px;
width: 100px;
background-color:salmon;
color: white;
font-size: 18px;
margin: 0 10px 10px 0;
float: left;
}
3.总结
语言表达能力和水平有限,啰嗦了半天也总觉得没有说清楚。不过我觉的这个需要自己写几个Demo去体会一下,尤其是对margin-right和margin-bottom负边距的理解,这个很重要。后续的篇章中会基于本篇中的理论来展开,主要是使用负边距的一些布局,其中包括著名的“圣杯布局”和“双飞翼布局”,未完待续哦!