理解并运用CSS的负margin值

本文样式代码采用 SCSS。

浏览器兼容性为 IE6+。

你的网页中,不可能没有使用过 margin。大多数情况下,我们采用的都是正数的 margin 值,可能有时候会用到负的 margin
值。在我们的印象中,负的 margin 值就类似于浏览器的 hack 一样,不被人接受。但是,本文要说明的就是,负的 margin 值并不是
hack,这是正常范围内的写法。

Negative values for margin properties are allowed, but there may be implementation-specific limits. —— W3C

根据 W3C,margin 是能够接受负值的,只是在具体实现上有一些区别。

那么,设置 margin 为负值究竟会是什么样的效果呢?

与设置正值不同,margin 设置负值需要根据设置的方向以及元素是否浮动以及其定位方式来判断最终的行为。

所以,具体行为按照以下几种情况说明。

第一种情况:元素没有设置浮动且没有设置定位或者 position 为 static

如果元素没有设置浮动并且没有设置定位或者 position 属性为 static 的情况下,对元素的 margin 设置负值会有以下的效果:

设置的 margin 的方向为 top 或者 left

当设置负值的 margin 的方向为 top 或者 left 的时候,元素会按照设置的方向移动相应的距离。

比如,设置 margin-left: -100px;。 那么,元素会往左移动 100px。对于设置 margin-top 也是一样的道理。

设置的 margin 的方向为 bottom 或者 right

当设置负值的 margin 的方向为 bottom 或者 right 的时候,元素本身并不会移动,元素后面的其他元素会往该元素的方向移动相应的距离,并且覆盖在该元素上面。

比如,设置 margin-right: -100px;。那么,元素本身并不会移动,后面的元素会向左移动 100px 到该元素上。对于设置 margin-bottom 也是同样的道理。

同时,在元素不指定宽度的情况下,如果设置 margin-left 或者 margin-right 为负值的话,会在元素对应的方向上增加其宽度。效果就和设置 padding-left 或者 padding-right 一样。

第二种情况:元素没有设置浮动且 position 为 relative

如果元素没有设置浮动,但是设置了相对定位,设置 margin 为负值的时候,表现如下:

设置的 margin 的方向为 top 或者 left

当设置负值的 margin 的方向为 top 或者 left 的时候,元素也会按照设置的方向移动相应的距离。

设置的 margin 的方向为 bottom 或者 right

当设置 margin-bottom/left 的时候,元素本身也不会移动,元素后面的其他元素也会往该元素的方向移动相应的距离,但是,该元素会覆盖在后面的元素上面 (当然,此处说的情况肯定是后面的元素没有设置定位以及 z-index 的情况)。

第三种情况:元素没有设置浮动且 position 为 absolute

如果元素没有设置浮动,但是设置了绝对定位,设置 margin 为负值的时候,表现如下:

设置的 margin 的方向为 top 或者 left

当设置负值的 margin 的方向为 top 或者 left 的时候,元素也会按照设置的方向移动相应的距离。

设置的 margin 的方向为 bottom 或者 right

由于设置绝对定位的元素已经脱离了标准文档流,所以,设置 margin-right/bottom 对后面的元素并没有影响。

第四种情况:元素设置了浮动

肯定没有既设置了浮动又设置绝对定位的情况,那样太荒唐了。

设置了浮动的元素,再设置 postion: relative; 的话,元素的行为和单独设置 float 是一样的。

对于设置了浮动的元素,设置 margin 为负值的时候,表现如下:

如果设置的 margin 的方向与浮动的方向相同,那么,元素会往对应的方向移动对应的距离。

比如:


  1. .elem { 
  2.  
  3.   float: right; 
  4.  
  5.   margin-right: -100px; 
  6.  
  7. }  

该元素则会向右移动 100px。

如果设置 margin 的方向与浮动的方向相反,则元素本身不动,元素之前或者之后的元素会向钙元素的方向移动相应的距离。

比如:


  1. .elem { 
  2.  
  3.   float: right; 
  4.  
  5.   margin-left: -100px; 
  6.  
  7. }  

位于该元素左边的元素则会向右移动 100px,同时覆盖在该元素上。

如果后面的元素也设置了浮动的话,我们以一个具体的例子来说明。


  1. <div class="container"> 
  2.     <div class="left"></div> 
  3.     <div class="right"></div> 
  4. </div>  

  1. .container { 
  2.     min-height: 300px; 
  3.     margin: 30px auto; 
  4.     overflow: hidden; 
  5.     border: 1px solid #000000; 
  6.     
  7.     .left { 
  8.         float: left; 
  9.         width: 400px; 
  10.         height: 200px; 
  11.         margin-right: -300px; 
  12.         background: purple; 
  13.     } 
  14.      
  15.     .right { 
  16.         float: left; 
  17.         width: 300px; 
  18.         height: 200px; 
  19.         background: #cccccc; 
  20.     } 
  21. }  

