今天研究了一下css中的margin,发现其中大有学问。margin存在边距合并的问题,而且在内联元素和块级元素中边距合并规则不同;什么时候该用padding、什么时候该用margin要区分开;负margin的用途多多。
一、margin的用途:margin的基本用途就是控制元素与周围其他元素的间隔。
二、margin的用法: margin通过使用单独的属性,可以对上、右、下、左的外边距进行设置。即:margin-top、margin-right、margin-bottom、margin-left;也可以使用简写的外边距属性同时改变所有的外边距:margin: top right bottom left;
三、margin的取值:margin的值类型有:auto | length | percentage,
根据css1 中所述:所谓可替换元素就是浏览器根据元素的标签和属性,来决定元素的具体显示内容。例如浏览器会根据<img>标签的src属性的值来读取图片信息并显示出来,而如果查看(x)html代码,则看不到图片的实际内容;又例如根据<input>标签的type属性来决定是显示输入框,还是单选按钮等。html中的<img>、<input>、<textarea>、<select>、<object>都是替换元素。而现在,这个概念已经发生了变化,在新的规范中,html5涉及到的<video>、<canvas>、<menu>元素也被认为是替换元素。因此可以把“替换”理解为“嵌入”,替换元素就可以理解为需要一些外部内容来嵌入它的空间的元素。
而不可替换元素(non-replaced element)就是不需要外部内容来填充它的空间的元素。
1、如果设置为auto,需要分为以下几种情景:
(1)大部分元素的默认值为0,css2.1规范中提到的以下元素margin设置为auto‘的水平方向的‘margin-left‘或者‘margin-right‘对应的值为‘0‘;而竖直方向上的margin不会产生任何效果。
- 内联的不可替换元素(non-replaced inline element):既是内联元素,又是不可替换元素,如
span
,strong
,i
,b
,em、cite
- 内联的可替换元素:如:a
- 浮动的不可替换元素(block元素和inline元素)
- 浮动的可替换元素(block元素和inline元素)
- 常规流中的不可替换的inline-block元素
- 常规流中可替换的inline-block元素
(2)常规流中的块级不可替换元素、常规流中的块级可替换元素, 若 margin-left‘和‘margin-right‘都是‘auto‘,那么它们的应用值相等。这会让该元素相对于其包含块的边水平居中。
(3)最复杂的就是绝对定位的不可替换元素和绝对定位的可替换元素,有一个比较复杂的公式,这个公式是:
‘left‘ + ‘margin-left‘ + ‘border-left-width‘ + ‘padding-left‘ + ‘width‘ + ‘padding-right‘ + ‘border-right-width‘ + ‘margin-right‘ + ‘right‘ = 包含块的宽度。
首先先了解一下包含块的定义,在 CSS2.1 中,很多框的定位和尺寸的计算,都取决于一个矩形的边界,这个矩形,被称作是包含块( containing block )。 一般来说,(元素)生成的框会扮演它子孙元素包含块的角色;我们称之为:一个(元素的)框为它的子孙节点建造了包含块。包含块是一个相对的概念,每个框关于它的包含块都有一个位置,但是它不会被包含块限制;它可以溢出(包含块)。包含块上可以通过设置 ‘overflow’ 特性达到处理溢出的子孙元素的目的。
接下来来看margin的计算:
如果‘left‘,‘width‘和‘right‘全都是‘auto‘:则‘margin-left‘和‘margin-right‘的值为0;
如果‘left‘,‘width‘和‘right‘都不是‘auto‘:如果‘margin-left‘和‘margin-right‘都是‘auto,则他们的应用值相等,除非这会让它们为负;(根据这个规则可以使绝对定位的元素水平居中);如果包含块的direction是‘ltr‘ (‘rtl‘),把‘margin-left‘ (‘margin-right‘)设置为0,再求出‘margin-right‘ (‘margin-left‘)。如果‘margin-left‘或者‘margin-right‘有一个是‘auto‘,则根据上述公式求出另外一个margin的值。
除以上规则外,‘margin-left‘和‘margin-right‘值为0。
2、设置为length的话很好理解,就是实际设置的值,单位可以是px、em等长度值。另外margin值可以设置为负值。
3、percentage:百分比是由被应用 box 的包含块containing block的大小所决定。对于 margin-top 和 margin-bottom 也同样成立。
四、margin外边距合并
外边距合并指的是,当两个垂直外边距相遇时(有可能是同辈或者后辈),它们将形成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。如果有负的外边距,那么值就是用最大的负的外边距的跟最大的正的外边距的相加。如果没有正值外边距,那么就是绝对值的最大值.
发生合并的情况:正常流中,一个盒子如果没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边距合并。一个盒子下边距会跟他的下一个兄弟盒子的的上边距合并。
不发生外边距合并的情况:水平方向上永远不会发生外边距合并; 垂直方向上:一个浮动的盒子跟其他盒子外边距不会合并;overflow设置为hidden|scroll|auto的元素不会与它的子元素的外边距合并;绝对定位的元素不会与它的相邻元素或子元素发生边距合并、行内块级(inline-block)元素不会与相邻元素或子元素发生边距合并。
建议只需要记住发生合并的情况就行了。发生外边距合并以后产生的影响盒子的显示大小= border +content+padding+正margin 值。负的 margin 值不会影响 box 的实际大小,但是负的 top 或 left 值会引起 box 的向上或向左位置移动,如果是 bottom 或 right 只会影响下面 box 的显示的参考线。
下面是给div元素设置margin:-10px 20px -30px 40px的例子;
如果还不清楚,可以参考网上几篇有关margin的文章:1、 你是否彻底了解margin属性 推荐
2、由浅入深漫谈margin属性 推荐
另外一篇文章介绍了负margin的几个用途,我知道你不知道的负margin
五、什么时候用margin,什么时候用padding
何时应当使用margin:需要在border外侧添加空白时。空白处不需要背景(色)时。上下相连的两个盒子之间的空白,需要相互抵消时。如15px + 20px的margin,将得到20px的空白。
何时应当时用padding:需要在border内测添加空白时。空白处需要背景(色)时。上下相连的两个盒子之间的空白,希望等于两者之和时。如15px + 20px的padding,将得到35px的空白。