写css,你少不了与margin打交道。你真的了解margin吗?你知道margin有什么特性吗?你知道什么是垂直外边距合并?margin在块元素、内联元素中的区别?何时该用padding而不是margin?你知道负margin吗?你知道负margin在实际工做中的用途吗?常见的浏览器下margin出现的bug有哪些?……css
CSS 边距属性定义元素周围的空间。经过使用单独的属性,能够对上、右、下、左的外边距进行设置。也可使用简写的外边距属性同时改变全部的外边距。——W3Schoolhtml
边界,元素周围生成额外的空白区。“空白区”一般是指其余元素不能出现且父元素背景可见的区域。——CSS权威指南html5
我比较喜欢使用“外边距”这个词来解释margin(同理padding能够称之为“内边距”,可是我又偏偏喜欢称呼padding为“补白”或者“留白”),咱们能够很清楚的了解到margin的最基本用途就是控制元素周围空间的间隔,从视觉角度上达到相互隔开的目的。浏览器
margin始终是透明的。margin经过使用单独的属性,能够对上、右、下、左的外边距进行设置。即:margin-top、margin-right、margin-bottom、margin-left。app
外边距的 margin-width 的值类型有:auto | length | percentage。也可使用简写的外边距属性同时改变全部的外边距:margin: top right bottom left;(eg: margin:10px 20px 30px 40px) 记忆方式是元素周围正上方顺时针“上右下左”记忆。ide
而且规范还提供了省略的数值写法,基本以下:布局
在实际应用中,我的不推荐使用三个值的margin,一是容易记错,二是不容易往后修改,一开始若是写成margin:10px 20px 30px;往后需求改动为上10px,右30px,下30px,左20px,你不得不仍是得把这个margin拆开为margin:10px 30px 30px 20px;费力且不讨好,不如一开始就老老实实的写成margin:10px 20px 30px 20px;来的实在,不要为了如今节省俩个字节而让往后再次开发的成本上升。性能
别被上面这个名词给吓倒了,简单地说,外边距合并指的是,当两个垂直外边距相遇时,它们将造成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。你能够查看W3Shool CSS外边距合并了解这个基本知识。学习
实际工做中,垂直外边距合并问题常见于第一个子元素的margin-top会顶开父元素与父元素相邻元素的间距,并且只在标准浏览器下(FirfFox、Chrome、Opera、Sarfi)产生问题,IE下反而表现良好。例子能够查看下面代码(IE下表现“正常”,标准浏览器下查看出现“bug”):ui
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>垂直外边距合并</title> <style> .top{width:160px; height:50px; background:#ccf;} .middle{width:160px; background:#cfc;} .middle .firstChild{margin-top:20px;} </style> </head> <body> <div class="top"></div> <div class="middle"> <div class="firstChild">我其实只是想和个人父元素隔开点距离。</div> <div class="secondChild"></div> </div> </body> </html>
若是按照CSS规范,IE的“良好表现”实际上是一个错误的表现,由于IE的hasLayout渲染致使了这个“表现良好”的外观。而其余标准浏览器则会表现出“有问题”的外观。好了,若是你读过了上面W3Shcool的CSS外边距合并的文章后,就很容易讨论这个问题了。这个问题发生的缘由是根据规范,一个盒子若是没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边距重叠。
再说了白点就是:父元素的第一个子元素的上边距margin-top若是碰不到有效的border或者padding.就会不断一层一层的找本身“领导”(父元素,祖先元素)的麻烦。只要给领导设置个有效的 border或者padding就能够有效的管制这个目无领导的margin防止它越级,假传圣旨,把本身的margin当领导的margin执行。
对于垂直外边距合并的解决方案上面已经解释了,为父元素例子中的middle元素增长一个border-top或者padding-top便可解决这个问题。
通常说来这个问题解释到这里,大多数文章就不会再深刻下去了,但做为一名实战开发者,最求的是知其然知其因此然,本来使用margin-top就是为了与父元素隔开距离,而按照你这么一个解法,实际上是一种“修复”,为了“弥补修复”这个父子垂直外边距合并这个CSS规范“Bug”,而强制在父元素上使用border-top和padding-top,不舒服,也不容易记住,下次再发生这样的状况仍是会忘记这条准则,并且在页面设计稿里若是不须要border-top加个上边框,这么一加反而多此一举,为之后修改留下隐患。
什么时候应当使用margin:须要在border外侧添加空白时。空白处不须要背景(色)时。上下相连的两个盒子之间的空白,须要相互抵消时。如15px + 20px的margin,将获得20px的空白。
什么时候应当时用padding:须要在border内测添加空白时。空白处须要背景(色)时。上下相连的两个盒子之间的空白,但愿等于二者之和时。如15px + 20px的padding,将获得35px的空白。
我的认为:margin是用来隔开元素与元素的间距;padding是用来隔开元素与内容的间隔。margin用于布局分开元素使元素与元素互不相干;padding用于元素与内容之间的间隔,让内容(文字)与(包裹)元素之间有一段“呼吸距离”。
HTML(这里说的是html标准,而不是xhtml)里分两种基本元素,即block和inline。顾名思义,block元素就是以”块”表现的元素(block-like elements),inline元素便是以”行”表现的元素(character level elements and text strings)。两者表现的主要差异在于,在页面文档中block元素另起一行开始,并独占一行。inline元素则同其余inline元素共处一行。
block元素(块元素)大体有:P|H1|H2|H3|H4|H5|H6|UL|OL|PRE| DL | DIV | NOSCRIPT | BLOCKQUOTE | FORM | HR | TABLE | FIELDSET | ADDRESS(随着html5标准的推动,一些元素将被废除,而一些新的元素将被引入)注意的是并不是全部的block元素的默认display属性都是block,像table这种display:table的元素也是block元素。
inline元素(内联元素)大体有:#PCDATA(即文本)| TT | I | B | BIG | SMALL|EM | STRONG | DFN | CODE |SAMP | KBD | VAR | CITE | ABBR | ACRONYM|A | IMG | OBJECT | BR | SCRIPT | MAP | Q | SUB | SUP | SPAN | BDO|INPUT | SELECT | TEXTAREA | LABEL | BUTTON
其中有类特殊的元素:如img|input|select|textarea|button|label等,他们被称为可置换元素(Replaced element)。他们区别通常inline元素(相对而言,称non-replaced element)是:这些元素拥有内在尺寸(intrinsic dimensions),他们能够设置width/height属性。他们的性质同设置了display:inline-block的元素一致。
或许有朋友对非置换元素(non-replaced element)有点疑惑,稍微帮助你们理解一下。非置换元素,W3C 中没有给出明确的定义,但咱们从字面能够理解到,非置换元素对应着置换元素(replaced element),也就是说咱们搞懂了置换元素的含义,就懂了非置换元素。置换元素,W3C中给出了定义:“An element that is outside the scope of the CSS formatter, such as an image, embedded document, or applet”
从定义中咱们能够理解到,置换元素(replaced element)主要是指 img, input, textarea, select, object 等这类默认就有 CSS 格式化外表范围的元素。进而可知,非置换元素(non-replaced element)就是除了 img, input, textarea, select, object 等置换元素之外的元素。
margin在块级元素下,他的性能能够彻底体现,上下左右任你设定。且记住块级元素的margin的参照基准是前一个元素即相对于自身以前的元素有margin距离。若是元素是第一个元素,则就是相对于父元素的margin距离(但第一个元素相对于父元素margin-top而父元素又没有设定padding-top/border-top的话要须要印证上面的垂直外边距合并的知识)
margin也能用于内联元素,这是规范所容许的,可是margin-top和margin-bottom对内联元素(对行)的高度没有影响,而且因为边界效果(margin效果)是透明的,他也没有任何的视觉影响。
这是由于边界应用于内联元素时不改变元素的行高度,若是你要改变内联元素的行高即相似文本的行间距,那么你只能使用这三个属性:line-height,fong-size,vertical-align。请记住,这个影响内联元素高度的是line-height而不是height,由于内联元素是一行行的,定一个height的话,那这究竟是整段inline元素的高呢?仍是inline元素一行的高呢?这都说不许,因此统一都给每行定一个高,只能是line-height了。
margin-top/margin-bottom对内联元素没有多大实际效果,不过margin-left/margin-right仍是可以对内联元素产生影响的。应用margin:10px 20px 30px 40px;,左边这个css若是写在inline元素上,他的效果大体是,上下无效果,左边离他相邻元素或者文本距离为40px,右边离他相邻元素或者文本距离为20px。你能够自行尝试一番。
最后在内联元素中还有上文咱们提到的非可置换inline元素(non-replaced element),这些个元素img|input|select|textarea|button|label虽然是内联元素,但margin依旧能够影响到他的上下左右!
总结下来margin 属性能够应用于几乎全部的元素,除了表格显示类型(不包括 table-caption, table and inline-table)的元素,并且垂直外边距对非置换内联元素(non-replaced inline element)不起做用。
在margin全部的实际应用中,负margin技术是我学习css路上最重要一课之一,许多高级应用和页面上的疑难杂症均可以用负margin技术来实现。margin技术是那么的有用,限于篇幅我又不想草草了事,因此我决定专门为他写一篇文章,详细的说明他的效果、原理、及其应用。在此以前你能够先阅读怿飞写的由浅入深漫谈margin属性这篇文章,大体了解“margin参考线”的概念,以后再来查看负margin技术及其应用这篇文章。
林林总总写了那么多,最后总结一些浏览器中常见的margin Bug吧,之后遇到margin下的布局问题能够查看这里找到解决的方案,若是你还发现其余关于浏览器下margin的Bug你能够发表留言,核对采纳后我会及时添加进去,感谢你的分享。
IE6中双边距Bug:
IE6中浮动元素3px间隔Bug:
IE6/7负margin隐藏Bug:
IE6/7下ul/ol标记消失bug:
IE6/7下margin与absolute元素重叠bug:
IE6/7/8下auto margin居中bug:
IE8下input[button | submit] 设置margin:auto没法居中
IE8百分比padding垂直margin bug: