元素盒模型

margin 在中文中我们翻译成外边距或者外补白(本文中引用外边距)。他是元素盒模型(box model)的基础属性。

一、margin的基本特性

margin 属性包括 margin-top, margin-right, margin-bottom, margin-left, margin,可以用来设置 box 的 margin area。属性 margin 可以用来同时设置 box 的四边外边距,而其他的 margin 属性只能设置其自各的外边距。

margin 属性可以应用于几乎所有的元素,除了表格显示类型(不包括 table-caption, table and inline-table)的元素,而且垂直外边距对非置换内联元素(non-replaced inline element)不起作用。

或许有朋友对非置换元素(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-width 的值类型有:auto | length | percentage

percentage:百分比是由被应用 box 的containing block(注:一个元素的 containing block 是该元素产生的 box(es)在计算位置和大小时参考的一个矩形)的大小所决定。对于 margin-top 和 margin-bottom 也同样成立。

margin 的默认值为 0,并且 margin 支持负值。

上面我们曾提到属性 margin 可以用来同时指定 box 的四边外边距。如果属性 margin 有四个值,那么值将按照上-右-下-左的顺序作用于四边,即从元素的上边开始,按照顺时针的顺序围绕元素。表达式如下:

margin:top right bottom left;

四个数值中间以空格分隔。效果等同于:

margin-top:value;
margin-right:value;
margin-bottom:value;
margin-left:value;

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

  1. 如果没有 left 值,则使用 right 代替;
  2. 如果没有 bottom 值,则使用 top 代替;
  3. 如果没有 right 值,则使用 top 值代替。

根据这些基本原则,我们可以有三种省略方式,但不管怎样省略 margin 的数值都会大于等于一个,而 margin 的默认数值是从 top 开始至 left 结束,那么对于省略的具体情况,我们可以从 left 反推理回去。

1、如果 margin 只有三个值,按照值的顺序为 margin:top right bottom; 缺少了 left,根据原则,则 left 的值有 right 来代替。margin:10px 20px 30px; 就等于 margin:10px 20px 30px 20px;

2、如果 margin 只有两个值,按照值的顺序为 margin:top right; 缺少了 bottom 和 left,根据原则 left 的值由 right 来代替,bottm 的值由 top 来代替。margin:10px 20px; 就等于 margin:10px 20px 10px 20px;

3、如果 margin 只有一个值,按照值的顺序为 margin:top; 缺少了 bottom、left 和 right,根据原则 left 的值由 right 来代替,bottom 的值由 top 来代替,right 的值右 top 来代替,也就是说 left 的值也由 top 来代替。margin:10px; 就等于 margin:10px 10px 10px 10px;

三、margin的解析逻辑

目前我们已经了解到了 margin 的基本特性和基本写法,但对元素 margin 的基本解析逻辑还是很模糊,到底 margin 的 top、right、bottom、left 都是以什么为基准来促使 box model 形成。为了形象,易懂的对 margin 的逻辑进行说明,下面讲解的过程中,将引入 W3C 上没有的参考线的说法。何谓参考线?参考线就是 margin 移动的基准点,此基准点相对于 box 是静止的。而 margin 的数值,就是 box 相对于参考线的位移量。

在 margin 中 top、right、bottom、left 的参考线并不一致为一类,而是分为了两类参考线,top 和 left 的参考线属于一类,right 和bottom 的参考线属于另一类。那他们到底各以什么为参考线呢?top 以 containing block 的 content 上边或者垂直上方相连元素 margin 的下边为参考线垂直向下位移;left 以 containing block 的 content 左边或者水平左方相连元素 margin 的右边为参考线水平向右位移。right 以元素本身的 border 右边为参考线水平向右位移;bottom 以元素本身的border 下边为参考线垂直向下位移。从上我们可以看到 top 和 left 都是以外元素为参考,而 right 和 bottom 以本元素为参考。上面的位移方向是指 margin 数值为正值时候的情形,如果是负值则位移方向相反。

margin的移动示例图

或许理论听起来比较枯燥,我们举例说明一下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
div {
	width:200px;
	height:200px;
	background:#ccc;
}
</style>
</head>    

<body>
	<div>外边距的margin-width的值类型有:auto | length | percentage</div>
</body>
</html>

如上代码,很简单,为了方便我们看到效果,我们给 div 设置了宽度和高度以及背景色。

现在我们给 div 的样式加上 margin 属性,比如:

margin:-10px 20px -30px 40px;

这时候 margin 的解析逻辑是怎样的呢?首先我们要搞清 div 的和周边元素的关系,div 没有相连元素,而此时 div 的 containing block 是 body 产生的 block box。则根据上面介绍的参考线原理,div 的左外边距以 containing block 的 content 左边为参考线,及此时以 body 的 content 左边为参考线进行水平向右位移,位移的大小为 40px,同理,上边距以 body 的 content 上边为参考线进行垂直向上位移 10px(负值和正值的方向相反),下边距依照现在 div 的 borer 下边(此时的 div 已经经过上边距位移过了)垂直向上位移 30px(此时,margin 不会改变 box 的 border 内的物理大小,但会改变 box 的逻辑大小,即:以此 box 的 margin 的下边为参考的元素,不是从 box 的物理位置开始的,而是从逻辑位置开始),右边距依照现在 div 的 borer 右边(此时的 div 已经经过左边距位移过了)水平向右位移 20px。或许有朋友问你分析的顺序怎么和 margin 表达式中出现的顺序不一样?如果按照 margin 表达式中出现的顺序来分析,结果是一样的,只是为了更好的方便大家的理解而没有按照表达式的顺序来分析。

margin的详解

用 margin 最后的实际显示大小的到底是怎么样呢,或许有朋友也比较疑惑,我暂时用逻辑大小和物理大小来区分(其实上面已用到此概念),到底什么是逻辑大小,什么是物理大小呢?!具体可以看图,物理大小指的是除去 margin,也就是包含 border 以内的 box 大小,而逻辑大小,则是 box 通过 margin 解析规则解析后得到的大小(这或许可以解释为什么IE5会错误解析盒模型)。在上图中,box 的实际显示的宽度等于 box 的逻辑大小,而 box 实际显示的高度等于 box 的物理大小,这说明 box 实际显示的大小可能是 box 的逻辑大小,也可能是 box的 物理大小,规则到底是怎样的——

box 的实际大小 = box 的物理大小 + 正的 margin

这仅对元素本身有效,对于其后面的相关元素,他们则只以 margin 的逻辑大小为准则,进行布局。

有朋友反应,听得很迷糊,越看越不懂,如果你对具体的理解过程不感兴趣的话,那记住下面我总结的结论就可以了,XD

结论:

box 最后的显示大小等于 box 的 border 及 border 内的大小加上正的 margin 值。而负的 margin 值不会影响 box 的实际大小,如果是负的 top 或 left 值会引起 box 的向上或向左位置移动,如果是 bottom 或 right 只会影响下面 box 的显示的参考线。



共有48 条评论

  1. 1. 头像 翅膀

    好详细….谢谢

  2. 2. 头像 大猫

    偶特地找个女友名字叫ma jin的,就是因为CSS里margin很好玩

  3. 3. 头像 ivanling

    总结的很好,以前只知道用,现在终于有了理论基础了,用起来也理直气壮,谢谢

  4. 4. 头像 加减乘除888

    比CSS权威指南更进一步的讲解,让我更深入的了解了CSS的盒模型,谢谢!

  5. 5. 头像 加减乘除888

    根据文中对box的讲解,对于overflow属性,如果设置overflow=”auto”,我理解是不是应该解释为当元素的物理大小超出父元素的右侧、下侧时就出现滚动条,如下面的代码:
    [code]

    css

    /* */

    css

    css

    [/code]
    我将p元素与其父元素div的宽度与高度都设为200px,且为p元素设置右边界、下边界为50px,虽然p元素的逻辑大小比其父元素大,但其物理大小还是与其父元素一样,所以其父元素div没有出现滚动条。而后我再将p元素width和height设为200px,右边界和下边界设为-50px,父元素的width和height设为170px,虽然p元素的逻辑大小比其父元素小,但物理大小还是比其父元素大,所以其父元素div出现了滚动条。我在firefox、opera、safari中测试后的确是这样,但在IE中有问题。

  6. 6. 头像 加减乘除888

    #div1 {
    width:200px;
    height:200px;
    }
    #p1 {
    width:200px;
    height:200px;
    margin:0 50px 50px 0;
    background:green;
    }
    #div2 {
    width:170px;
    height:170px;
    overflow:auto;
    }
    #p2 {
    width:200px;
    height:200px;
    margin:0 -50px -50px 0;
    background:green;
    }

    css

    css

  7. 7. 麦鸡的博客 » 你真的认识margin么

    [...] (注:本文图片,定义直接copy译飞的由浅入深漫谈margin属性) [...]

  8. 8. 头像 加减乘除888

    你好,怿飞,我看了这篇文章后对CSS框模型有了一点疑惑,希望你能为我解答:)
    根据CSS的定义,元素框的大小是由元素的margin、border、padding、width、height决定,但根据你的对margin的解释,我是否应该理解,如果将margin-top值设为负值,那这个值就不会改变元素框的大小,只是将元素框向上拉动?

  9. 9. 头像 Sunxc

    我的博客导航栏 编程开发 那里有个2级菜单 可是鼠标点不到
    我看了下样式 是导航下面的内容部分的样式有个
    margin:10px auto 10px;
    我把10px弄大就可以了 不知道是为什么啊

    http://www.qbencao.com 博客地址 请求援助啊

  10. 10. 头像 asp.cms

    margin属性 写得非常透彻呀,以前有些迷惑的地方

  11. 11. margin详细解释 | 渡客地带

    [...] 摘自:http://www.planabc.net/2007/03/18/css_attribute_margin/ [...]

  12. 12. 头像 textbox

    讲的很细致,但还有一个问题没有涉及到。
    margin 负边距用百分比算 W3Cschool上如果说“ 规定基于父元素的宽度的百分比的外边距。” 在FF,ie7,ie8下正常。

    在IE6下是基于那个父亲呢?ie6真变态 ,如果 100%它又正常了。只要小于百分之百就不知道到底父亲是那一个了。希望楼主给于解答。。。。。。

  13. 13. 头像 textbox

    附上调试代码,希望楼主出山解决问题。我是百思不得其解

    fghfghfgh

    这个是负边距的

  14. 14. 小强ORG - 这家伙很懒,什么都没留下

    [...] margin值的解析规则是margin-left和margin-top的参考线为左边元素/上面元素的参考线,如果没有兄弟元素,就是以父元素的左内侧和上内侧为参考线(内侧即盒模型的content外侧)而margin-right和margin-bottom的参考线为元素本身的border右侧和border下侧为参考线。margin为正值会影响整个盒模型的大小即border以内的盒模型大小+margin值,如果margin为负值,则根据参考线向参考线外面位移。更详细的讲解请看由浅入深漫谈margin属性 [...]

  15. 15. 头像 FX

    十分感谢,逻辑大小这个词汇解释了我心中不少的疑惑。尤其是页面中用到的负边距技术就很好理解了

  16. 16. 头像 海玉

    这里的margin参考线说法感觉很奇特,实际效果也很好。以后可以大量使用负边距来代替position:absolute的移位问题。

  17. 17. 不要告诉我你懂margin

    [...] 在margin所有的实际应用中,负margin技术是我学习css路上最重要一课之一,许多高级应用和页面上的疑难杂症都可以用负margin技术来实现。margin技术是那么的有用,限于篇幅我又不想草草了事,所以我决定专门为他写一篇文章,详细的说明他的效果、原理、及其应用。在此之前你可以先阅读怿飞写的由浅入深漫谈margin属性这篇文章,大致了解“margin参考线”的概念,之后再来查看负margin技术及其应用这篇文章。 [...]

  18. 18. 浅析CSS margin属性 « whoscats

    [...] 看了怿飞的《由浅入深漫谈margin属性》,不管新手还是老手,多多少少能够了解一些,只不过对于新手来说,可能有些看得不太明白。主要是其没有给出box的相邻元素,因此设置margin-right和margin-bottom时很难看出会有什么变化。 [...]

  19. 19. 头像 super

    文中“如果是 bottom 或 right 只会影响下面 box 的显示的参考线”,这句话我觉得right的部分说的有问题,某些实例说明设个负值也会影响对象本身

  20. 20. あなたは分かりmargin抱いてセニョリータだった | テクニカルブログ

    [...] すべてはmarginの実用化の中で、敗margin技術は、私が勉强してcss途中の最も重要な一課の一つで、多くの高級アプリケーションや画面上の難病を身につけることも敗margin技术です。margin技術はそんなにの有用に限り、私はまた際限の分量でたくない、だから私は彼のために书いて別途の文章、詳しい説明が彼の効果、原理、そしてその応用します。。これに先立って、先に読んで飞ぶ怿书かれているというまんだん由浅入深margin属性ではないこの文章、はみな「marginガイドライン」の概念に親しくなってからを参照されたい敗margin技術とその応用しますこの文章だ。 [...]

  21. 21. Don’t tell me you know to bid

    [...] the details of his effect, principle, and its application.Before that you can read the Yi fly writeThrough discussing the attribute to bidThis article, general idea "to bid to a reference line" concept, then to viewNegative to [...]

  22. 22. [转]不要告诉我你懂margin(有点嚣张的标题) « Ronnie 猫's 一亩三分地

    [...] 在margin所有的实际应用中,负margin技术是我学习css路上最重要一课之一,许多高级应用和页面上的疑难杂症都可以用负margin技 术来实现。margin技术是那么的有用,限于篇幅我又不想草草了事,所以我决定专门为他写一篇文章,详细的说明他的效果、原理、及其应用。在此之前你可 以先阅读怿飞写的由浅入深漫谈margin属性这篇文章,大致了解“margin参考线”的概念,之后再来查看负margin技术及其应用这篇文章。 [...]

  23. 23. 几篇关于margin的文章 | 前端代码

    [...] 关于负margin的详细解释:http://www.planabc.net/2007/03/18/css_attribute_margin/ [...]

  24. 24. CSS属性之margin总结篇 | 云设计

    [...] 在margin所有的实际应用中,负margin技术是我学习css路上最重要一课之一,许多高级应用和页面上的疑难杂症都可以用负margin技术来实现。margin技术是那么的有用,限于篇幅我又不想草草了事,所以我决定专门为他写一篇文章,详细的说明他的效果、原理、及其应用。在此之前你可以先阅读怿飞写的由浅入深漫谈margin属性这篇文章,大致了解“margin参考线”的概念,之后再来查看负margin技术及其应用这篇文章。 [...]

  25. 25. CSS:你真的懂margin吗?

    [...] 在margin所有的实际应用中,负margin技术是我学习css路上最重要一课之一,许多高级应用和页面上的疑难杂症都可以用负margin技术来实现。margin技术是那么的有用,限于篇幅我又不想草草了事,所以我决定专门为他写一篇文章,详细的说明他的效果、原理、及其应用。在此之前你可以先阅读怿飞写的由浅入深漫谈margin属性这篇文章,大致了解“margin参考线”的概念,之后再来查看负margin技术及其应用这篇文章。 [...]

  26. 26. 我的网页收藏夹 – 小前端 | 记录心得的地方.

    [...] 由浅入深漫谈margin属性 [...]

  27. 27. 小前端的收藏夹[强力推荐] | 小前端 | 前端开发新人一枚

    [...] 由浅入深漫谈margin属性 [...]

  28. 28. 我知道你不知道的负Margin

    [...] 这里梳理一下规律,当margin四个值都为正数值的话,那么margin按照正常逻辑同周围元素产生边距。当元素margin的top和left是负值时会引起元素的向上或向左位置移动。而当元素margin的bottom和right是负值时会影响右边和下边相邻元素的参考线。如果你再想深入了解参考线理论的话你也可访问由浅入深漫谈margin属性这篇文章。 [...]

  29. 29. 不要告诉我你懂margin | 海风如歌

    [...] 在margin所有的实际应用中,负margin技术是我学习css路上最重要一课之一,许多高级应用和页面上的疑难杂症都可以用负margin技术来实现。margin技术是那么的有用,限于篇幅我又不想草草了事,所以我决定专门为他写一篇文章,详细的说明他的效果、原理、及其应用。在此之前你可以先阅读怿飞写的由浅入深漫谈margin属性这篇文章,大致了解“margin参考线”的概念,之后再来查看负margin技术及其应用这篇文章。 [...]

  30. 30. 头像 XiaoXiong

    求指教,当一个元素同时是浮动,并且设定了负的margin值时,这时候好像和文中提到的参考线一说不是很符合。例子:

    当给divTwoChildTwo设置float:right和margin-right:-20px时,divTwoChildTwo会超过divTwo。请问当浮动和负的margin相遇时是怎样处理的,我写了一些demo,但不是很理解,麻烦讲解一番,谢谢。

  31. 31. 不要告诉我你懂margin(转载自海玉的博客) | 前端薇薇

    [...] 在margin所有的实际应用中,负margin技术是我学习css路上最重要一课之一,许多高级应用和页面上的疑难杂症都可以用负margin技术来实现。margin技术是那么的有用,限于篇幅我又不想草草了事,所以我决定专门为他写一篇文章,详细的说明他的效果、原理、及其应用。在此之前你可以先阅读怿飞写的由浅入深漫谈margin属性这篇文章,大致了解“margin参考线”的概念,之后再来查看负margin技术及其应用这篇文章。 [...]

  32. 32. 头像 丁小倪

    如果是负的 top 或 left 值会引起 box 的向上或向左位置移动,如果是 bottom 或 right 只会影响下面 box 的显示的参考线。

    这里需要加一个前提,是在兄弟元素的关系时,试想如果是margin-right和包含块的右侧content相邻时?
    见DEMO http://jsfiddle.net/liang139163/zVGEy/
    所以right和bottom并不能忽略包含块的情况。

  33. 33. Negative margin - Smallni's blog

    [...] 下面引入margin的“参考线”的概念,margin的“参考线”W3C中没有严格的规范,但通过我们的实战可以很轻易的总结出一些规律,怿飞的总结,怿飞也对margin做了详细的探究(但有部分观点本人不作认同): [...]

  34. 34. 使用负值margin

    [...] [7]: http://www.planabc.net/2007/03/18/css_attribute_margin/ ”由浅入深漫谈margin属性” [...]

  35. 35. 负Margin理论 « 优设花园

    [...] 这里梳理一下规律,当margin四个值都为正数值的话,那么margin按照正常逻辑同周围元素产生边距。当元素margin的top和left是负值时会引起元素的向上或向左位置移动。而当元素margin的bottom和right是负值时会影响右边和下边相邻元素的参考线。如果你再想深入了解参考线理论的话你也可访问由浅入深漫谈margin属性这篇文章。 [...]

  36. 36. 转载:由浅入深漫谈margin属性 | Yuan Peng`s Tech Blog

    [...] http://www.planabc.net/2007/03/18/css_attribute_margin/ [...]

  37. 37. 不要告诉我你懂margin

    [...] 在margin所有的实际应用中,负margin技术是我学习css路上最重要一课之一,许多高级应用和页面上的疑难杂症都可以用负margin技术来实现。margin技术是那么的有用,限于篇幅我又不想草草了事,所以我决定专门为他写一篇文章,详细的说明他的效果、原理、及其应用。在此之前你可以先阅读怿飞写的由浅入深漫谈margin属性这篇文章,大致了解“margin参考线”的概念,之后再来查看负margin技术及其应用这篇文章。 CSS 学习笔记 [...]

  38. 38. 双飞翼布局 | HUSTecho

    [...] 效果如下图: 就到这里为止么?No,No,No,对于新手来说,理解双飞翼布局的难点,是在negative margin上,比如说上面用的是float:left;结合margin-left,你做测试的时候也许想,我换个方向来试试,用float:right;结合margin-right,这时候你就会发现出问题了,不能达到你想要的效果,why?这时候你就需要更详细的了解margin的解析机制了。因为margin的left和top是相对于自身而言,而right和bottom则是相对于靠着它的下一个元素而言的。还是不能理解,那看看这篇文章,怿飞前辈的由浅入深漫谈margin,相信看完你就可以完全理解了。另外关于玉伯前辈双飞翼布局的详细介绍看这里 本条目发布于 2013 年 3 月 30 日。属于 Css 分类,被贴了 css、float、lifesinger、双飞翼布局、淘宝UED、玉伯、负margin 标签。作者是 HUSTecho。 [...]

  39. 39. 【转】负margin的用法。 | 蜗牛说

    [...] 由浅入深漫谈margin属性 [...]

  40. 40. margin移动的基准点?? - 开发者问答

    [...] http://www.planabc.net/2007/03/18/css_attribute_margin/ [...]

  41. 41. 负margin用法权威指南 « 前端开发

    [...] 由浅入深漫谈margin属性 [...]

  42. 42. 当为 div 同时设置了浮动和负的 margin 的表现是怎样的(浮动的方向和 margin 方向相同或者相反)?负 margin 中提到的参考线一说会怎样表现? - web前端开发 - 开发者问答

    [...] 回答:谢邀,关于这个问题直接推荐圆心的《由浅入深漫谈margin属性 》http://www.planabc.net/2007/03/18/css_attribute_margin/ [...]

  43. 43. margin为负时的定位。。 - web前端 - 开发者问答

    [...] 回复: 对于margin负值可详细阅读:http://www.planabc.net/2007/03/18/css_attribute_margin/ 回复: LZ..你的这类问题我以前也经常问.. [...]

  44. 44. 负margin | 大冒险家的博客 | 大冒险家的博客

    [...] 参考文章 margin的解析逻辑 [...]

  45. 45. 负margin的应用 | arayzou

    [...] 这里梳理一下规律,当margin四个值都为正数值的话,那么margin按照正常逻辑同周围元素产生边距。当元素margin的top和left是负值时会引起元素的向上或向左位置移动。而当元素margin的bottom和right是负值时会影响右边和下边相邻元素的参考线。如果你再想深入了解参考线理论的话你也可访问由浅入深漫谈margin属性这篇文章。 [...]

  46. 46. » 不要告诉我你懂margin

    [...] 在margin所有的实际应用中,负margin技术是我学习css路上最重要一课之一,许多高级应用和页面上的疑难杂症都可以用负margin技术来实现。margin技术是那么的有用,限于篇幅我又不想草草了事,所以我决定专门为他写一篇文章,详细的说明他的效果、原理、及其应用。在此之前你可以先阅读怿飞写的由浅入深漫谈margin属性这篇文章,大致了解“margin参考线”的概念,之后再来查看负margin技术及其应用这篇文章。 [...]

  47. 47. 头像 小猪

    楼8 你可以参考css设计指南里面的盒模型的两条结论以后在看这边文章会更加理解

  48. 48. 实用的margin负值 - css - 布局 - 盒模型 - 嗅探实事

    [...] margin 在上、左方和下、右方解析逻辑有所不同。这里引用怿飞博客《由浅入深漫谈margin属性》 [...]

发表评论

(必填)

(必填,会为您保密)

评论仅支持“a、abbr、strong、em、blockquote、code”几个简单的标签