平时很多问题,大多是知其然不知其所以然造成的。所以,明白了原理,在遇到问题就有了分析的思路。所以,我希望大家在遇到非标准的问题的时候,也就所谓的某些bug的时候,
多去探查一下,为什么会产生这种问题。解决的原理是什么,别解决了就算完了。现在的省事,会给你将来的成长埋下隐患。
而往往所谓的bug,是对规范,原理的理解不透彻造成的。
所以多问个为什么,虽尺有所短,但假以时日,必寸有所长。
本文主要涉及以下知识点点:
- 垂直外边距合并
- 什么时候用maigin,什么时候用padding
- 行内替换元素和费替换元素
- margin的基线
- 盒子的物理大小,显示大小,逻辑大小
- 浮动触发haslayout
了解了这些,就可以说margin我是懂点了。距离真正懂还差得远。下面是针对自己情况的一些笔记和总结。
具体详细的文档可参考 圆心、海玉的文章和w3c上的规范。
http://www.planabc.net/2007/03/18/css_attribute_margin/ 圆心
http://www.hicss.net/do-not-tell-me-you-understand-margin/ 海玉
http://www.w3cplus.com/css/the-definitive-guide-to-using-negative-margins.html 大漠老师网站
感谢前辈们的心血。
- margin下面,父元素的背景可以看到。可以说margin的地方是透明的
- 当一个元素位于另一个元素中,且这个父元素没有东西来和子元素隔开(父元素有border或者padding都可以隔开子元素),那父元素与子元素的上/下外边距也会合并。
- 只有普通文档流中块框的垂直外边距才会发生外边距合并。行内框、浮动框或绝对定位之间的外边距不会合并。
外边距合并只发生在垂直方向上,水平方向上是不会发生外边距合并的。 - 实际工作中,垂直外边距合并问题常见于第一个子元素的margin-top会顶开父元素与父元素相邻元素的间距,而且只在标准浏览器下(FirfFox、Chrome、Opera、Sarfi)产生问题,IE下反而表现良好。
像水一样,接触后融合。但大小是之前大的那个。 - 根据规范,一个盒子如果没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边距重叠。
注意,脱离文档流后不受影响。
再说了白点就是:父元素的第一个子元素的上边距margin-top如果碰不到有效的border或者padding.就会不断一层一层的找自己“领导”(父元素,祖先元素)的麻烦,把自己的margin当领导的margin执行
其中有类特殊的元素:如img|input|select|textarea|button|label等,他们被称为可置换元素(Replaced element)
- 他们区别一般inline元素(相对而言,称non-replaced element)是:这些元素拥有内在尺寸(intrinsic
dimensions),他们可以设置width/height属性。他们的性质同设置了display:inline-block的元素一致。
margin也能用于内联元素,这是规范所允许的,但是margin-top和margin-bottom对内联元素(对行)的高度没有影响,并且由于边界效果(margin效果)是透明的,他也没有任何的视觉影响。 - 给行内非替换元素设置上下margin是没用的。而且行内元素不会发生外边距合并。外边距合并只在垂直方向上。
注意 也会占个位置
行内替换元素,可以设置宽高,margin上下也会有效果。且不会在水平方向上有外边距合并,还是那句话,外边距合并只在垂直方向上。 - margin 属性可以应用于几乎所有的元素,除了表格显示类型(不包括 table-caption, table and inline-table)的元素,而且垂直外边距对非置换内联元素(non-replaced inline element)不起作用。
置换元素(replaced element)主要是指 img, input,
textarea, select, object 等这类默认就有 CSS 格式化外表范围的元素。 - 何谓参考线?参考线就是 margin 移动的基准点,此基准点相对于 box 是静止的。而 margin 的数值,就是 box 相对于参考线的位移量。
从上我们可以看到 top 和 left 都是以外元素为参考,而 right 和 bottom 以本元素为参考。上面的位移方向是指 margin 数值为正值时候的情形,如果是负值则位移方向相反。
box 的实际大小 = box 的物理大小 + 正的 margin
这仅对元素本身有效,对于其后面的相关元素,他们则只以 margin 的逻辑大小为准则,进行布局。
结论:
box
最后的显示大小等于 box 的 border 及 border 内的大小加上正的 margin 值。而负的 margin 值不会影响 box 的实际大小,如果是负的 top 或 left 值会引起 box 的向上或向左位置移动,如果是 负的bottom
或 right 只会影响下面 box 的显示的参考线。
实际的逻辑大小,是按照边边来算的。
- 基线,逻辑大小,物理大小,显示大小。
基线是margin的关键。逻辑大小改变后,下一个block基线位置就变了,最后的定位还是看基线位置。尤其是上面和左面。 - 行内元素,设置了浮动,就可以设置宽高了
float:left等浮动属性可以让inline元素haslayout,会让inline元素表现得跟inline-block元素的特性一样,支持高宽,垂直margin和padding等
IE6/7/8下auto margin居中bug:
发生场合:给block元素设置margin auto无法居中 解决方法:出现这种bug的原因通常是没有Doctype,然后触发了ie的quirks mode,加上Doctype声明就可以了。在《打败IE的葵花宝典》里给出的方法是给block元素添加一个width能够解决,但根据本人亲测,加with此种方法是无效的,如果没有Doctype即使给元素添加width也无法让block元素居中。
原理分析:缺少Doctype声明。
IE8下input[button | submit] 设置margin:auto无法居中
发生场合:ie8下,如果给像button这样的标签(如button input[type="button"] input[type="submit"])设置{ display: block; margin:0 auto; }如果不设置宽度的话无法居中。
解决方法:可以给为input加上宽度
原理分析:IE8浏览器Bug。IE8百分比padding垂直margin bug:
发生场合:当父元素设置了百分比的padding,子元素有垂直的margin的时候,就好像父元素被设置了margin一样。
解决方法:给父元素加一个overflow:hidden/auto。
原理分析:IE8浏览器Bug。