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. 【前端性能】高性能滚动 scroll 及页面渲染优化

    最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...

  2. 探索C#之6.0语法糖剖析

    阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...

  3. console的高级使用

    1.console.table()用来表格化展示数据. var people = { zqz: { name: 'zhaoqize', age: 'guess?' }, wdx: { name: 'w ...

  4. pt-pmp

    pt-pmp有两方面的作用:一是获取进程的堆栈信息,二是对这些堆栈信息进行汇总. 进程的堆栈信息是利用gdb获取的,所以在获取的过程中,会对mysql服务端的性能有一定的影响. 用官方的话说: Thi ...

  5. Mybatis XML配置

    Mybatis常用带有禁用缓存的XML配置 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...

  6. SharePoint 2013: A feature with ID has already been installed in this farm

    使用Visual Studio 2013创建一个可视web 部件,当右击项目选择"部署"时报错: "Error occurred in deployment step ' ...

  7. DevExpress第三方控件使用实例之ASPxPopupControl弹出子窗体

    弹出页面控件:ASPxPopupControl, <dxpc:ASPxPopupControl ID="popubCtr" runat="server" ...

  8. 烂泥:数据库管理之phpmyadmin免密码配置

    本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 其实这篇文章很早就想写了,但是一直没有时间.刚好今天下午稍微空了点,就把这篇文章整理出来 ...

  9. Spring mvc @initBinder 类型转化器的使用

    一.单日期格式 因为是用注解完完成的后台访问,所以必须在大配置中配置包扫描器: 1.applicactionContext.xml <?xml version="1.0" e ...

  10. 从Unity3D编译器升级聊起Mono

    接前篇Unity 5.3.5p8 C#编译器升级,本文侧重了解一些Mono的知识. Unity3D的编译器升级 新升级的Mono C#编译器(对应Mono 4.4) Unity编辑器及播放器所使用的M ...