问个关于CSS的问题。为毛margin-top没效果
html
<!doctype html> <html> <head> <title>{{title}}</title> <link href="static/main.css" rel="stylesheet"/> </head> <body class="bg-main"> <div class="container position-center margin-top-large bg-white radius" style="position:relative"> <div style="width:90%;" class="position-center"> <!-- 就这里 --> <div id="!!!这里!!!" class="margin-top-big text-left font-bold" style="height:30px;line-height:30px;border-top:1px;border-bottom:1px;border-style:solid;border-color:#eee;"> <a href="" class="color-green font-bold">asdf</a> </div> <div class="margin-top-big"> asdfasdf </div> </div> </div> </body> </html>
css
.margin-top-big { margin-top:20px; }
如果没有前面的
,死活没效果,不会跟外层的div有边距。但是在这个div前面加上个
就有……为啥
附所有的CSS:
css
* { margin: 0; padding:0; font-size:14px; border:0px; box-sizing:border-box; font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; vertical-align: baseline; outline:none; } body,html { height:100%; width:100%; } body { color:#333; } a { text-decoration: none; } .header { width:100%; } .container { min-width:800px; max-width:1000px; } .position-center { margin:0 auto; } .text-center { text-align:center; } .text-left { text-align:left; } .text-right { text-align:right; } .padding-top-small { padding-top:10px; } .padding-top-big { padding-top:20px; } .padding-top-large { padding-top:30px; } .padding-bottom-small { padding-bottom:10px; } .padding-bottom-big { padding-bottom:20px; } .padding-bottom-large { padding-bottom:30px; } .padding-left-small { padding-left:10px; } .padding-left-big { padding-left:20px; } .padding-left-large { padding-left:30px; } .margin-top-small { margin-top:10px; } .margin-top-big { margin-top:20px; } .margin-top-large { margin-top:30px; } .content-radius-top { border-top-left-radius: 4px; -moz-border-top-left-radius: 4px; -webkit-border-top-left-radius: 4px; border-top-right-radius:4px; -moz-border-top-right-radius:4px; -webkit-border-top-right-radius:4px; } /** form **/ .form-group:after { display:table; content:" "; clear:both; } .form-group { margin-right:-15px; margin-left:-15px; margin-bottom:15px; } .form-group .control-label { text-align:right; padding-top:7px; margin-top:0px; margin-bottom:0px; } .form-control { display: block; width:100%; padding:6px 12px; color:#555; vertical-align: middle; border-radius: 4px; -moz-border-radius:4px; -webkit-border-radius:4px; box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.075) inset; -moz-box-shadow:0px 1px 1px rgba(0, 0, 0, 0.075) inset; -webkit-box-shadow:0px 1px 1px rgba(0, 0, 0, 0.075) inset; transition:border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; background:none repeat scroll 0% 0% rgba(0, 0, 0, 0.6); border:1px solid #000; } .form-control:focus { box-shadow: 0px 0px 10px 4px #49af00 ; color:#49af00; } .w-1 { width:10%; float:left; } .w-2 { width:20%; float:left; } .w-3 { width:30%; float:left; } .w-4 { width:40%; float:left; } .w-5 { width:50%; float:left; } .w-6 { width:60%; float:left; } .w-7 { width:70%; float:left; } .w-8 { width:80%; float:left; } .w-9 { width:90%; float:left; } .w-10 { width:100%; float:left; } .border-top-nav { border:1px solid #777; } .border-main { border-width:1px 1px 1px 1px; border-style:solid; border-color:#050505 #050505 #050505 #222; } .radius { border-radius:3px; -moz-border-radius:3px; -webkit-border-radius:3px; } .button { height:8px; line-height:8px; padding:8px; } .font-bold { font-weight:bold; } .bg-main { background-color:#292929; } .bg-sk { background: none repeat scroll 0% 0% rgba(0, 0, 0, 0.5); } .bg-white { background-color: white; } .bg-gray { background-color: gray; } .bg-green { background-color:#49AF00; } .color-main { color:#333; } .color-green { color:#49AF00; } .color-white { color:white; } .color-gray { color:#777; } .color-555 { color:#555; }
Answers
这个问题困惑了很久,虽然没有大碍早就摸出来怎么搞定它,但始终不明白原因出在哪里,如果只是IE有问题我也不会太在意,可问题是所有上等浏览器都表现如此,这样叫我怎能安心?今天总算下狠心查出来怎么回事,居然是CSS2.1盒模型规范……虽然很别扭,非常别扭的规定。
问题如下图
两层Div结构,Outer Div属性为“margin:0 auto”,本该紧贴外框顶部的,如果没有Inner Div,或者没有Inner Div的“margin-top”属性,一切如预期。但是当Inner Div设置了“margin-top:10px”之后,它的父元素Outer Div也被撑出来一个本不该有的“margin-top:10px”效果。
这个“问题”……它是CSS2.1的盒模型中规定的内容——Collapsing margins:
In this specification, the expression collapsing margins means that adjoining margins (no non-empty content, padding or border areas or clearance separate them) of two or more boxes (which may be next to one another or nested) combine to form a single margin. 所有毗邻的两个或更多盒元素的margin将会合并为一个margin共享之。毗邻的定义为:同级或者嵌套的盒元素,并且它们之间没有非空内容、Padding或Border分隔。
这就是原因了。“嵌套”的盒元素也算“毗邻”,也会 Collapsing Margins。这个合并Margin其实很常见,就是文章段落元素
,并列很多个的时候,每一个都有上下1em的margin,但相邻的
之间只会显示1em的间隔而不是相加的2em。这个很好理解,我就是奇怪为什么W3C要让嵌套的元素也共享Margin,想不出来在什么情况下需要这样的表现。 这个问题的避免方法很多,只要破坏它出现的条件就行。给 Outer Div 加上 padding/border,或者给 Outer Div / Inner Div 设置为 float/position:absolute(CSS2.1规定浮动元素和绝对定位元素不参与Margin折叠)。 更多信息,关于不同值的margin折叠后表现的计算方法等等,可自行查阅W3C的CSS2.1规范:Collapsing margins。
解决方法:
1、修改父元素的高度,增加padding-top样式模拟(padding-top:1px;常用)
2、为父元素添加overflow:hidden;样式即可(完美)
3、为父元素或者子元素声明浮动(float:left;可用)
4、为父元素添加border(border:1px solid transparent可用)
5、为父元素或者子元素声明绝对定位