PS:测试浏览器均为chrome。
首先说下负margin的影响。
正常html页面在显示时,默认是根据文档流的形式显示的。文档流横向显示时,会有一个元素横向排列的基准线,并且以最高元素的vertical-align设置为基准线,此元素的高度也为本行的高度。当横向空间不够,或者元素为block时,文档流会换行显示。
除去绝对定位、固定定位的元素,文档中的每一个元素在文档流中是占据一定空间的,此空间包括margin、border、padding、content。根据元素的display、line-height、text-align、vertical-align、float等属性,对元素进行排列布局。
如果对一个处于文档流中的元素设置了margin属性值,会改变紧接其后的元素在文档流的位置。
元素的margin为正值,会使此元素占据的文档流位置加大,同改变padding和content大小效果相似。
例
<div style="display:inline-block;width:100px;height:100px;border:1px solid black;margin-bottom:10px;vertical-align:bottom;"></div>
<div style="display:inline-block;width:100px;height:50px;border:1px solid black;"></div>
会发现第二个div同第一个div的下边缘对齐时,将第一个div的margin-bottom考虑进来了,距离第一个div的bottom正好向下移动了10px。
元素margin为负值,会使此元素本身占据的文档流空间减小,同时使出现的下一个元素占据的文档流位置,向上和向左移动,同文档流的方向正好相反。文档流换行显示时,会出现下行元素同上行元素重合的现象。而改变padding和content则无法达到此效果,因为padding和content最小为0。
<div style="display:inline-block;width:100px;height:100px;border:1px solid black;margin-bottom:-10px;vertical-align:bottom;"></div>
<div style="display:inline-block;width:100px;height:50px;border:1px solid black;"></div>
此时发现,第二个div的位置向上移动了,并且距离第一个div的bottom正好向上移动了10px。如果margin-left和margin-right为负值,会发现元素出现了重叠。
width值有四种:auto、length(px、em)、%、inherit。
auto,根据元素的显示方式(block,inline-block),一级父元素内部的content大小,自适应子元素的显示大小,此时子元素的auto宽度会包括margin的大小。
%,取父元素的content宽度,设置为此子元素的content加border的总宽度。如果此时子元素有padding、margin等属性值,会发现子元素可能会超出父元素的显示区域,与父元素之外的显示元素重叠。
如果子元素拥有box-sizing:border-box属性, 会取父元素的content宽度,设置为此子元素的content加padding加border的总宽度。有margin时,还是可能会与父元素以及父元素之外的元素重叠。
总结:无box-sizing:border-box时,百分比或者数值的width设置只影响元素content,有box-sizing:border-box时影响padding+content;margin不受影响,margin只会影响元素在文档流的位置和占据的空间,不参与元素大小的计算。width的百分比,参考的是父元素的content的width。此外所有和百分比相关的位置、大小设置,都是基于父元素的content。除了line-height~