css中的负margin技术以及运用

刚刚开始学习css的时候,我采用了float为主来实现布局的方式,但是运用浮动很长一段时间之后,我发现这是一种被人牵着鼻子走的做法。至少,页面上不应过多的运用浮动,尤其是不要拿来确定整个布局。

很简单的道理,当你用了float:left,后面的div很可能需要跟着用float:left,而且当宽度不够的时候,本来该和上一个div一个水平线上的div跑到下面去了,如果某个div有margin属性,还会遇到ie6那个烦人的bug。而且浮动之后,你还必须在合适的地方使用清除浮动。

在网上看到了一篇讲负margin的文章,仔细研究之后,觉得很实用。我将那篇文章的内容提炼出来,原文写的很好,但是需要花很长的时间去阅读。

 

为了形象、易懂的解释负margin,我们将引入W3C上没有的参考线的说法。何谓参考线?参考线就是 margin移动的基准点,此基准点相对于box(自身)是静止的。而margin的数值,就是box相对于参考线的位移量。

一个完整的margin属性是这么写的margin: top right bottom left;(eg: margin:10px 20px 30px 40px)。在margin属性中一共有两类参考线,top和left的参考线属于一类,right和bottom的参考线属于另一类。top和left是以外元素为参考,right和bottom是以元素本身为参考。margin的位移方向是指margin数值为正值时候的情形,如果是负值则位移方向相反。

 

先看看一个完整的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<meta http-equiv= "Content-Type" content= "text/html; charset=utf-8" />      
<title>Margin参考线举例说明</title>      
<style type= "text/css" >      
*{margin:0; padding:0;}      
.wrap{width:400px; border:5px solid #aaa;}      
.example{width:200px; height:200px; background: #CCCCFF;}      
.normal{width:200px; height:200px; background: #CCE8CF;}      
               
.example{margin:-10px 20px -30px 40px;}      
               
</style>      
</head>      
<body>      
<div class= "wrap" >      
   <div class= "example" >example元素:margin参考线举例说明文字,请查看此元素由于margin的变化所移动的位移量。</div>      
   <div class= "normal" >一个普通的Box</div>      
</div>      
</body>      
</html>

 

来分析这段代码,example元素下方有一相邻元素normal(注:这里分析的是添加和删除margin后的example元素,normal元素仅作为example元素前后效果的参照)。

根据上文的参考线原理margin:-10px(top) 20px(right) -30px(bottom) 40px(left); 上-10px和左40px将以外元素为参考,所谓外元素就是本元素的边界元素(再白话点的解释就是元素的紧邻元素,这里涉及到containing block知识,可自行网上搜索)。example元素上边和左边的边界元素即为wrap父元素,wrap父元素为基准点,example的margin-top为-10px,想象下如果这里margin-top为+10px会什么情况,没错如果为+10px,example元素相对于wrap父元素边缘为基准,那么example元素会同wrap父元素10px产生间隙边距,那么反过来,margin-tip:-10px;还是与wrap父元素边缘为基准,反过来向上推10px的距离位置。example元素的margin-left为40px,这里就按照正常逻辑相隔40px边距,同理如果为-40px,那么就是反方向向左推进40px的距离位置。

再来看example元素的margin-right和margin-bottom,由上文得知这俩个值是以元素本身为参考。什么叫以元素本身为参考呢,确切含义是指以自身为参考来影响周围元素的位置(实质即为影响下边和右边相邻元素的参考线)。这里的margin-bottom为-30px,对于其自身位置没有任何变化,但是对于其下方元素normal元素产生了极大的影响,因为normal元素的上边界元素即为example元素,根据example元素边界来判定自身位置,想象下如果example元素margin-bottom为+30px,那么example元素将隔开下方的normal元素,反之为-30px,下方normal元素由于example参考线内凹,导致了normal元素自个儿身不由己的被“提”了上去了。这就是以自身为参考影响周围元素位置的含义。

当margin四个值都为正数值的话,那么margin按照正常逻辑同周围元素产生边距。当元素margin的top和left是负值时会引起元素的向上或向左位置移动。而当元素margin的bottom和right是负值时会影响右边和下边相邻元素的参考线。

 

接下来我们将利用两个例子深入讲解负margin技术的应用领域。

负margin在Tab选项卡中的应用: 

最核心的就是下方俩行高亮部分代码,第二行的margin-bottom:-1px;使下方的正文部分向上“提”了1px的距离,从而达到了鼠标上移后选项卡白色遮住下方黑色边框的效果(注:由于IE不是符合W3C标准,所以当鼠标移到选项卡上时需要添加一个额外属性position:relative;来修复IE不覆盖下方边框的这个Bug)。第四行的margin-left:-1px;的目的是让四个选项卡向左移动1px的距离,达到左右都只有一条分割线的效果。

 

1
2
3
4
5
6
7
8
9
.demoTab{width:400px; font:14px/1.5 Microsoft YaHei,verdana,Helvetica,Arial,sans-serif;}
.demoTab .demoTabHd{margin-bottom:-1px; border:1px solid #6C92AD; border-bottom:none; background:#EAF0FD;}
.demoTab .demoTabNav{height:28px; overflow:hidden; *zoom:1;}
.demoTab .demoTabList{float:left; margin-left:-1px;  padding:0 22px; line-height:28px; border-left:1px solid #6C92AD; border-right:1px solid #6C92AD;  font-weight:bold; color:#005590; text-align:center; cursor:pointer;}
.demoTab .demoTabList.current{position:relative; background: #fff;}
.demoTab .demoTabBd{border:1px solid #6C92AD;}
.demoTab .demoTabBd .roundBox{padding:15px;}
.demoTab .demoTabContent{display:none;}
.demoTab .demoTabContent.current{display:block;}

HTML代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id= "demoTab" class= "demoTab" >
   <div class= "demoTabHd" >
     <ul class= "demoTabNav clearfix" >
       <li class= "demoTabList current" >前端</li>
       <li class= "demoTabList" >实战</li>
       <li class= "demoTabList" >交互</li>
       <li class= "demoTabList" >优化</li>
     </ul>
   </div>
   <div class= "demoTabBd" >
     <div class= "roundBox" >
       <div class= "demoTabContent current" >这是第一个选项卡的内容。</div>
       <div class= "demoTabContent" >这是第二个选项卡的内容。</div>
       <div class= "demoTabContent" >这是第三个选项卡的内容。</div>
       <div class= "demoTabContent" >这是第四个选项卡的内容。</div>
     </div>
   </div>
</div>

利用负margin制作自适应左右布局:

1
2
3
4
5
.demoLayout{width:500px; border:1px solid #aaa; background:#EEEEEE;}
.demoLayout .roundBox{padding:10px; min-height:170px; _height:170px;}
.demoLayout .demoShowPic img{padding:1px; border:1px solid #DAA520;}
.demoText{margin:-170px 0 0 215px;}
.demoLayoutBtn{margin:15px 0 0 0;}
1
2
3
4
5
6
<div id= "demoLayout" class= "demoLayout" >
   <div class= "roundBox" >
     <div class= "demoShowPic" ><img width= "200" height= "166" src= "toygersKittens.jpg" alt= "toygers kittens" /></div>
     <div class= "demoText" >利用负margin制作自适应左右布局</div>
   </div>
</div>

如上例这类布局效果(左边一个固定图片,右边为内容),负margin能够替代float浮动布局,进行左右布局规划,并且拥有float所没有的自适应效果。

根据上面的几个实例,相信你已经对负margin技术有了一个比较完整的理解。负margin不但可以做出一般CSS属性所不能达到的效果还能够化繁为简、化腐朽为神奇之奇效,当然负margin用到的地方不仅仅是这些,还有许多效果都是需要负margin技术来实现的,只要你耐心的去实践去探索,相信你会发现更多负margin用到得场合。

负边距(negative margin)实现自适应的div左右排版

我记得我写过一篇  css中的负margin技术以及运用  的文章,那是很久以前的事了,现在看来那篇文章讲了很多,但是始终没把握好重点,现在再通过这篇文章clear一下思路。

    左右排版本来是可以这样实现的:两边都使用百分比,然后左右浮动。但是这样做满足不了下面这样的场景:    在一个文章页面里面,分为左边的正文区域和右边的与文章关联的其他信息区域,我想让正文区域能随着用户的显示屏宽度变化而变化,这似乎百分比就能做到,但是如果使用百分比,左右两边都必须有一个固定的比值,那样右边也会随着用户显示屏的宽度变化,如果用户的显示屏很宽,那这右边就显得似乎国语宽了,正文无论多款是无所谓的,但是侧边最好是一个固定值。
   就像这种下图所示效果: 

       
    也就是说我需要一个左边自适应,而右边固定的左右布局,或者说某一边固定,另一边占据剩余部分,该如何做呢?
    我找到的最好的答案是使用   负margin  (配合浮动),下面概括一下原理:
    使用负margin可以使当前的div左边能容纳下面的div浮动上来,因此把右边的div摆在前面,左边的摆后面,右边的使用负margin就能让左边的浮上来,这样就遮住了右边的左半部分,只要右边再内部使用一个div,外左边距为左边的宽度就实现了左右的排版。

1、左边固定,右边自适应
    (1)右边使用margin-left值为200(刚好是左边的宽度)的宽度,那么左边就刚好能浮动上来。为什么说浮动上来呢,因为如果没有这个margin: 0 0 0 -200px;由于右边的宽度是100%,因此左边肯定是排在下面的。
    (2)左边虽然能浮动上来,但是右边和左边的内容是有重叠的

           
所以你还需要绿色部分的代码,右边再内部使用一个div,外左边距为左边的宽度


<div>
    <div style="float: right; margin: 0 0 0 -200px; width: 100%;">
        <div style="margin: 0 0 0 200px; background: #e4e4e4;">
            这是右边部分
        </div>
    </div>
    <div style="float: left; width: 200px; background: #669999">
            这是左边部分
    </div>
</div>
    这个产生的效果如下图:(图片区域宽度固定的,但是文字是占据这个div的剩余部分,这里右边没有紧贴边框是因为父div有较大padding的原因没能挤满,不要受误导)。
    提示:真正在实现的时候好像没必要左边必须写在后面,我试过,即使按从左到右书写也是可以的,但是很多大型网站都是反着写,我就按正规的来讲了。



2、右边固定,左边自适应
跟上一个最大的不同点就是,左右两个div容器的代码的前后位置换了,原因就是"float:rihgt"一定要在"float:left"前面。

  1. <div>
  2. <div style="float: right; width: 200px; background: #669999">
  3.             这是右边部分
  4. </div>
  5. <div style="float: left; margin: 0 -200px 0 0; width: 100%;">
  6. <div style="margin: 0 200px 0 0; background: #e4e4e4;">
  7.                 这是左边部分
  8. </div>
  9. </div>
  10. </div>
复制代码

3、左右各占一定百分比,这就简单了,把上面任意一种将200px改成比例值20%就实现了。

  1. <div>
  2. <div style="float: right; margin: 0 0 0 -20%; width: 100%;">
  3. <div style="margin: 0 0 0 20%; background: #e4e4e4;">
  4.                 这是右边部分
  5. </div>
  6. </div>
  7. <div style="float: left; width: 20%; background: #669999">
  8.             这是左边部分
  9. </div>
  10. </div>
复制代码

4、再加一栏,实现左中右三栏布局。这只要再加一栏,float为right的多空一些位置就行了。这里以按比例为例

  1. <div>
  2. <div style="float: right; margin: 0 0 0 -40%; width: 100%;">
  3. <div style="margin: 0 0 0 40%; background: #e4e4e4;">
  4.                 这是右边部分
  5. </div>
  6. </div>
  7. <div style="float: left; width: 20%; background: #669999">
  8.             这是左边部分
  9. </div>
  10. <div style="float: left; width: 20%; background: #663333">
  11.             这是中间部分
  12. </div>
  13. </div>
复制代码

5、实现框架页的效果(左右可分别出现滚动条,页面无滚动条):只要左右div各加position: absolute; overflow: scroll; height: 100%;左边再加left: 200px;即实现了,这里用了绝对定位,因此float属性可以干掉了

  1. <div>
  2. <div style="margin: 0 0 0 -200px; width: 100%; position: absolute; overflow: scroll;
  3.             height: 100%; left: 200px;">
  4. <div style="margin: 0 0 0 200px; background: #e4e4e4;">
  5.                 这里是右边部分
  6. </div>
  7. </div>
  8. <div style="width: 200px; background: #669999; position: absolute; overflow: scroll;
  9.             height: 100%;">
  10.             这是左边部分
  11. </div>
  12. </div>
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值