<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CSSASS &#187; margin collapsing</title>
	<atom:link href="http://www.cssass.com/blog/index.php/tag/margin-collapsing/feed" rel="self" type="application/rss+xml" />
	<link>http://www.cssass.com/blog</link>
	<description>三人行必有我师焉，择其善者而从之，其不善者而改之</description>
	<lastBuildDate>Wed, 08 Sep 2010 05:41:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>如何避开麻烦的margin叠加(margin collapsing)</title>
		<link>http://www.cssass.com/blog/index.php/2009/164.html</link>
		<comments>http://www.cssass.com/blog/index.php/2009/164.html#comments</comments>
		<pubDate>Sat, 21 Mar 2009 17:28:27 +0000</pubDate>
		<dc:creator>ONEBOYS</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[haslayout]]></category>
		<category><![CDATA[margin collapsing]]></category>

		<guid isPermaLink="false">http://www.cssass.com/blog/?p=164</guid>
		<description><![CDATA[在斯芬克斯——ie私有属性haslayout这篇文章中，我们提到的第一个斯芬克斯之迷，其实就是一个margin叠加问题。
关于margin collapsing，在W3C中是有明文规范的，符合其规则的都将产生margin collapsing。W3C认为margin叠加后的布局界面更良好。
margin collapsing（css2.1规范）
margin collapsing（css2规范）
margin叠加现象（父子级别）：


 &#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.0 Transitional//EN&#34; &#34;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&#34;&#62;
&#60;html xmlns=&#34;http://www.w3.org/1999/xhtml&#34;&#62;
&#60;head&#62;
&#60;meta http-equiv=&#34;Content-Type&#34; content=&#34;text/html; charset=UTF-8&#34; /&#62;
&#60;head&#62;
&#60;style type=&#34;text/css&#34;&#62;
 *{padding:0;margin:0;}
 #wrap{background:#ccc;}
 #content{background:#eee;margin:50px 0;}
&#60;/style&#62;
&#60;/head&#62;
&#60;body&#62;
&#60;div id=&#34;wrap&#34;&#62;
&#60;div id=&#34;content&#34;&#62;margin:50px 0;&#60;/div&#62;
&#60;/div&#62;
&#60;/body&#62;
&#60;/html&#62;

  

可以看出wrap未被子层的margin所撑开。
但是，这种margin叠加往往不是我们所想要的效果（一些人甚至将此称为一个bug：margin叠加bug，也有称高度不适应bug的）——平心而论，我们努力的要避开margin collapsing多少也有些违背了W3C的初衷。不过，由于ie下经常有意无意的会触发haslayout，从而会避开margin叠加，这使得浏览器间显示不一。因此，我们还是有理由在适当时候彻底避开margin叠加的。
那么，如何避免这种margin叠加现象呢？

从《斯芬克斯——ie私有属性haslayout》那篇文章中，我们知道，ie下触发haslayout可以避开margin叠加。那么其他浏览器呢？

我们先看一下另两种解决方法。
方法一：在父级内部的添加上、下两个空元素。
有些教科书上将这种方法称为完美的解决方法。但实际当中我们一般不会使用，因为这种方法不仅要多加两个无意义元素标签，对这两个元素还要特别设置CSS使其高度为0。）:


&#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.0 Transitional//EN&#34; &#34;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&#34;&#62;
&#60;html xmlns=&#34;http://www.w3.org/1999/xhtml&#34;&#62;
&#60;head&#62;
&#60;meta http-equiv=&#34;Content-Type&#34; content=&#34;text/html; charset=UTF-8&#34; /&#62;
&#60;head&#62;
&#60;style type=&#34;text/css&#34;&#62;
 *{padding:0;margin:0;}
 #wrap{background:#ccc;}
 #content{background:#eee;margin:50px 0;}
&#60;/style&#62;
&#60;/head&#62;
&#60;body&#62;
&#60;div id=&#34;wrap&#34;&#62;
&#60;div&#62;&#38;nbsp;&#60;/div&#62;
&#60;div id=&#34;content&#34;&#62;margin:50px 0;&#60;br /&#62;上下各添加一个额外空元素。元素只要不脱离文档流，就能在ie,ff等浏览器下避开margin-top塌陷。如果元素是脱离文档流的，只要是触发了haslayout，在ie下也能避开塌陷。这两个元素一般要设置其高为0,而不让其增加页面的额外高度。&#60;/div&#62;
&#60;div&#62;&#38;nbsp;&#60;/div&#62;
&#60;/div&#62;
&#60;/body&#62;
&#60;/html&#62;

  

第二种，在父级上使用border属性（属性值0和none除外）。
这个方法也不大经常使用，因为在wrap上至少要设置一个1px的多余边框（上下两个就是2px）,而且这条边线的颜色的颜色设置也是个问题，因为可能在wrap内部会使用背景图片(background-image),那么这条边线就无法伪装隐藏了。


 &#60;!DOCTYPE html PUBLIC [...]


Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2009/147.html' rel='bookmark' title='Permanent Link: 斯芬克斯之迷——ie私有属性haslayout的困扰'>斯芬克斯之迷——ie私有属性haslayout的困扰</a> <small>就象神话中的斯芬克斯一样，ie的私有属性haslayout是个神秘且让人困惑的难缠东西，她只游荡于ie（这片沙漠）之下。 她无法使用css声明直接创建。即便是对于ie，她也不能说是一个实实在在存在的属性。 ie下的元素有些本身拥有haslayout（基本上是一些拥有内在尺寸的可置换元素）,有些可以通过一些css属性可以触发产生。 我们可以在ie developer toolbar上查看到到haslayout这个属性项，他的值是-1。这说明这个元素触发了layout。 详细haslayout资料：On having layout抄录 更详细资料：译文On...</small></li><li><a href='http://www.cssass.com/blog/index.php/2009/71.html' rel='bookmark' title='Permanent Link: 一种不常用的布局——中间列宽度固定，左右列自适应宽'>一种不常用的布局——中间列宽度固定，左右列自适应宽</a> <small>三列布局，中间列宽度固定，左右列自适应宽。 在蓝色理想上的一个提问。 这种布局一般来说不大会用上。 （而相对比较常见的是这种布局：左右列固定高度，中间列自适应宽度。 之前写过一种此结构的扩展结构：三列自适应等高且中列宽度自适应布局） 用css来实现这种不常见的结构着实也不太容易（或许也是这种结构不流行的一个原因吧）。 实现主要难点在于左右列的宽度计算，假设中间列的宽度为Y,那么左右列的宽度就应该是(100%-Y)/2(左右列等宽情况下)。但是CSS又不支持这种算式计算（当然，ie下有expression，但是这种不标准的东西我们一向是不屑的）。 历数css中，唯一有减法效果的也就margin边距这么一种属性。 所以，我们找到了我们的独木桥——margin。 上下级包含的结构中，如果上级元素（block类型）固定宽度为X，下级元素不定宽，而设置属性margin:50px;那么下级元素的宽度就等于X-2×50px。...</small></li><li><a href='http://www.cssass.com/blog/index.php/2009/70.html' rel='bookmark' title='Permanent Link: 不同编码、浏览器下的尺寸（dimension）'>不同编码、浏览器下的尺寸（dimension）</a> <small>首先，说明下，第一次测试忽视了一个属性在不同编码，浏览器下的不同解释造成的尺寸不同，即line-height属性。 可以看出： 1，gb2312编码下： 未定高度,由文字填充的block元素在ff和ie下高度一致， 只是inline元素在ie7中要比在ff中较高。 2，utf-8编码下： inline,block(未定宽高)元素ie和ff的差别就大了。(ff中的inline,block元素都要比ie7中较高) 3.不论在gb2312或utf-8编码下，ff3的显示都是一致的（对照第一幅的左半边和第二幅的左半边）。 而ie7中相差就比较大了（gb2312编码下的inline,block元素都要比utf-8的高）。 4.ff下的bloak元素边框与文字间，上下有一定的间隙（类似padding，但无法去除）。...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>在<a href="/blog?p=147" target="_blank">斯芬克斯——ie私有属性haslayout</a>这篇文章中，我们提到的第一个斯芬克斯之迷，其实就是一个margin叠加问题。<br />
关于margin collapsing，在W3C中是有明文规范的，符合其规则的都将产生margin collapsing。W3C认为margin叠加后的布局界面更良好。</p>
<blockquote><p><a href="http://www.w3.org/TR/CSS21/box.html#collapsing-margins" target="_blank">margin collapsing（css2.1规范）</a><br />
<a href="http://www.w3.org/TR/CSS2/box.html#collapsing-margins" target="_blank">margin collapsing（css2规范）</a></p></blockquote>
<p>margin叠加现象（父子级别）：</p>
<div class="runcode">
<p><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_f3JQYJ" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
 &lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;head&gt;
&lt;style type=&quot;text/css&quot;&gt;
 *{padding:0;margin:0;}
 #wrap{background:#ccc;}
 #content{background:#eee;margin:50px 0;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;wrap&quot;&gt;
&lt;div id=&quot;content&quot;&gt;margin:50px 0;&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode.open_new('runcode_f3JQYJ');"/> <input type="button" value="选择" class="runcode_button" onclick="runcode.copy('runcode_f3JQYJ');"/> </p>
</div>
<p>可以看出wrap未被子层的margin所撑开。</p>
<p>但是，这种margin叠加往往不是我们所想要的效果（一些人甚至将此称为一个bug：margin叠加bug，也有称高度不适应bug的）——平心而论，我们努力的要避开margin collapsing多少也有些违背了W3C的初衷。不过，由于ie下经常有意无意的会触发haslayout，从而会避开margin叠加，这使得浏览器间显示不一。因此，我们还是有理由在适当时候彻底避开margin叠加的。</p>
<p>那么，如何避免这种margin叠加现象呢？<br />
<span id="more-164"></span><br />
从《斯芬克斯——ie私有属性haslayout》那篇文章中，我们知道，ie下触发haslayout可以避开margin叠加。那么其他浏览器呢？<br />
<br />
我们先看一下另两种解决方法。<br />
方法一：在父级内部的添加上、下两个空元素。<br />
有些教科书上将这种方法称为完美的解决方法。但实际当中我们一般不会使用，因为这种方法不仅要多加两个无意义元素标签，对这两个元素还要特别设置CSS使其高度为0。）:</p>
<div class="runcode">
<p><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_z_4fJV" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;head&gt;
&lt;style type=&quot;text/css&quot;&gt;
 *{padding:0;margin:0;}
 #wrap{background:#ccc;}
 #content{background:#eee;margin:50px 0;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;wrap&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div id=&quot;content&quot;&gt;margin:50px 0;&lt;br /&gt;上下各添加一个额外空元素。元素只要不脱离文档流，就能在ie,ff等浏览器下避开margin-top塌陷。如果元素是脱离文档流的，只要是触发了haslayout，在ie下也能避开塌陷。这两个元素一般要设置其高为0,而不让其增加页面的额外高度。&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode.open_new('runcode_z_4fJV');"/> <input type="button" value="选择" class="runcode_button" onclick="runcode.copy('runcode_z_4fJV');"/> </p>
</div>
<p>第二种，在父级上使用border属性（属性值0和none除外）。<br />
这个方法也不大经常使用，因为在wrap上至少要设置一个1px的多余边框（上下两个就是2px）,而且这条边线的颜色的颜色设置也是个问题，因为可能在wrap内部会使用背景图片(background-image),那么这条边线就无法伪装隐藏了。</p>
<div class="runcode">
<p><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_kGQMDv" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
 &lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;head&gt;
&lt;style type=&quot;text/css&quot;&gt;
 *{padding:0;margin:0;}
 #wrap{background:#ccc;border:1px solid #ccc} /* border的颜色设置同background一样 */
 #content{background:#eee;margin:50px 0;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;wrap&quot;&gt;
&lt;div id=&quot;content&quot;&gt;margin:50px 0;&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode.open_new('runcode_kGQMDv');"/> <input type="button" value="选择" class="runcode_button" onclick="runcode.copy('runcode_kGQMDv');"/> </p>
</div>
<p>
最后一个方法，就利用到了ie的haslayout原理了（清除浮动也用到了这种方法）。对于ff下，在父级（wrap）上使用overflow:hidden；对于ie则触发其layout——如何触发，可以看这篇文章：<a href="/blog?p=35" target="_blank">on having layout</a>。</p>
<div class="runcode">
<p><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_RrvxhP" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
 &lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;head&gt;
&lt;style type=&quot;text/css&quot;&gt;
 *{padding:0;margin:0;}
 #wrap{background:#ccc;overflow:hidden;width:100%}
 #content{background:#eee;margin:50px 0;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;wrap&quot;&gt;
&lt;div id=&quot;content&quot;&gt;margin:50px 0;&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode.open_new('runcode_RrvxhP');"/> <input type="button" value="选择" class="runcode_button" onclick="runcode.copy('runcode_RrvxhP');"/> </p>
</div>
<p>（overflow：hidden也会触发ie7中的layout。但是对之前的ie版本无效，否则倒是可以一个属性搞定）。</p>


<p>Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2009/147.html' rel='bookmark' title='Permanent Link: 斯芬克斯之迷——ie私有属性haslayout的困扰'>斯芬克斯之迷——ie私有属性haslayout的困扰</a> <small>就象神话中的斯芬克斯一样，ie的私有属性haslayout是个神秘且让人困惑的难缠东西，她只游荡于ie（这片沙漠）之下。 她无法使用css声明直接创建。即便是对于ie，她也不能说是一个实实在在存在的属性。 ie下的元素有些本身拥有haslayout（基本上是一些拥有内在尺寸的可置换元素）,有些可以通过一些css属性可以触发产生。 我们可以在ie developer toolbar上查看到到haslayout这个属性项，他的值是-1。这说明这个元素触发了layout。 详细haslayout资料：On having layout抄录 更详细资料：译文On...</small></li><li><a href='http://www.cssass.com/blog/index.php/2009/71.html' rel='bookmark' title='Permanent Link: 一种不常用的布局——中间列宽度固定，左右列自适应宽'>一种不常用的布局——中间列宽度固定，左右列自适应宽</a> <small>三列布局，中间列宽度固定，左右列自适应宽。 在蓝色理想上的一个提问。 这种布局一般来说不大会用上。 （而相对比较常见的是这种布局：左右列固定高度，中间列自适应宽度。 之前写过一种此结构的扩展结构：三列自适应等高且中列宽度自适应布局） 用css来实现这种不常见的结构着实也不太容易（或许也是这种结构不流行的一个原因吧）。 实现主要难点在于左右列的宽度计算，假设中间列的宽度为Y,那么左右列的宽度就应该是(100%-Y)/2(左右列等宽情况下)。但是CSS又不支持这种算式计算（当然，ie下有expression，但是这种不标准的东西我们一向是不屑的）。 历数css中，唯一有减法效果的也就margin边距这么一种属性。 所以，我们找到了我们的独木桥——margin。 上下级包含的结构中，如果上级元素（block类型）固定宽度为X，下级元素不定宽，而设置属性margin:50px;那么下级元素的宽度就等于X-2×50px。...</small></li><li><a href='http://www.cssass.com/blog/index.php/2009/70.html' rel='bookmark' title='Permanent Link: 不同编码、浏览器下的尺寸（dimension）'>不同编码、浏览器下的尺寸（dimension）</a> <small>首先，说明下，第一次测试忽视了一个属性在不同编码，浏览器下的不同解释造成的尺寸不同，即line-height属性。 可以看出： 1，gb2312编码下： 未定高度,由文字填充的block元素在ff和ie下高度一致， 只是inline元素在ie7中要比在ff中较高。 2，utf-8编码下： inline,block(未定宽高)元素ie和ff的差别就大了。(ff中的inline,block元素都要比ie7中较高) 3.不论在gb2312或utf-8编码下，ff3的显示都是一致的（对照第一幅的左半边和第二幅的左半边）。 而ie7中相差就比较大了（gb2312编码下的inline,block元素都要比utf-8的高）。 4.ff下的bloak元素边框与文字间，上下有一定的间隙（类似padding，但无法去除）。...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.cssass.com/blog/index.php/2009/164.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>斯芬克斯之迷——ie私有属性haslayout的困扰</title>
		<link>http://www.cssass.com/blog/index.php/2009/147.html</link>
		<comments>http://www.cssass.com/blog/index.php/2009/147.html#comments</comments>
		<pubDate>Sat, 21 Mar 2009 07:02:16 +0000</pubDate>
		<dc:creator>ONEBOYS</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[float]]></category>
		<category><![CDATA[haslayout]]></category>
		<category><![CDATA[margin collapsing]]></category>

		<guid isPermaLink="false">http://www.cssass.com/blog/?p=147</guid>
		<description><![CDATA[就象神话中的斯芬克斯一样，ie的私有属性haslayout是个神秘且让人困惑的难缠东西，她只游荡于ie（这片沙漠）之下。
她无法使用css声明直接创建。即便是对于ie，她也不能说是一个实实在在存在的属性。
ie下的元素有些本身拥有haslayout（基本上是一些拥有内在尺寸的可置换元素）,有些可以通过一些css属性可以触发产生。
我们可以在ie developer toolbar上查看到到haslayout这个属性项，他的值是-1。这说明这个元素触发了layout。
详细haslayout资料：On having layout抄录
更详细资料：译文On having layout这篇文章本人还没怎么看，相信很多问题在这里都有解释
遇到斯芬克斯是件很麻烦的事情，她会给你提出很多怪怪的让人困惑的问题，更何况只要我们在ie沙漠中游荡的话，遇到的概率是非常高的。
遇到她，我们会有三种结果：
猜不出迷题的答案——我们会在迷失在困惑中；
猜错了迷题的答案——我们会误会很多东西；
猜对了迷题的答案——恭喜你，你就不用怕斯芬克斯这个丑婆娘了。

那让我们来猜一下她的几个比较困惑的问题吧。

斯芬克斯之迷1：是firefox错了？


&#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.0 Transitional//EN&#34; &#34;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&#34;&#62;
&#60;html xmlns=&#34;http://www.w3.org/1999/xhtml&#34; &#62;
&#60;head&#62;
&#60;meta http-equiv=&#34;Content-Type&#34; content=&#34;text/html; charset=UTF-8&#34; /&#62;
&#60;style type=&#34;text/css&#34;&#62;
 *{padding:0;margin:0;}
 .wrap{}
  #left{float:left;color:red;}
  #right{background:#ccc;margin-top:50px;}
&#60;/style&#62;
&#60;/head&#62;
&#60;body&#62;
  &#60;div class=&#34;wrap&#34;&#62;
   &#60;div id=&#34;left&#34;&#62; left &#60;/div&#62;
   &#60;div id=&#34;right&#34;&#62; 在FF下，对right设置margin-top。结果不止right上方空出了50px;连left也一样空出了50px;是FF的解析有问题吗？&#60;/div&#62;
 &#60;/div&#62;
&#60;/body&#62;
&#60;/html&#62;

  

left是浮动元素，她脱离了文档流（注意，这是下一个斯芬克斯之迷），所以right的margin-top相对的是其上级wrap作用的。但我们只是对right设置margin-top。结果在FF下，怎么连left也“产生了margin-top&#8221;呢。对比ie和FF下的效果，是不是觉得IE下的解析会比较合理呢？
但是
别忘了影响margin-top/bottom的一个重要规则——margin塌陷（margin collapsing）。
margin collapsing（css2.1规范）
margin collapsing（css2规范）
在ff下就是产生了这么一个margin塌陷。导致wrap的&#8221;剥夺&#8221;了本属于子元素#right的margin-top值。
为了更加直观看出是否塌陷，可以給wrap添加一个背景：background:#000；


&#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.0 Transitional//EN&#34; &#34;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&#34;&#62;
&#60;html xmlns=&#34;http://www.w3.org/1999/xhtml&#34; [...]


Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2009/164.html' rel='bookmark' title='Permanent Link: 如何避开麻烦的margin叠加(margin collapsing)'>如何避开麻烦的margin叠加(margin collapsing)</a> <small>在斯芬克斯——ie私有属性haslayout这篇文章中，我们提到的第一个斯芬克斯之迷，其实就是一个margin叠加问题。 关于margin collapsing，在W3C中是有明文规范的，符合其规则的都将产生margin collapsing。W3C认为margin叠加后的布局界面更良好。 margin collapsing（css2.1规范） margin collapsing（css2规范） margin叠加现象（父子级别）： &lt;!DOCTYPE...</small></li><li><a href='http://www.cssass.com/blog/index.php/2009/71.html' rel='bookmark' title='Permanent Link: 一种不常用的布局——中间列宽度固定，左右列自适应宽'>一种不常用的布局——中间列宽度固定，左右列自适应宽</a> <small>三列布局，中间列宽度固定，左右列自适应宽。 在蓝色理想上的一个提问。 这种布局一般来说不大会用上。 （而相对比较常见的是这种布局：左右列固定高度，中间列自适应宽度。 之前写过一种此结构的扩展结构：三列自适应等高且中列宽度自适应布局） 用css来实现这种不常见的结构着实也不太容易（或许也是这种结构不流行的一个原因吧）。 实现主要难点在于左右列的宽度计算，假设中间列的宽度为Y,那么左右列的宽度就应该是(100%-Y)/2(左右列等宽情况下)。但是CSS又不支持这种算式计算（当然，ie下有expression，但是这种不标准的东西我们一向是不屑的）。 历数css中，唯一有减法效果的也就margin边距这么一种属性。 所以，我们找到了我们的独木桥——margin。 上下级包含的结构中，如果上级元素（block类型）固定宽度为X，下级元素不定宽，而设置属性margin:50px;那么下级元素的宽度就等于X-2×50px。...</small></li><li><a href='http://www.cssass.com/blog/index.php/2009/73.html' rel='bookmark' title='Permanent Link: CSS多类选择符测试'>CSS多类选择符测试</a> <small> &lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt; &lt;html...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>就象神话中的斯芬克斯一样，ie的私有属性haslayout是个神秘且让人困惑的难缠东西，她只游荡于ie（这片沙漠）之下。<br />
她无法使用css声明直接创建。即便是对于ie，她也不能说是一个实实在在存在的属性。<br />
ie下的元素有些本身拥有haslayout（基本上是一些拥有内在尺寸的可置换元素）,有些可以通过一些css属性可以触发产生。<br />
<blockquote>我们可以在ie developer toolbar上查看到到haslayout这个属性项，他的值是-1。这说明这个元素触发了layout。<br />
详细haslayout资料：<a href="/blog?p=35" target="_blank">On having layout抄录</a><br />
更详细资料：<a href="http://bbs.blueidea.com/thread-2636904-1-1.html" target="_blank">译文On having layout</a>这篇文章本人还没怎么看，相信很多问题在这里都有解释</p></blockquote>
<p>遇到斯芬克斯是件很麻烦的事情，她会给你提出很多怪怪的让人困惑的问题，更何况只要我们在ie沙漠中游荡的话，遇到的概率是非常高的。<br />
遇到她，我们会有三种结果：<br />
猜不出迷题的答案——我们会在迷失在困惑中；<br />
猜错了迷题的答案——我们会误会很多东西；<br />
猜对了迷题的答案——恭喜你，你就不用怕斯芬克斯这个丑婆娘了。<br />
<br />
那让我们来猜一下她的几个比较困惑的问题吧。<br />
<span id="more-147"></span></p>
<h3>斯芬克斯之迷1：是firefox错了？</h3>
<div class="runcode">
<p><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_Mc5jwH" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; &gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;style type=&quot;text/css&quot;&gt;
 *{padding:0;margin:0;}
 .wrap{}
  #left{float:left;color:red;}
  #right{background:#ccc;margin-top:50px;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div class=&quot;wrap&quot;&gt;
   &lt;div id=&quot;left&quot;&gt; left &lt;/div&gt;
   &lt;div id=&quot;right&quot;&gt; 在FF下，对right设置margin-top。结果不止right上方空出了50px;连left也一样空出了50px;是FF的解析有问题吗？&lt;/div&gt;
 &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode.open_new('runcode_Mc5jwH');"/> <input type="button" value="选择" class="runcode_button" onclick="runcode.copy('runcode_Mc5jwH');"/> </p>
</div>
<p>left是浮动元素，她脱离了文档流（注意，这是下一个斯芬克斯之迷），所以right的margin-top相对的是其上级wrap作用的。但我们只是对right设置margin-top。结果在FF下，怎么连left也“产生了margin-top&#8221;呢。对比ie和FF下的效果，是不是觉得IE下的解析会比较合理呢？<br />
但是<br />
别忘了影响margin-top/bottom的一个重要规则——margin塌陷（margin collapsing）。</p>
<blockquote><p><a href="http://www.w3.org/TR/CSS21/box.html#collapsing-margins" target="_blank">margin collapsing（css2.1规范）</a><br />
<a href="http://www.w3.org/TR/CSS2/box.html#collapsing-margins" target="_blank">margin collapsing（css2规范）</a></p></blockquote>
<p>在ff下就是产生了这么一个margin塌陷。导致wrap的&#8221;剥夺&#8221;了本属于子元素#right的margin-top值。<br />
为了更加直观看出是否塌陷，可以給wrap添加一个背景：background:#000；</p>
<div class="runcode">
<p><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_JzzGpE" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; &gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;style type=&quot;text/css&quot;&gt;
 *{padding:0;margin:0;}
 .wrap{background:#000}
  #left{float:left;color:red;}
  #right{background:#ccc;margin-top:50px;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div class=&quot;wrap&quot;&gt;
   &lt;div id=&quot;left&quot;&gt; left &lt;/div&gt;
   &lt;div id=&quot;right&quot;&gt; 在FF下，对right设置margin-top。结果不止right上方空出了50px;连left也一样空出了50px;是FF的解析有问题吗？&lt;/div&gt;
 &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode.open_new('runcode_JzzGpE');"/> <input type="button" value="选择" class="runcode_button" onclick="runcode.copy('runcode_JzzGpE');"/> </p>
</div>
<p>在ff下wrap块的高度并没有被子元素right的margin-top撑开。反而自身拥有了50px的margin-top。<br />
而浮动的left尽管脱离了文档流，但还是受其父级限制的（这跟absolute定位的元素层受限于其定义为relative的父级一样）。所以left还是包含在wrap之中，这样在ff下看起来left也拥有margin-top，而事实上是因为wrap高度不撑开的结果。</p>
<p>这么说,FF并没有错咯,那么IE下又是怎么避开margin塌陷的呢？<br />
问题就出在浮动上面，在ie下，元素浮动将触发其haslayout。就是这个原因，使得在ie下意外（意外？）的就避开了margin塌陷。<br />
haslayout差点让我们怀疑了我们的亲密伙伴firefox。</p>
<blockquote><p>&#8212;&#8212;&#8212;-谜题之外&#8212;&#8212;&#8212;&#8211;<br />
但是，margin塌陷往往不是我们想要的效果。那么我们需要怎么避开他呢？<br />
可以看下这篇独立文章：<a href="/blog?p=164" target="_blank">如何解决麻烦的margin塌陷(margin collapsing)</a></p></blockquote>
<h3>斯芬克斯之迷2：在ie下，float元素不脱离文档流？</h3>
<p>在前面的问题里，我们提到浮动元素时一直认为浮动元素脱离文档流。但是看一下下面这个现象：</p>
<div class="runcode">
<p><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_GG7ayF" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; &gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;title&gt;ie下,float不脱离文档流？&lt;/title&gt;
&lt;style type=&quot;text/css&quot;&gt;
 *{padding:0;margin:0;}
 .wrap{}
  #left{float:left;color:red;}
  #right{background:#ccc;width:500px;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div class=&quot;wrap&quot;&gt;
   &lt;div id=&quot;left&quot;&gt; left &lt;/div&gt;
   &lt;div id=&quot;right&quot;&gt; ie下width:500px;触发了#right的layout，所以貌似ie下float并不会脱离文档流，&lt;/div&gt;
 &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode.open_new('runcode_GG7ayF');"/> <input type="button" value="选择" class="runcode_button" onclick="runcode.copy('runcode_GG7ayF');"/> </p>
</div>
<p>很多人都一直怀疑浮动元素脱离文档流的这种说法，就是因为ie下haslayout的经常出现。ie下，浮动的元素（left）牢牢的占着自己的位置。后面的block元素（right），只能跟随其后（请对比FF下的效果）。<br />
没错，这又是haslayout在迷惑我们，这回除了left因为浮动触发了haslayout外，right也由于使用了width:500px也触发了haslayout，使得他考虑到了前面浮动的left元素。<br />
如果把right的宽度去掉，或则把值改成auto。就能使ie下达到ff下一样的效果：后面的block元素会忽略前面浮动元素的存在，直接跑到浮动元素的z轴方向的下面（为什么是下面？因为浮动元素的Z值较正常的要高），而inline元素则环绕此浮动元素。<br />
我们再看一个更加明了的demo:</p>
<div class="runcode">
<p><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_mP5__B" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;title&gt;haslayout影响浮动元素脱离文档流&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div style=&quot;background:#000;width:100%;&quot;&gt;
  &lt;div style=&quot;float:left;width:100px;height:100px;background:#ccc;&quot;&gt;ie下。去除父级wrap的width:100%。对比效果。&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode.open_new('runcode_mP5__B');"/> <input type="button" value="选择" class="runcode_button" onclick="runcode.copy('runcode_mP5__B');"/> </p>
</div>
<p>由于父级使用width:100%.触发了haslayout。使得原本脱离文档流的浮动元素，又在其父级之内拥有了一席之地。</p>
<blockquote><p>&#8212;&#8212;-谜题之外&#8212;&#8212;&#8211;<br />
浮动有三个作用效果：<br />
一是使得自身脱离文档流，使得父层不适应其高度,而后面的block元素也将忽略其“存在”，跑到浮动元素之下（可在block元素上加背景色查看）；<br />
二是使得后面的inline元素“顺流环绕”浮动元素。<br />
三是浮动元素的尺寸，如果未定义的话，将按内部元素的尺寸来决定（而不是block元素默认的充满整行）。而且即便浮动元素本身是非可置换inline元素，她都可以定义width/height(还有margin也将算入尺寸计算)。<br />
其实第一个效果往往不是我们所想要的。所以ie下的haslayout可以说正中我们下怀。那么FF下怎么让left元素不脱离文档流（看起来没有脱离）呢？<br />
在上面的例子中，我们可以对right也使用浮动，或则在right加上overflow:hidden。<br />
知道了这个原理，我们对于这个【右列宽度自适应】的布局（其实这是个左右布局均自适应的布局。一般来说我们会固定左列的宽度）就能很好理解了：<br />
zoom:1针对IE系列触发haslayout.overflow:hidden针对FF。使得right不会忽视已经脱离文档流的浮动元素left。</p>
<div class="runcode">
<p><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_P024yY" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; &gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;title&gt;二列，右列自适应宽度布局&lt;/title&gt;
&lt;style type=&quot;text/css&quot;&gt;
 *{padding:0;margin:0;}
 .wrap{overflow:hidden;}
  #left{float:left;color:red;}
  #right{background:#ccc;zoom:1;overflow:hidden;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div class=&quot;wrap&quot;&gt;
   &lt;div id=&quot;left&quot;&gt; left &lt;/div&gt;
   &lt;div id=&quot;right&quot;&gt; 更多右列宽度自适应布局的方法：&lt;a href=&quot;http://www.cssass.com/blog/index.php/2008/31.html&quot;&gt;http://www.cssass.com/blog/index.php/2008/31.html&lt;/a&gt;&lt;/div&gt;
 &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode.open_new('runcode_P024yY');"/> <input type="button" value="选择" class="runcode_button" onclick="runcode.copy('runcode_P024yY');"/> </p>
</div>
</blockquote>
<p>IE下的haslayout会引发很多问题：</p>
<blockquote><p>  IE 很多常见的浮动 bug 。<br />
  元素本身对一些基本属性的异常处理问题。<br />
  容器和其子孙之间的边距重叠(margin collapsing)问题。<br />
  使用列表时遇到的诸多问题。<br />
  背景图像的定位偏差问题。<br />
  使用脚本时遇到的浏览器之间处理不一致的问题。</p></blockquote>
<p>她经常让我们困惑不堪。<br />
但是只要逐步认识她，重视她。经常怀疑，怀疑自己的怀疑。我们就能慢慢摸清她的谜题，了解问题的本质。</p>


<p>Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2009/164.html' rel='bookmark' title='Permanent Link: 如何避开麻烦的margin叠加(margin collapsing)'>如何避开麻烦的margin叠加(margin collapsing)</a> <small>在斯芬克斯——ie私有属性haslayout这篇文章中，我们提到的第一个斯芬克斯之迷，其实就是一个margin叠加问题。 关于margin collapsing，在W3C中是有明文规范的，符合其规则的都将产生margin collapsing。W3C认为margin叠加后的布局界面更良好。 margin collapsing（css2.1规范） margin collapsing（css2规范） margin叠加现象（父子级别）： &lt;!DOCTYPE...</small></li><li><a href='http://www.cssass.com/blog/index.php/2009/71.html' rel='bookmark' title='Permanent Link: 一种不常用的布局——中间列宽度固定，左右列自适应宽'>一种不常用的布局——中间列宽度固定，左右列自适应宽</a> <small>三列布局，中间列宽度固定，左右列自适应宽。 在蓝色理想上的一个提问。 这种布局一般来说不大会用上。 （而相对比较常见的是这种布局：左右列固定高度，中间列自适应宽度。 之前写过一种此结构的扩展结构：三列自适应等高且中列宽度自适应布局） 用css来实现这种不常见的结构着实也不太容易（或许也是这种结构不流行的一个原因吧）。 实现主要难点在于左右列的宽度计算，假设中间列的宽度为Y,那么左右列的宽度就应该是(100%-Y)/2(左右列等宽情况下)。但是CSS又不支持这种算式计算（当然，ie下有expression，但是这种不标准的东西我们一向是不屑的）。 历数css中，唯一有减法效果的也就margin边距这么一种属性。 所以，我们找到了我们的独木桥——margin。 上下级包含的结构中，如果上级元素（block类型）固定宽度为X，下级元素不定宽，而设置属性margin:50px;那么下级元素的宽度就等于X-2×50px。...</small></li><li><a href='http://www.cssass.com/blog/index.php/2009/73.html' rel='bookmark' title='Permanent Link: CSS多类选择符测试'>CSS多类选择符测试</a> <small> &lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt; &lt;html...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.cssass.com/blog/index.php/2009/147.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
