CSS探索: 负边距巧用

Author : luckyGirl

之前对于负边距的使用有限,最近经常听到这个词,应用场景蛮多,包括流布局,等高布局等,于是乎就总结一下。

一. 原理
1. 对于普通文档流(normal
flow)中的元素(除浮动/绝对对位/固定定位),这些元素的位置跟随文档流的变化而变化。而负边距会使这些元素在文档流的位置发生偏移,与相对定位不同,通过负边距偏移的元素会放弃偏移前所占据的空间,让文档流的其他元素“流”过来填充这部分空间,如下图
当块元素不设置宽度(或width: auto)时,盒模型对于宽度和高度的计算公式为:
子元素的宽度 = 父元素的宽度 – 父元素的左右padding – 子元素的左右margin
父元素的高度 =  子元素最下边界 – 子元素的最上边界
由此公式可以解释例图的现象:
a) 水平方向:当块元素的宽度 不进行设置时,负边距可以加宽元素的宽度
b) 垂直方向:父元素的高度减少了 15*4
即60px,总的来说,元素的上下边界由margin决定,而负边距相当于将边界向里收而如论实际尺寸是多少,在标准浏览器中父元素还需要一个
overflow: hidden属性
c) 文档流只能向左或是向上流动
2.
对于浮动元素,负边距对其影响与文档流的元素类似。文档流元素的位置由文档流决定,而浮动元素可以看做有一个“浮动流”的存在,既可以向左,又可以向右
3.
对于绝对定位元素,top、right、bottom、left等是自身元素与最近已定位的祖先元素的距离,当margin为正时,元素的边界是向外扩的,当margin为负时,边界是向里收的。
二. 应用场景
1. 水平垂直居中 : 负边距 + 定位
使用绝对定位将 content的定点定位到body的中心,然后使用负边距
(content宽高的一半),将content的中心拉回到body的中心,来实现水平垂直居中的效果
.content{
        width:550px;
        height:400px;
        position:absolute;
        top:50%;
        left:50%;
        margin-left:-275px;
        margin-top:-210px;
        border:1px dashed #333;
        background:#eee;
        -moz-border-radius:5px;
        -webkit-border-radius:5px;
        border-radius:5px;
        padding:10px;
}

点击 Demo

2. 去除列表右边距

项目中经常会使用浮动列表展示信息,为了美观通常为每个列表之间设置一定的间距(margin-right),当父元素的宽度固定式,每一行的最右端的li元素的右边距就多余了,去除的方法通常是为最右端的li添加class,设置
margin-right:0; 这种方法需要动态判断为哪些li元素添加class,麻烦!!!利用负margin就可以实现下面这种效果:
HTML 结构
<div>
  <ul>
    <li><img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/250668/o_margin1.png" alt="" /></li>
    <li><img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/250668/o_margin1.png" alt="" /></li>
    <li><img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/250668/o_margin1.png" alt="" /></li>
    <li><img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/250668/o_margin1.png" alt="" /></li>
    <li><img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/250668/o_margin1.png" alt="" /></li>
    <li><img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/250668/o_margin1.png" alt="" /></li>
    <li><img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/250668/o_margin1.png" alt="" /></li>
    <li><img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/250668/o_margin1.png" alt="" /></li>
    <li><img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/250668/o_margin1.png" alt="" /></li>
    <li><img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/250668/o_margin1.png" alt="" /></li>
  </ul>
</div>
CSS
.list_wrap{
        width:640px;
        overflow:hidden;
        background:#ccc;
}
.list_wrap ul{
        margin-right:-30px;
        overflow:hidden;
        zoom:1;
}
.list_wrap ul li{
        float:left;
        width:120px;
        height:120px;
        margin:0 10px 10px 0;
}
.list_wrap ul li img{
        width:120px;
        height:120px;
}
.remove_margin_bottom{
        margin-top:30px;
}
.remove_margin_bottom ul{
        margin-bottom:-10px;
}
点击 Demo

3. 去除列表最后一个li元素的border-bottom

列表中我们经常会添加border-bottom值,最后一个li的border-bottom往往会与外边框重合,视觉上不雅观,往往要移除。效果如下:


方法有多种,加class去除,这种方法需要破坏html结构;另一种方法是使用结构伪类
:nth-child(an+b),设置a:last-child{border-bottom:0
none;}
,可惜我们的IE6不支持这么高级的选择器。不过,我们可以为li元素设置margin-bottom:-1px;来实现,不过不要为ul/ol设置高度,需要高度请在外层嵌套一个div设置高度

HTML
结构
<ul>
  <li>地月成像照稍后公布 星箭分离延迟25秒</li>
  <li>火箭一级残骸坠落贵州 整流罩坠落江西</li>
  <li>中国航天体制之困 NASA:何时返月不重要</li>
  <li>长城现特警执勤 故宫游客超最大容量 国庆专题</li>
  <li>9月人民币对美元涨1.74% 创汇改最大单月涨幅</li>
  <li>温家宝:中国将积极参与希腊新发行国债认购</li>
  <li>俄总统梅德韦杰夫拟下月登上日俄争议岛屿</li>
  <li>美联航合并大陆航空 世界最大航空公司诞生</li>
</ul>
CSS
ul{
        margin:20px;
        width:390px;
        background:#F4F8FC;
        -moz-border-radius:3px 3px 3px 3px;
        -webkit-border-radius:3px 3px 3px 3px;
        border-radius:3px 3px 3px 3px;
        border:2px solid #D7E2EC;
}
ul li{
        height:25px;
        line-height:25px;
        padding:5px;
        border-bottom:1px dotted #D5D5D5;
        margin-bottom:-1px;
}
点击 Demo

4.
负边距自适应布局

此例适用于一栏宽度固定一栏宽度自适应的布局,导航栏宽度固定,内容区域随着浏览器的大小而自动缩放。

HTML结构
<div id="header">
  <h2>#header</h2>
</div>
<div id="container">
  <div id="content">
   <h2>#content</h2>
    your content goes here.
  </div>
</div>
<div id="sidebar">
  <h2>#sidebar</h2>
  <ul>
    <li>link-1</li>
    <li>link-2</li>
    <li>link-3</li>
    <li>link-4</li>
    <li>link-5</li>
    <li>link-6</li>
    <li>link-7</li>
    <li>link-8</li>
  </ul>
</div>
<div id="footer">
  <h2>#footer</h2>
</div>

CSS
#header {
        background:#d7dabd;
        height:60px;
}
#container {
        width:100%;
        float:left;
        margin-right:-200px;
}
#content {
        background:#f1f2ea;
        margin-right:200px;
}
#sidebar {
        background:#e5e7d3;
        width:200px;
        float:right;
}
#footer {
        background:#d7dabd;
        clear:both;
        height:60px;
}
点击Demo

5.
Google reader 自适应渐变圆角按钮

现在大家都比较追求纯,前端人士追求的是纯css,无图片,自适应。google reader
的按钮就具备了以上特点,而且还有渐变的效果,其内层div的左右border就使用了负边距以达到模拟1像素圆角的效果,下图是效果放大图:
HTML结构
<div class="button-outer-box">
  <div class="button-inner-box">
    <div class="button-content">
      <span>我是纯CSS制作的自适应渐变圆角按钮</span>
    </div>
  </div>
</div>
CSS
.button-outer-box {
        border-bottom:1px solid #AAA;
        border-top:1px solid #BBB;
        display:inline-block;
        cursor:pointer;
}
.button-inner-box{
        background:#E3E3E3;
        border-left:1px solid #BBB;
        border-right:1px solid #AAA;
        margin:0 -1px;
        position:relative;
}
.button-top-shadow {
        background:#F9F9F9;
        border-bottom:0.23em solid #EEE;
        height:0.692em;
        display:block;
        position:absolute;
        top:0;
        left:0;
        right:0;
}
.button-content {
        color:#333;
        line-height:1.4em;
        padding:0 0.461em;
        position:relative;
        text-align:center;
}
点击Demo

6.
三栏等高

此例关键是给每个框设置大的底部内边距,然后用数值相似的负外边距消除这个高度。这会导致每一列溢出容器元素,如果把外包容器的overflow属性设为hidden,列就在最高点被裁切。
HTML结构
<div class="wrapper">
  <div class="box">
    <h1>Andy Budd</h1>
    <p>your content goes here.</p>
    <div class="bottom"></div>
  </div>
  <div class="box">
    <h1>Richard Rutter</h1>
    <p>your content goes here.</p>
    <div class="bottom"></div>
  </div>
  <div class="box">
    <h1>Jeremy Keith</h1>
    <p>your content goes here.</p>
    <div class="bottom"></div>
  </div>
</div>

CSS
.wrapper {
        overflow:hidden;
        width:100%;
        position: relative;
}
.box {
    width:250px;
        margin-left:20px;
        float:left;
        display:inline;
        padding:20px;
        padding-bottom:220px;
        margin-bottom:-200px;
        background:#89ac10 url(img/top.gif) no-repeat left top;
}

.bottom {
        position:absolute;
        bottom:0;
        height:20px;
        width:290px;
        background:#89ac10 url(img/bottom.gif) no-repeat left bottom;
        margin-left:-20px;
}
点击Demo

参考博文:
http://www.topcss.org/?p=94
http://www.cnblogs.com/2050/archive/2012/08/13/2636467.html
http://blog.sina.com.cn/s/blog_63ff72a60101d000.html

standard
  1. lovecicy - 2013 年 8 月 13 日 9:02 下午

    新浪的图片不能外链,都显示不出来了

    回复

Have your say