日期:2013-11-22  浏览次数:20941 次

网页制造aiyiweb文章简介:谈到CSS中的Margin,不得不知道的内容.

你真的了解margin吗?你知道margin有什么特性吗?你知道什么是垂直外边距合并?margin在块元素、内联元素中的区别?什么时候该用padding而不是margin?你知道负margin吗?你知道负margin在实际任务中的用途吗?常见的浏览器下margin出现的bug有哪些?……

写css,你少不了与margin打交道,而对于这个平时我们最常用的css属性我们并非十分了解。介于此我打算写下这篇文章,一来是本人任务中的总结,也是对本人知识的一次梳理。


Margin是什么

CSS 边距属性定义元素四周的空间。通过使用单独的属性,可以对上、右、下、左的外边距进行设置。也可以使用简写的外边距属性同时改变所有的外边距。——W3School
边界,元素四周生成额外的空白区。“空白区”通常是指其他元素不能出现且父元素背景可见的区域。——CSS权威指南


我比较喜欢使用“外边距”这个词来解释margin(同理padding可以称之为“内边距”,但是我又恰恰喜欢称呼padding为“补白”或者“留白”),我们可以很清楚的了解到margin的最基本用途就是控制元素四周空间的间隔,从视觉角度上达到互相隔开的目的。

Margin的特性
margin一直是通明的。

margin通过使用单独的属性,可以对上、右、下、左的外边距进行设置。即:margin-top、margin-right、margin-bottom、margin-left。

外边距的 margin-width 的值类型有:auto | length | percentage

也可以使用简写的外边距属性同时改变所有的外边距:margin: top right bottom left;(eg: margin:10px 20px 30px 40px) 记忆方式是元素四周正上方顺时针“上右下左”记忆。

并且规范还提供了省略的数值写法,基本如下:

1、如果margin只要一个值,表示上右下左的margin同为这个值。例如:margin:10px; 就等于 margin:10px 10px 10px 10px;

2、如果 margin 只要两个值,第一个值表示上下margin值,第二个值为左右margin的值。例如:margin:10px 20px; 就等于 margin:10px 20px 10px 20px;


3、如果margin有三个值,第一个值表示上margin值,第二个值表示左右margin的值,第三个值表示下margin的值。例如:margin:10px 20px 30px; 就等于 margin:10px 20px 30px 20px;

4、如果margin有四个值,那这四个值分别对应上右下左这四个margin值。例如:margin:10px 20px 30px 40px;

在实际使用中,团体不推荐使用三个值的margin,一是容易记错,二是不容易日后修正,一开始如果写成margin:10px 20px 30px;日后需求改动为上10px,右30px,下30px,左20px,你不得不还是得把这个margin拆开为margin:10px 30px 30px 20px;费力且不讨好,不如一开始就老老实实的写成margin:10px 20px 30px 20px;来的实在,不要为了如今节省俩个字节而让日后再次开发的成本上升。

垂直外边距合并问题

别被上面这个名词给吓倒了,简单地说,外边距合并指的是,当两个垂直外边距相遇时,它们将构成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。你可以查看CSS外边距合并了解这个基本知识。

实际任务中,垂直外边距合并问题常见于第一个子元素的margin-top会顶开父元素与父元素相邻元素的间距,而且只在标准浏览器下(FirfFox、Chrome、Opera、Sarfi)产生问题,IE下反而表现良好。例子可以查看下面代码(IE下表现“正常”,标准浏览器下查看出现“bug”):

<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加个上边框,这么一加反而画蛇添足,为当前修正留下隐患。
为什么一定要用border-top,padd