.left 和 .right 都设置了浮动,在 .left 上设置了 margin-right: -300px;,那么,.right 会向左移动 300px,从而覆盖在.left 上。这种行为与没有既没有设置浮动也没有设置定位的表现类似。

到此,我们把设置负 margin 的各种情况以及在各种情况下的表现都大概了解了一遍。那么,我们真正运用到实际中会是什么样子呢。

半遮挡的标题

原谅我措辞不好,大概就是下图的效果:

按照一般的思想,肯定是直接给 title 设置绝对定位,然后再将其调整过去。

但是,按照我们现在所说的,其实很简单就能实现这个效果。

这里只写了主要部分的代码。


  1. <div class="title">Hey This is title!</div> 
  2.  
  3. <div class="content">Hah! This is content.</div>  

  1. .title { 
  2.     position: relative; 
  3.     width: 200px; 
  4.     height: 60px; 
  5.     margin-bottom: -30px; 
  6.     margin-left: -20px; 
  7.     background: #000000; 
  8.  
  9. .content { 
  10.     max-width: 800px; 
  11.     height: 400px; 
  12.     padding: 0 50px; 
  13.     background: yellow; 
  14. }  

我们为 title 设置了两个 margin 的负值,分别是 margin-bottom: -30px;,以及 margin-left: -20px;。

设置 margin-bottom 是为了让 content 向上移动,设置 margin-left 是为了让 title 向左移动一小段距离。

还有个需要注意的地方就是,需要给 title 设置 position: relative;,根据我们的第二种情况所说的,这样,才能保证 title 覆盖在 content 之上。

简单的一列定宽的两列流式布局

根据我们的最后一种情况,通过设置 margin 为负值,我们可以很容易的实现一列定宽的两列流式布局。


  1. <div class="container"> 
  2.  
  3. <div class="left"></div> 
  4.  
  5. <div class="right"></div> 
  6.  
  7. </div>  

  1. .left { 
  2.     float: left; 
  3.     width: 100%; 
  4.     height: 200px; 
  5.     margin-right: -300px; 
  6.     background: purple; 
  7. .right { 
  8.     float: left; 
  9.     width: 300px; 
  10.     height: 200px; 
  11.     background: #cccccc; 
  12. }  

唯一需要注意的地方就是设置了 100% 宽度的元素上的 margin 负值的绝对值一定要和定宽的元素的宽度相同。

两边固定,中间自适应的三列布局

这是一个很老的话题了,以前也有各种实现的方式,比如双飞翼布局,或者圣杯布局。

我们此处就以双飞翼布局来作示例。

先设置页面结构:


  1. <div class="container"> 
  2.  
  3. <div class="center"></div> 
  4.  
  5. <div class="left"></div> 
  6.  
  7. <div class="right"></div> 
  8.  
  9. </div>  

此处我们没有把 center 放在中间,具体原因后面会解释。

然后,我们设置这三列都浮动:


  1. .left, 
  2. .right, 
  3. .center { 
  4.     float: left; 
  5.     height: 500px; 
  6. }  

同时为他们指定宽度:


  1. .left { 
  2.     width: 300px; 
  3.     background: #000000; 
  4.  
  5. .right { 
  6.     width: 400px; 
  7.     background: #00FFFF; 
  8.  
  9. .center { 
  10.     width: 100%; 
  11.     background: #93c759; 
  12. }  

现在我们要让 left 在左边,相当于就是让它覆盖在 center 的上面,所以,只需要这样一句:


  1. margin-left: -100%; 

同时,要让 right 在右边,同理,这样设置:


  1. margin-left: -400px; 

注意,此处的 margin 值的绝对值与 right 的宽度值相同。

其实,这样设置,我们的三列布局就基本完成了。

那么,我们为什么要把 center 放在 left 和 right 之前呢?

这个其实涉及到元素的堆叠顺序的知识 (这里就不详细讲解了,后面有时间的话专门拿一篇文章来讲解吧),此处简单说明一下。

由于我们的三列都设置了浮动,所以,从某种意义上说,它们三个是在同一个平面的 (相当于 z-index 相同),那么,这里就不能根据 CSS 来判断堆叠顺序了。所以,此处的 HTML 结构就决定了它们的堆叠顺序:所谓后来居上。

我们要让 left 在 center 之上,所以,肯定需要让 left 元素放在 center 之前。

所以,三列布局完整的 SCSS 代码如下:


  1. .container { 
  2.     overflow: hidden; 
  3.      
  4.     .left, 
  5.     .right, 
  6.     .center { 
  7.         float: left; 
  8.         height: 500px; 
  9.     } 
  10.      
  11.     .left { 
  12.         width: 300px; 
  13.         margin-left: -100%; 
  14.         background: #000000; 
  15.     } 
  16.      
  17.     .right { 
  18.         width: 400px; 
  19.         margin-left: -400px; 
  20.         background: #00FFFF; 
  21.     } 
  22.      
  23.     .center { 
  24.         width: 100%; 
  25.         background: #93c759; 
  26.     } 
  27. }  


作者:Erichain_Zain

来源:51CTO

时间: 2024-09-18 20:19:45

理解并运用CSS的负margin值的相关文章

css中负Margin你不知道的秘密

现如今,负margin技术的应用可谓越来越广,任一个大型站点惊鸿一瞥之下都会有其身影所在.个人认为负margin技术是学习css路上必不可缺少的课题之一,许多高级应用及疑难杂症修复都可以使用负margin技术进行实现. 负margin理论: 在说明什么是负margin之前,你得清楚margin是个啥么玩意,如果还不清楚可以先阅读本人的前一篇文章<不要告诉我你懂margin>,预补下知识,回头再读这篇文章,相信俩篇文章都能给你带来不少的收获. 为了形象.易懂的解释负margin,我们将引入W3C

CSS网页设计经验分享:负margin

文章简介:负margin是好东西. 上个月完成的项目,举个让我纠结N小时的模块,先上图: 默认状态为灰色,不带圆圈,已完成状态为红色,当前进行中显示为黄色,并且圆圈在两个字中间,最后一个状态"成功"如果为灰色,线条要小于文字,但其它部分要连贯.原型代码如下,为了JS结构当然越简单越好: <ul>< li class="status_finished">选择</li>< li class="status_curren

css-&amp;amp;quot;两个元素之间的间距取较大的那个margin值&amp;amp;quot;,这种说法不对吧?应取相加值吧?

问题描述 "两个元素之间的间距取较大的那个margin值",这种说法不对吧?应取相加值吧? 有这样一种说法: "因为不同的浏览器对css的支持不同,一般两个元素之间的间距或者说是距离大小,并不是两个元素的margin相加,而是取较大的那个margin值!" 我遇到的情况都是一个元素的右边距和另一个元素的左边距相加为这两个元素之间的间距. 有"取较大的那个margin值"这种情况吗? 请举例,谢谢! 解决方案 是取较大的,因为较大的已经满足两个条件

请教各位算法大神,acm一道题:赋权无向图的最小权值遍历用什么算法(存在负权值)?

问题描述 请教各位算法大神,acm一道题:赋权无向图的最小权值遍历用什么算法(存在负权值)? 1C 如题,问题是这样的:有一赋权无向连通图,可以从任意一结点出发,求遍历所有结点的最小权值路线.结束点也是任意的,每个节点也没有访问次数的限制,但必须每个节点都要被访问到.,想问一下用什么算法呢? 解决方案 可以参考djstera算法,求最短路径~借鉴其中的标记功能,只不过结束状态标志是所有节点均已遍历. 解决方案二: 可以参考djstera算法,求最短路径~借鉴其中的标记功能,只不过结束状态标志是所

javascript-js获取css样式返回的值如何进行判断?

问题描述 js获取css样式返回的值如何进行判断? 比如返回了rbg(255,0,0),用直接字符串"rbg(255,0,0)"做相等判断似乎不行,返回false,不知道用什么方法可以做判断? 解决方案 返回了rbg(255,0,0),那么alert下返回值是显示什么的? 解决方案二: 返回值前后可能会有空格,所以判断会可能不相等 解决方案三: 返回的可能不是一个字符串,,typeof看看,,

css padding 与margin的区别

css padding 与margin的区别,下面我们来看看一张图片,然后再来具体的根据图片进行分析padding 与margin的区别何在吧 如上图,A,B两个方框,A代码padding,B代表margin,现在我们看A箭头与蓝色边框的距离,这就是padding叫做内边距,下面再来看看B外面的箭头与B之前的距离就是我们所说的margin的,叫做外间距,哈哈你现在应该明白了,什么是padding,什么是margin, 本站原创转载请注明来处www.111cn.net

彻底理解浮动float CSS浮动详解 清除浮动的方法

原文:彻底理解浮动float CSS浮动详解 清除浮动的方法  我们把网页的常用的布局格式分为以下三种:   1.标准流.  所谓的标准流就是,行内元素自己单独一行,而块级元素是上下显示的. 以前我们学习的都是标准流.   注意:标准流使我们网页布局中最稳定的一种结构       2. 浮动流  使我们学习的脱离标准流的第一种方式.会影响我们标准流的排列.所以,我们布局的时候,能用标准流做的,就不用浮动做.       3. 定位流   定位流也是脱离标准流的一种模式.它完全脱离标准流,不会对标

IE6中float造成margin值双倍解决办法

例1 一个元素向左浮动(float:left),且添加了向左空白边(margin-left:10px),那么会自动的加一倍变成30px. 例:  代码如下 复制代码 <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>IE6双空白边Bug</title> </head> <body> <div style="

理解Java中的引用传递和值传递

关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天学习和分析一下,着急可以先看最后的结论. >>基本类型和引用类型在内存中的保存 Java中数据类型分为两大类,基本类型和对象类型.相应的,变量也有两种类型:基本类型和引用类型. 基本类型的变量保存原始值,即它代表的值就是数值本身: 而引用类型的变量保存引用值,"引用值"指向内存空间