W3C规范在介绍margin时有这样一句话:

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

于是,聪明的开发者们就发现了很多负边距的巧妙用法。

比如,他可以增加一个不定宽块框的宽度,他可以让一个框向上移动去覆盖另一个框,他可以让文字移动去覆盖文字,也可以让浮动框移动去覆盖另一个浮动框。

利用这些特点,我们可以实现圣杯布局和双飞翼布局、等高布局、多列布局等等实用的布局方式。

那么负边距到底是如何工作的呢?也就是说,这些现象要怎么解释?

我是这样理解的:

在可视化格式模型中,一切都是框。所有的框都处于流动状态。就像是一个个漂浮在水上的小木块儿,水会将他们往一个地方推。

而边距,就是用于截流。就像是将一条河截成两段之后,后一段的水流就无法影响到前一段水流中的小木块了儿。

普通流(normal flow):

普通流中有块级格式化上下文和行内级格式化上下文。

在块级格式化上下文中,块级框占满一行从上到下依次排列。占满一行意味着,如果他没有被设置宽度的话,他就会横向填充满整个包含框。

所以,块级格式化上下文中的应该是这样的:

所以,给第一个p元素设置margin-bottom:10px;的意思就是在第一个p元素的border-bottom边线下10px的位置,设置一条拦截线,阻止之后的框被水流冲过这条线。

而如果设置margin-bottom:-10px的话,拦截线就会被设置在第一段文字border-bottom边线上10px的位置,之后的框会从那里开始流动,也就是会覆盖住第一段文字10px。按照这个逻辑,在这个例子中,给第一段文字设置margin-bottom:-10px和给的二段文字设置margin-top:-10px的效果是相同的,因为他们都把拦截线设置在了同一个地方。

除了纵向的流外,这里还有两个横向的流,一个横向是块级框内部的,用于控制他的宽度,另一个是外部的,用于控制他的流向。给一个块级框设置margin-left: -10px;,那么他的左外边缘就会被设置在border-left左侧10px的位置,他就会去填满那10px空隙。而如果这时候他刚好没有被宽度限制的话,他的border-right就不会移动以保证他的宽度。

这也就是为什么给一个不定宽的块级框设置正边距会让他的宽度减小,设置负边距会让他的宽度增加。而给一个定宽的块级框设置左负边距会让他左移,设置右负边距对他没有影响。

上图,p1和p2都设置了margin-left: -10px,p2和p3设置了宽度为300px,p3设置了margin-right:-10px;

在行内级格式化上下文中,行级框在水平方向上依次排列,至于是从左到右还是从右到左,由direction属性决定。如果当前行盒剩余的空间不足以装下它,他就会折断,多余的部分换到下一行。纵向的margin值对于行内级框来说无效的,也就是说,行内级框只会受到一个横向流动的力。

所以,行内级格式化上下文中的流应该是这样的:

      

以direction:ltr为例,给第二个行内级框设置margin-left: -20px; margin-right: -20px,结果应该是,他和第三个行内级框向左流动20px后,第三个行内级框又向左移动20px

浮动:

浮动框的上边缘会去贴当前行盒的上边缘或是之前浮动框的下边缘,左浮动框的左边缘会去贴包含框的左边缘,或者他之前的左浮动框的右边缘。如果当前行剩余的空间容不下一个浮动框,他就会换行。(右浮动同理)

一句话描述就是,只要空间够且无阻碍,浮动框边缘一定是要挨着包含框content边缘的。

所以,浮动框的流应该是这样的:

(三个框都是左浮动,包含框做了清浮动处理,设置了宽度500px。第一个浮动宽为100%,第二个浮动宽为150px,第三个浮动宽为100px.)

浮动流的力量会推它去贴包含框的content边缘,也就是说,如果一个浮动边缘已经贴在包含框的content边缘,且没有margin的话,在那个方向上,他将不受流动的力量控制。上图中,第二个浮动的上边缘被第一个浮动挡住,第三个浮动的左边缘被第二个浮动挡住,上边缘被第一个浮动挡住。

如果给第二个浮动设置margin-left:-20px的话,他的左拦截线就会移动到第一个浮动的border-right左侧20px的位置:

如果他的margin-left的负值的绝对值大于他自身的宽度,就意味着他的上边缘不再受第一个浮动的约束,左拦截线也移动到了足以容纳他的位置,他就会上移一行,第三个浮动会被一直向左推,直到碰到包含框的左边缘:

这个时候第二个浮动的负margin绝对值的增大会让他继续往左移动,而第三个浮动将不受影响,因为它的左边缘已经贴在包含框的content左边缘,已经没有力量会让他左移动了,除非,给他设置一个负边距值,当这个值足够让他的上边界拜托第一个浮动的阻碍时,它也会上移:

绝对定位:

绝对定位的框完全脱离普通流,所以他对其他任何框都不会产生影响,也就意味着,他的margin-left和margin-top会让他左右和上下移动,而margin-right和margin-bottom则不会产生任何影响。

总结:

边距用于截流,边距的正负决定拦截线在对应边框线的哪一边(上下左右)。截流之后元素动不动,往哪里动,还是要看它本身处于哪一种流中。

