margin是盒模型几个属性中一个很是特殊的属性。简单举几个例子:只有margin不显示当前元素背景,只有margin能够设置为负值,margin和宽高支持auto,以及margin具备很是奇怪的重叠特性。以前的博文中已经分别详细地介绍了margin的基础知识和负margin的详细用法。本文将详细介绍外边距margin的几个重点部分,包括重叠、auto和无效状况css
【前提】html
margin重叠又叫margin合并,发生这种状况有两个前提web
一、只发生在block元素上(不包括float、absolute、inline-block元素)django
二、只发生在垂直方向上(不考虑writing-mode)浏览器
【分类】markdown
margin重叠共包括如下3种状况布局
一、相邻的兄弟元素post
<style> p{ line-height: 2em; margin:1em 0; background-color: lightblue; display:inline-block; width: 100%; } </style> <p>兄弟一</p> <p>兄弟二</p>
二、父级元素和第一个或最后一个子元素,父子级的margin重叠又叫margin传递spa
<style> .box{ background-color: pink; height:30px; } .inner{ margin-top: 1em; background-color: lightblue; } </style> <div class="box"> <div class="inner">子级</div> </div>
条件设计
相对比相邻兄弟元素margin重叠来讲,父子级margin重叠须要知足如下几个条件(以margin-top重叠为例):
a、父元素不是BFC元素
b、父元素没有padding-top值
c、父元素没有border-top值
d、父元素和第一个子元素之间没有inline元素分隔
若是是父子级的margin-bottom重叠,第d条改成父元素和最后一个子元素之间没有inline元素分隔,以及还须要知足父元素没有height、min-height、max-height限制
三、空的block元素
<style> .box{ background-color: lightgreen; overflow: hidden; } .void{ margin: 1em 0; } </style> </head> <body> <div class="box"> <div class="void"></div> </div> 一行文字
从下面结果中,能够看出空block元素应该撑开父级margin-top+margin-bottom共2em的高度,但因为margin重叠,只有1em
一样地,空block元素发生margin重叠也须要知足一些条件
a、元素没有border值
b、元素没有padding值
c、里面没有inline元素
d、没有height或min-height
【规则】
两个正垂直外边距,浏览器取大值;若是垂直外边距都设置为负值,浏览器会选取两个外边距的绝对值的最大值;若是一个正外边距与一个负外边距合并,会从正外边距减去这个负外边距的绝对值
简单点说,就是正正取大值、正负值相加、负负最负值
【用途】
在网页布局中,由于margin重叠的缘由,咱们经常把margin做为一个“问题样式”而尽可能少地使用它。但实际上,它是在很大的做用的
HTML文档建立的初衷只是用来展现信息的。HTML文档只使用默认样式的前提下,若是上下margin不发生重叠,则会出现如下几个问题:一、连续段落或列表之类,若是没有margin重叠,首尾项间距会和其余兄弟元素呈现1:2的关系,排版不天然;二、web中任何地方嵌套或直接放入任何裸div,都会影响原生的布局,与web设计原则相违背;三、遗落的空的任意多个p标签,会影响原来的阅读排版
因此,咱们要善用重叠,能够在列表项中同时使用margin-top和margin-bottom。这样,使页面结构更具备健壮性,最后一个元素移除或位置调换,都不会破坏原生的布局
【新属性】
-webkit-margin-collapse
-webkit-margin-collapse: <collapse>(默认重叠) | <discard>(取消) | <separate>(分隔)
该属性用于设置margin是否重叠,做用于发生margin重叠的两个元素之一。若是,两个都使用该属性,一个设置为discard,一个设置为separate,则最终效果为重叠collase
只有width/height和margin能够设置auto。关于auto的详细信息,已经在CSS视觉格式化中详细介绍过。下面仅介绍关于margin:auto的部分
【为何margin:auto没法实现垂直居中】
水平方向能够居中是由于块级元素的宽度默认是撑满父级元素的,若是给宽度设置一个固定值,而左右margin设置为auto,则能够平分剩余空间
垂直方向不能够居中是由于块级元素的高度默认是内容高度,与父级元素的高度并无直接的关系,而上下margin设置为auto,则被重置为0
【为何图片使用margin:auto不能水平居中】
图片没法水平居中,相似于块级元素没法垂直居中。由于图片的宽度width默认是自身宽度,与父元素的宽度没有直接关系。左右margin设置为auto,会被重置为0
因此,图片要水平居中,须要设置为display:block元素
【实现垂直居中】
使用margin:auto实现垂直居中,有如下两种方法
一、使用writing-mode:vertical-lr;
writing-mode表明页面流方向,默认是水平方向。改成垂直方向后,可实现垂直居中,但水平不居中了
二、将元素变为绝对定位元素(IE7-浏览器不支持)
将元素变为绝对定位元素后,设置top:0;bottom:0;,使绝对定位元素与定位父级的高度有了直接的联系。再设置margin:0 auto;,使margin-top和margin-bottom平分剩余空间,达到垂直居中的效果
一、行内元素垂直margin无效
由于行内元素垂直布局主要是经过行高line-height和垂直对齐vertical-align来影响的,垂直margin并不会影响它们,因此不会影响垂直布局。而在显示方式,margin区域不会显示元素背景,因此也不会影响自身元素的显示,因此行内元素垂直margin无效
[注意]不包括inline-block或设置writing-mode为vertical-lr的状况
二、某些表格类元素margin无效
<thead>``<tbody>``<tfoot>``<tr>``<col>``<colgroup>``<td>``<th>
不可设置margin。对于display属性来讲,display为table相关类型(不包括table-caption、table、inline-table),margin声明无效
三、绝对定位元素非定位方向的margin值看似无效
绝对定位的margin值是一直有效的,只是由于绝对定位元素是脱离文档流的,与其余元素节点没有什么关系,因此看不出效果
四、BFC形成的margin看似无效
左侧元素使用浮动,右侧元素使用overflow-hidden实现两栏自适应的布局时,右侧元素的margin-left值只有足够大,才能看到效果。这是由于margin-left是相对于父元素左侧,而不是图片右侧
五、内联特性致使的margin无效
一个div里面包着一张图片,当图片的margin-top小到必定值时,图片就再也不接着向上移动了。这是由于图片是内联元素,它受制于内联元素vertical-align对齐特性的影响。默认基线对齐。以页面假想的大写X字符为例,X是不会由于图片margin-top足够小而跑到父元素外面的,因此图片移动到必定位置就再也不接着向上移动了