一、标准盒模型和怪异模式盒模型
标准盒模型和怪异模式盒模型可以通过box-sizing来设置:
标准盒模型:box-sizing: content-box
怪异模式盒模型:box-sizing: border-box
两种模型的区别:标准模式会被设置的padding撑开,而怪异模式则相当于将盒子的大小固定好,再将内容装入盒子。盒子的大小并不会被padding所撑开。
1.标准盒模型:盒子总宽度 = width + padding + border + margin
2.怪异模式盒模型:盒子总宽度 = width + margin
二、margin百分比
假设我们有这样的一段HTML代码,外面一个DIV宽度980px,高度500px,里面有一个子元素DIV,宽度和高度都不设置,然后给他设置margin:10% 5%,这个属性相当于margin:10% 5% 10% 5%。
HTML代码:
<div class="demo1"> <div>这个div设置:margin:10% 5%</div> </div>
CSS代码:
.demo1{ height:500px; width:980px; margin:0 auto; background:#EEE; overflow:hidden;} .demo1 div{margin:10% 5%; background:#666;}
这里还出现了一个小的hack,就是demo1盒子不会紧挨着body,也就是不会定格布局,而且body元素上面还有一段空白,这段空白的高度刚好是.demo1 div元素的margin-top,demo1和.demo1 div元素都是顶格对其的,只要给demo1元素设置overflow:hidden,即可解决这个问题。
我们根据以往的理解,.demo1 div的margin应该是:50px 49px 50px 49px,但是运行以后,通过查看盒模型示意图,却发现是:98px 49px 98px 49px:
得出结论:
当margin设置成百分数的时候,其top right bottom left的值是参照父元素盒子的宽度进行计算,在w3c的规范中也是这样描述的: margin 的百分比值参照其包含块的宽度进行计算,同样的padding如果设置成百分数的话,其盒子模型和margin是一样的。
这只发生在默认的 writing-mode: horizontal-tb;
和 direction: ltr;
的情况下,当书写模式变成纵向的时候,其参照将会变成包含块的高度。
三、关于img的margin设置问题
margin-top 和 margin-bottom 值对行内非替换元素(non-replaced inline element)是无效的。因此我们可以指定 img 元素的 margin-top 和 margin-bottom,而非替换行内元素(如 i,span 等)设置 margin-top 和 margin-bottom 却不会产生效果。
四、margin--在同级元素(非父子关系)之间应用
(1)水平方向的外边距合并
两个水平方向的盒子相遇,那么最终两者之间的距离为左边盒子的右外边距和右边盒子的做外边距之和。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>水平方向的两个盒子</title>
<style>
*{
margin:0;
padding:0;
border:0;
}
body{
font-size: 0;
}
.left{
width: 100px;
height: 100px;
background: red;
display: inline-block;
margin-right: 50px;
font-size: 20px;
}
.right{
width: 100px;
height: 100px;
background: yellow;
display: inline-block;
margin-left: 50px;
font-size: 20px;
}
</style>
</head>
<body>
<div class="left">宽为100px,右边距为50px</div>
<div class="right">宽为100px,左边距为50px</div>
</body>
</html>
效果图:
补充说明:
大家可以看到,为了使得两个div(块状元素)脱离正常的文档流我使用了display:inline-block;属性,另外,我还把body的font-size设置为0,这样可以解决inline-block自身的问题,否则两个div的举例会大于100px。当然使用float也可以使得两个div出现在同一行中。
如果使用
display: inline-block;
,则会出现一个bug,例如li
、a
把设置成display: inline-block;
,然后把padding和margin都设置为0还是会出现空隙,如:
此时有两种方法设置间距为0:
1.将设置display: inline-block;
的元素写在一行。
2.将父元素设置为font-size: 0
。
(2)竖直方向的外边距合并
两个竖直方向的盒子相遇时,其竖直方向的距离等于上方盒子的下外边距和下方盒子的上外边距中较大的一个。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>水平方向的两个盒子</title>
<style>
*{
margin:0;
padding:0;
border:0;
}
.top{
width: 100px;
height: 100px;
margin-bottom: 100px;
background: red;
}
.bottom{
width: 100px;
height: 100px;
margin-top: 50px;
background: green;
}
</style>
</head>
<body>
<div class="top">高为100px,下边距为100px</div>
<div class="bottom">高为100px,上边距为50px</div>
</body>
</html>
此时两个块之间的间隙为100px,而非100+50px。
另外一个有趣的例子就是:假设有一个元素同时设置了margin-top和margin-bottom,但是内容为空,那么这两个margin值也会叠加,值为两者最大的一个,它类似与竖直方向上两个盒子margin值的叠加。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>水平方向的两个盒子</title>
<style>
*{
margin:0;
padding:0;
}
.top{
width: 500px;
height: 100px;
background: red;
}
.middle{
margin-top: 100px;
margin-bottom:50px;
}
.footer{
width: 500px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<div class="top">上面的div,高100px</div>
<div class="middle"></div>
<div class="footer">下面的div,高100px</div>
</body>
</html>
我们发现这时在上面的div和在下面的div之间的举例并不是100+50=150px,而是两者中的最大者,即100px。
(3)margin--在父元素和子元素之间应用(重点)
(1)在子元素中设置水平方向的margin值,父元素设置padding:父子元素距离为margin+padding,不会叠加;
(2)在子元素中设置竖直方向的margin值:margin-top: 100px;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>margin</title>
<style>
*{padding:0; margin:0; border:0;}
.father{
width: 500px;
height: 500px;
background: red;
}
.son{
width: 100px;
height: 100px;
background: green;
margin-top: 100px;
}
</style>
</head>
<body>
<div class="father">
<div class="son">高度为100px,margin-top为100px。</div>
</div>
</body>
</html>
效果如下:
我们希望子元素的上部距离父元素的上部为100px,可是我们看到的却是父元素的上部距离浏览器页面的上部有100px的距离,实际上这是因为当父元素没有设置padding值以及border值时,出现了一个bug--父元素的上方与子元素的上方完全重合在了一起,无法分开。所以才会导致上述这种父元素和子元素同时向下的情况。
对于这种问题解决方法有下面几种:
- 方法一:给父元素添加padding-top值
- 方法二:给父元素添加border值
- 方法三:给父元素添加属性overflow:hidden;
- 方法四:给父元素或者子元素声明浮动float;
- 方法五:使父元素或子元素声明为绝对定位:position:absolute;
- 方法六:给父元素添加属性 overflow:auto; positon:relative;
转载自 http://www.cnblogs.com/zhuzhenwei918/p/6124263.html
margin的高度塌陷总结:
在标准文档流中,竖直方向上的margin不叠加,以较大的为准,水平方向叠加无塌陷,如果不在标准文档流中(例如绝对定位,浮动),无塌陷现象。