探究负边距(negative margin)原理的更多相关文章

  1. (转)CSS布局-负边距-margin

    css中的负边距(negative margin)是布局中的一个常用技巧,只要运用得合理常常会有意想不到的效果.很多特殊的css布局方法都依赖于负边距,所以掌握它的用法对于前端的同学来说,那是必须的. ...

  2. css中的负边距

    css中的负边距(negative margin)是布局中的一个常用技巧,只要运用得合理常常会有意想不到的效果.很多特殊的css布局方法都依赖于负边距,所以掌握它的用法对于前端的同学来说,那是必须的. ...

  3. CSS布局奇淫巧计之-强大的负边距

    css中的负边距(negative margin)是布局中的一个常用技巧,只要运用得合理常常会有意想不到的效果.很多特殊的css布局方法都依赖于负边距,所以掌握它的用法对于前端的同学来说,那是必须的. ...

  4. CSS布局之-强大的负边距

    css中的负边距(negative margin)是布局中的一个常用技巧,只要运用得合理常常会有意想不到的效果.很多特殊的css布局方法都依赖于负边距,所以掌握它的用法对于前端的同学来说,那是必须的. ...

  5. CSS3与页面布局学习笔记(四)——页面布局大全(负边距、双飞翼、多栏、弹性、流式、瀑布流、响应式布局)

    一.负边距与浮动布局 1.1.负边距 所谓的负边距就是margin取负值的情况,如margin:-100px,margin:-100%.当一个元素与另一个元素margin取负值时将拉近距离.常见的功能 ...

  6. margin 负边距 的知识点

    本文介绍了css负边距在普通文档流中的作用和效果.左和右的css负边距对元素宽度的影响.css负边距对浮动元素的影响.css负边距对绝对定位元素的影响.懒人建站偶然浏览到这篇文章,感觉非常好,于是分享 ...

  7. IE6 IE7 IE8(Q) 负边距 (margin) 导致元素溢出 hasLayout 容器时显示异常

    标准参考 根据W3C CSS2.1规范第8.3节中的描述,边距属性设置了一个框的边距区的宽度.'margin' 缩写属性设置所有四边的边距,而其它的边距属性( 'margin-top' ,'margi ...

  8. RB1001: IE6 IE7 IE8(Q) 负边距 (margin) 导致元素溢出 hasLayout 容器时显示异常

    标准参考 根据W3C CSS2.1规范第8.3节中的描述,边距属性设置了一个框的边距区的宽度.'margin' 缩写属性设置所有四边的边距,而其它的边距属性( 'margin-top' ,'margi ...

  9. CSS负边距margin的应用

    原文 简书原文:https://www.jianshu.com/p/75a178e65207 相关文章 CSS负margin的影响:https://www.cnblogs.com/shcrk/p/93 ...

随机推荐

  1. 在jekyll模板博客中添加网易云模块

    最近使用GitHub Pages + Jekyll 搭建了个人博客,作为一名重度音乐患者,博客里面可以不配图,但是不能不配音乐啊. 遂在博客里面引入了网易云模块,这里要感谢网易云的分享机制,对开发者非 ...

  2. 【NLP】干货!Python NLTK结合stanford NLP工具包进行文本处理

    干货!详述Python NLTK下如何使用stanford NLP工具包 作者:白宁超 2016年11月6日19:28:43 摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的 ...

  3. C++随笔:.NET CoreCLR之corleCLR核心探索之coreconsole(2)

    这篇文章是上篇的续集,本文将会继续介绍coreconsole.cpp里面的逻辑.也许大家会看一些CLR的书,我承认我没有看过,因为我觉得一个人,他再NB,那也是他自己的眼光,而且说句难听的,CLR也不 ...

  4. ABP创建数据库操作步骤

    1 ABP创建数据库操作步骤 1.1 SimpleTaskSystem.Web项目中的Web.config文件修改数据库配置. <add name="Default" pro ...

  5. T-SQL 拆分使用指定分隔符的字符串(split string)

    比如有一个表,我们需要些一个语句像SELECT OtherID, SplitData WHERE SomeID = 'abcdef-.......' , 然后就能返回分割成单独的行. 原表: | So ...

  6. 第10章 Shell编程(4)_流程控制

    5. 流程控制 5.1 if语句 (1)格式: 格式1 格式2 多分支if if [ 条件判断式 ];then #程序 else #程序 fi if [ 条件判断式 ] then #程序 else # ...

  7. 如何在Open Live Writer(OLW)中使用precode代码高亮Syntax Highlighter

    早先Microsotf的Windows Live Writer(WLW)现在已经开源了,并且更名为Open Live Writer,但是现在Windows Live Writer还是可以现在,Open ...

  8. mono for android学习过程系列教程(2)

    接着上一讲继续开始写,今天介绍的是安卓的基本组成结构. 在大多数情况下,MONO FOR ANDROID的命名空间和Android的命名空间 是互相映射的.有时候需要大小写,非字母数字字符的用法以及名 ...

  9. JavaScript多线程之HTML5 Web Worker

    在博主的前些文章Promise的前世今生和妙用技巧和JavaScript单线程和浏览器事件循环简述中都曾提到了HTML5 Web Worker这一个概念.在JavaScript单线程和浏览器事件循环简 ...

  10. DOM对象模型接口规范中的四个基本接口

    DOM对象模型的四个基本接口 在DOM对象模型接口规范中,有四个基本的接口:Document,Node,NodeList以及NamedNodeMap.在这四个基本接口中,Document接口是对文档进 ...