﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-VincentChen‘s Blog-文章分类-JavaScript</title><link>http://www.blogjava.net/Vencent/category/7762.html</link><description>&lt;font color='orange'&gt;本博客仅为收集所用。在此对原作者表示感谢。&lt;/font&gt;
&lt;center&gt;
&lt;script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;div class="custom"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-6256612161572960";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text";
google_ad_channel ="";
google_page_url = document.location;
google_color_border = ["FFDDAA","FFDDAA","FFDDAA","FFDDAA"];
google_color_bg = ["EEEEEE","EEEEEE","EEEEEE","EEEEEE"];
google_color_link = ["FFDDAA","0033FF","00008B","99CC33"];
google_color_url = ["999999","0033FF","00008B","FFCC00"];
google_color_text = ["0033FF","AA9999","0033FF","AA9999"];
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;/center&gt;
&lt;bgsound src="http://www.blogjava.net/Files/Vencent/The%20Mass%20Era.zip" volume="10" loop="10"/&gt;</description><language>zh-cn</language><lastBuildDate>Mon, 14 May 2007 07:21:44 GMT</lastBuildDate><pubDate>Mon, 14 May 2007 07:21:44 GMT</pubDate><ttl>60</ttl><item><title>转载：On having layout</title><link>http://www.blogjava.net/Vencent/articles/117308.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Mon, 14 May 2007 04:53:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/117308.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/117308.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/117308.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/117308.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/117308.html</trackback:ping><description><![CDATA[<h1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; On having layout</h1>
<p>　　译者注：一篇很好的文章，很久以前在blog上就推荐过，这两天断断续续花了点时间翻译了一下，推荐读读。<a href="http://www.satzansatz.de/cssd/onhavinglayout.htm"><u><font color=#0066cc>英文原文在此</font></u></a>。</p>
<p>　　文中所有的 layout 这个单词都未作翻译，一来本身这个单词意思就比较多，翻成啥都觉得别扭，二来它也是专有的属性，所以就意会一下吧。水平有限，很多地方都是模模糊糊地意译，发现错误欢迎留言指出。</p>
<p>　　引用一段来自<a href="http://dean.edwards.name/weblog/"><u><font color=#0066cc>Dean Edwards</font></u></a>的评价：</p>
<blockquote>
<p>　　I recommend that every CSS designer and DOM scripter read this. Understanding &#8220;layout&#8221; gives a huge insight into lots of other IE bugs and idiosyncrasies.</p>
</blockquote>
<p class=blockquotesource>(<a href="http://dean.edwards.name/weblog/2005/06/layout/"><u><font color=#0066cc>Dean Edwards</font></u></a>)</p>
<h4 id=intro>介绍</h4>
<p>　　Internet Explorer 中有很多奇怪的渲染问题可以通过赋予其&#8220;layout&#8221;得到解决。John Gallant 和 Holly Bergevin 把这些问题归类为&#8220;尺寸bug(dimensional bugs)&#8221;，意思是这些 bug 可以通过赋予相应元素某个宽度或高度解决。这便引出关于&#8220;layout&#8221;的一个问题：为什么它会改变元素的渲染特性，为什么它会影响到元素之间的关系？这个问题问得很好，但却很难回答。在这篇文章中，我们专注于这个复杂问题会有那些方面的表现，某一方面的具体讨论和范例请参考文中给出的相关链接。</p>
<h4 id=def>hasLayout — 定义</h4>
<p>　　&#8220;Layout&#8221;是一个 IE/Win 的私有概念，它决定了一个元素如何显示以及约束其包含的内容、如何与其他元素交互和建立联系、如何响应和传递应用程序事件/用户事件等，这有点类似于一个窗体的概念。</p>
<p>　　微软的开发者们认为盒状元素(box-type elements)应该具有一个&#8220;属性(property)&#8221;(这是面向对象编程中的一个概念)，于是他们便使用了 <code>layout</code> , 也就是 <code>hasLayout</code>。</p>
<p>　　<code>hasLayout</code> 其实既不是一个属性更不是一个行为，而是 IE 这个渲染引擎代代继承一贯拥有的一个渲染概念，在这个概念下渲染的元素将具有一种特性。</p>
<p>　　实际上这种渲染特性在有些 HTML 元素中与身俱来，而在另外一些元素中也可以通过一些 CSS 属性将其触发为 <code>true</code> ，且一旦触发将不可逆转。</p>
<div class=alpha>
<h5 id=nom>术语</h5>
<p>　　当我们说一个元素&#8220;拥有layout&#8221;或&#8220;得到layout&#8221;，或者说一个元素&#8220;has layout&#8221; 的时候，我们的意思是指它的微软专有属性 <a title=查看MSDN中的属性描述 href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/haslayout.asp"><code><u><font color=#0066cc>hasLayout</font></u></code></a> 被设为了 <code>true</code> 。一个&#8220;layout元素&#8221;可以是一个默认就拥有 layout 的元素或者是一个通过设置某些 CSS 属性得到 layout 的元素。</p>
<p>　　而&#8220;无layout元素&#8221;，是指 hasLayout 未被触发的元素，比如一个未设定宽高尺寸的干净 div 元素就可以做为一个 &#8220;无layout祖先&#8221;。</p>
<p>　　给一个默认没有 layout 的元素赋予 layout 的方法包括设置可触发 <code>hasLayout = true</code> 的 CSS 属性。参考<a href="http://www.sharkui.com/articles/onhavinglayout.html#elem"><u><font color=#0066cc>默认 layout 元素</font></u></a>以及这些<a href="http://www.sharkui.com/articles/onhavinglayout.html#prop"><u><font color=#0066cc>属性</font></u></a>列表。没有办法设置 <code>hasLayout = false</code> ， 除非把一开始那些触发 <code>hasLayout = true</code> 的 CSS 属性去除。</p>
</div>
<h4 id=begin>问题种种</h4>
<p>　　<code>hasLayout</code> 的问题不管新手还是老手，不管设计师或者程序员可能都遇到过。具有 layout 的元素通常有着不同寻常而且难以预料的的显示效果，而且有时甚至会牵连到他们的孩子元素。</p>
<p>　　一个元素是否具有&#8220;layout&#8221;可能会引发如下的一些问题：</p>
<ul>
    <li>IE 很多常见的浮动 bug 。
    <li>元素本身对一些基本属性的异常处理问题。
    <li>容器和其子孙之间的边距重叠(margin collapsing)问题。
    <li>使用列表时遇到的诸多问题。
    <li>背景图像的定位偏差问题。
    <li>使用脚本时遇到的浏览器之间处理不一致的问题。 </li>
</ul>
<p>　　上面的列表只是列出一个大概，也不完善。下面的文章将尽可能详细彻底的描述有无&#8220;layout&#8221;所带来的各种问题。</p>
<h4 id=wherefrom>Layout 从何而来</h4>
<p>　　不同于标准属性，也不像某些浏览器的私有 CSS 属性，layout <em>无法通过某一个 CSS 声明直接设定</em> 。也就是说没有&#8220;layout属性&#8221;这么一个东西，元素要么本身自动拥有 layout，要么借助一些 CSS 声明悄悄地获得 layout。</p>
<div class=alpha>
<h5 id=elem>默认layout元素</h5>
<p>　　下列元素应该是默认具有 layout 的：</p>
<ul>
    <li><code>&lt;html&gt;, &lt;body&gt;</code>
    <li><code>&lt;table&gt;, &lt;tr&gt;, &lt;th&gt;, &lt;td&gt;</code>
    <li><code>&lt;img&gt;</code>
    <li><code>&lt;hr&gt;</code>
    <li><code>&lt;input&gt;, &lt;select&gt;, &lt;textarea&gt;, &lt;button&gt;</code>
    <li><code>&lt;iframe&gt;, &lt;embed&gt;, &lt;object&gt;, &lt;applet&gt;</code>
    <li><code>&lt;marquee&gt;</code> </li>
</ul>
<h5 id=prop>属性</h5>
<p>　　下列 CSS 属性和取值将会让一个元素获得 layout：</p>
<dl>
<dt><code>position: absolute</code>
<dd>绝对定位元素的包含区块(containing block)就会经常在这一方面出问题。
<dt><code>float: left|right</code>
<dd>由于 layout 元素的特性，浮动模型会有很多怪异的表现。
<dt><code>display: inline-block</code>
<dd>当一个内联级别的元素需要 layout 的时候往往就要用到它，这也可能也是这个 CSS 属性的唯一效果——让某个元素拥有 layout。&#8220;inline-block行为&#8221;在IE中是可以实现的，但是非常与众不同： <a title="查看Bruno Fassino的相关文章" href="http://www.brunildo.org/test/InlineBlockLayout.html"><u><font color=#0066cc>IE/Win: inline-block and hasLayout</font></u></a> 。
<dt><code>width: 任意值</code>
<dd>很多人遇到 layout 相关问题发生时，一般都会先尝试用这个来修复。
<dt><code>height: 任意值</code>
<dd>height: 1% 就在 Holly Hack 中用到。
<dt><code>zoom: 任意值</code> (<a title=查看MSDN中的属性描述 href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/zoom.asp"><u><font color=#0066cc>MSDN</font></u></a>)
<dd>MS专有属性，无法通过校验。 不过 <code>zoom: 1</code> 可以临时用做调试。
<dt><code>writing-mode: tb-rl</code> (<a title=查看MSDN中的属性描述 href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/writingmode.asp"><u><font color=#0066cc>MSDN</font></u></a>)
<dd>MS专有属性，无法通过校验。 </dd></dl>
<p>　　在 IE7 中，overflow 也变成了一个 layout 触发器：</p>
<dl>
<dt><code>overflow: hidden|scroll|auto</code>
<dd>这个属性在之前版本 IE 中没有触发 layout 的功能。
<dt><code>overflow-x|-y: hidden|scroll|auto</code>
<dd>overflow-x 和 overflow-y 是 CSS3 盒模型中的属性，尚未得到浏览器的广泛支持。他们在之前版本IE中没有触发 layout 的功能。 </dd></dl>
<p>　　另外 IE7 的荧幕上又新添了几个 haslayout 的演员，如果只从 hasLayout 这个方面考虑，min/max 和 width/height 的表现类似，position 的 fixed 和 absolute 也是一模一样。</p>
<dl>
<dt><code>position: fixed</code>
<dd>./.
<dt><code>min-width: 任意值</code>
<dd>就算设为0也可以让该元素获得 layout。
<dt><code>max-width: 除 none 之外的任意值</code>
<dd>./.
<dt><code>min-height: 任意值</code>
<dd>即使设为0也可以让该元素的 haslayout=true
<dt><code>max-height: 除 none 之外的任意值</code>
<dd>./. </dd></dl>
<p>　　以上结论借助 IE Developer Toobar 以及预先测试得出。</p>
<h5 id=inline>有关内联级别元素</h5>
<p>　　对于内联元素(可以是默认即为内联的比如 <code>span</code> 元素，也可以是 <code>display: inline</code> 的元素)</p>
<ul>
    <li><code>width</code> 和 <code>height</code> 只在 IE5.x 下和 IE6 的 quirks 模式下触发 <code>hasLayout</code> 。因为在 IE6 中，如果浏览器运行于标准兼容模式下，内联元素会忽略 width 或 height 属性，所以设置 width 或 height 不能在此种情况下令该元素具有 layout。
    <li><code>zoom</code> 总是可以触发 <code>hasLayout</code>，但是在 IE5.0 中不支持。 </li>
</ul>
<p>　　具有&#8220;layout&#8221; 的元素如果同时也 <code>display: inline</code> ，那么它的行为就和标准中所说的 inline-block 很类似了：在段落中和普通文字一样在水平方向和连续排列，受 vertical-align 影响，并且大小可以根据内容自适应调整。这也可以解释为什么单单在 IE/Win 中内联元素可以包含块级元素而少出问题，因为在别的浏览器中 <code>display: inline</code> 就是内联，不像 IE/Win 一旦内联元素拥有 layout 还会变成 inline-block。</p>
<h5 id=haslayoutprop>脚本属性 hasLayout</h5>
<p>　　我们这里称 hasLayout 为&#8220;脚本属性&#8221;是为了和我们熟知的 CSS 属性相区别。</p>
<p>　　注意一旦一个元素拥有了 layout，就没有办法再将其设成 <code>hasLayout = False</code> 了。</p>
<p>　　<a title=查看MSDN中的属性描述 href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/haslayout.asp"><u><font color=#0066cc>hasLayout-property</font></u></a> 可以用来检测一个元素是否拥有 layout：举个例子，如果它的 <code>id</code> 是&#8220;eid&#8221;，那么只要在 IE5.5+ 的地址栏里输入 <code class=c1>javascript: alert(eid.currentStyle.hasLayout)</code> 即可检测它的状态。</p>
<p>　　IE的 <a title=MS提供的下载 href="http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e-2d5e1db91038&amp;displaylang=en"><u><font color=#0066cc>Developer Toolbar</font></u></a> 可以实时检查一个元素的当前样式；如果 <code>hasLayout</code> 是 true ，那么它的值显示为 &#8220;-1&#8221;。 我们可以通过实时修改一个元素的属性将&#8220;zoom(css)&#8221;设置为&#8220;1&#8221;来触发 <code>hasLayout</code> 以便调试。</p>
<p>　　另外一个需要注意的是&#8220;layout&#8221;会影响脚本编程。如果一个元素没有&#8220;layout&#8221;，那么<code>clientWidth</code>/<code>clientHeight</code> 总是返回0。这会让一些脚本新手感到困惑，而且这和 Mozilla 浏览器的处理方式也不一样。不过我们可以利用这一点在 IE5.0 中检测&#8220;layout&#8221;：如果 <code>clientWidth</code> 是零那么这个元素就没有 layout。</p>
</div>
<h4 id=hack>CSS hacks</h4>
<p>　　下面用于触发 <code>haslayout</code> 的 hack 已经经过 IE6 及以下版本测试。今后版本的IE有可能会对此做不同处理。如果新版本浏览器发布我们会重新整理这部分内容。</p>
<p>　　John Gallant 和 Holly Bergevin 在2003年发布的 <a title=发表于communitymx href="http://www.communitymx.com/content/article.cfm?page=2&amp;cid=C37E0"><u><font color=#0066cc>Holly hack</font></u></a> ：</p>
<pre class=code>/* \*/
* html .gainlayout { height: 1%; }
/* */	</pre>
<ul>
    <li>可以让 IE5+ 的任意元素获得 layout，除了标准兼容模式 IE6 中的内联元素。
    <li>一般都很有效，除了在某些极少情况下，需要用 height:0 或者 1px 更好一些。
    <li>和 <code>overflow: hidden</code> 不相容，除非在 IE6 的标注兼容模式下(因为这时如果父元素没有定高，那么<code>height: 1%</code> 会被变回 <code>height: auto</code>)。 </li>
</ul>
<p>　　或者我们可以用 <a title="查看WellStyled Workshop中的文章" href="http://wellstyled.com/singlelang.php?lang=en&amp;page=css-underscore-hack.html"><u><font color=#0066cc>underscore hack</font></u></a>:</p>
<pre class=code>.gainlayout { _height: 0; }</pre>
<p>　　另外，更具有向后兼容性的方法是使用 <a title=查看MSDN href="http://msdn.microsoft.com/workshop/author/dhtml/overview/ccomment_ovw.asp"><u><font color=#0066cc>条件注释(conditional comments)</font></u></a>:</p>
<pre class=code>&lt;!--[if lte IE 6]&gt;
&lt;style&gt;
.gainlayout { height: 1px; }
&lt;/style&gt;
&lt;![endif]--&gt;</pre>
<p>　　在条件注释中链接一个专门对 IE/Win 做修正的外部样式表文件，也不失为一个安全有效的好方法：</p>
<pre class=code>&lt;link rel="stylesheet" href="allbrowsers.css" type="text/css" /&gt;
&lt;!--[if lte IE 6]&gt;
&lt;link rel="stylesheet" href="iefix.css" type="text/css" /&gt;
&lt;![endif]--&gt;</pre>
<p>　　我们更倾向于使用 <code>height: 0</code> 和 <code>1px</code> —— 并主张始终使用 <code>height</code> 除非它和别的什么东西冲突 (<code>overflow: hidden</code>)。对于取值，我们则倾向于避免 <code>1%</code> ，因为它可能会(虽然很少)引起<a title=看看Fassino的测试样例 href="http://www.brunildo.org/test/relayout.html"><u><font color=#0066cc>一些问题</font></u></a>。</p>
<p>　　一个需要注意的情况是如果我们希望一个元素保持内联，那么就不能使用 <code>height</code> 了，这时可以用 <code>display: inline-block</code> 。我们只在早期调试阶段用 <code>zoom: 1</code> 来避免一些渲染错误。</p>
<p>　　我们曾看过一些把 Holly hack 真的当作 holy(神圣的) hack 盲目使用的情况，比如对浮动元素使用或者对已经具有特定宽度的元素也使用这个 hack。要记住这个 hack 的目的不是要给某个元素加一个高度，而只是要触发 <code>hasLayout = True</code> 而已。</p>
<p>　　不要给所有元素设置 layout：<code>* {_height: 1px;}</code>。所谓过犹不及，获得 layout 不等于获得灵丹妙药，它只是用来改变渲染模式。</p>
<div class=alpha>
<h5 id=hackmanagement>Hack整理</h5>
<p>　　但是浏览器总是会变的，我们需要面对很多问题，比如一些依赖 IE6 的 bug 所做的 hack 会在 IE7 或更高版本的新浏览器中因 bug 修复而失效(甚至有害)的问题；比如新版本浏览器中类似的布局 bug 依然存在但用于 hack 的过滤器比如 <code>* html</code> 却不能正常工作的问题。这种情况下，MS专有属性 <code>zoom</code> 就可以考虑使用了。</p>
<pre class=code>&lt;!--[if lt IE 7]&gt;&lt;style&gt;
/* IE 6 + IE5.5 + IE5.0 所用样式*/
.gainlayout { height: 0; }
&lt;/style&gt;&lt;![endif]--&gt;
&lt;!--[if IE 7]&gt;&lt;style&gt;
.gainlayout { zoom: 1;}
/* 或者其他任何以后可能需要的东西 */
&lt;/style&gt;&lt;![endif]--&gt;</pre>
<ul>
    <li><code>zoom: 1;</code> 可以让 IE5.5+ 的任何元素(包括内联元素)获得 layout，但是在 IE5.0 中无效。
    <li>没有其他附带效果(内联元素会变成 inline-block，这个当然)。
    <li>如果需要通过验证，应该用条件注释将 <code>zoom</code> 隐藏起来。 </li>
</ul>
<p>　　其实当我们考虑到&#8220;向后兼容&#8221;时是很自相矛盾的，我们强烈建议页面设计者回过头看一下自己页面中用的到的明显的或是不明显的&#8220;hacks&#8221;，并用条件注释针对不同浏览器重新处理以保万无一失。</p>
</div>
<h4 id=iemac>关于IE Mac 的小问题</h4>
<p>　　IE Mac 和 windows 下的 IE 是完全不同的两个东西，它们各自拥有自己的渲染引擎，IE Mac 就全然不知&#8220;hasLayout&#8221;(或contenteditable)所谓何物。相比之下 IE Mac 的渲染引擎要更标准兼容一点，比如 <code>height</code> 就是被当作 <code>height</code> 处理，没有别的效果。因此针对&#8220;hasLayout&#8221;的 hacks 和别的解决方法(特别是通过使用 <code>height</code> 或 <code>width</code> 属性的)往往对 IE Mac 来说是有害的，所以需要对其隐藏。更多的关于 IE Mac 相关的问题可以在 <a title="CSS problems in IE Mac" href="http://www.l-c-n.com/IE5tests/"><u><font color=#0066cc>IE Mac, bugs and oddities pages</font></u></a> 找到。</p>
<h4 id=docu>MSDN 文档</h4>
<p>　　MSDN 中涉及到 hasLayout 这个 MS 属性的地方寥寥无几，而具体解释 layout 和 IE 渲染模型之间关系的则少之又少。</p>
<p>　　在IE4的时候，除了未经绝对定位也未指定宽高的内联元素，几乎所有元素都有某种 layout(<a title="查看MSDN中的 measurement and location overview" href="http://msdn.microsoft.com/workshop/author/css/overview/measurementandlocation.asp"><u><font color=#0066cc>MSDN</font></u></a>)。在这种早期的layout概念中，像 <code>border, margin, padding</code> 这些属性被称作&#8220;layout属性&#8221;，它们是不能应用到一个简单的内联元素上的。换句话说，&#8220;拥有layout&#8221;就可以粗略理解成：&#8220;可以拥有这几个属性&#8221;。</p>
<p>　　MSDN 上仍然使用 layout 属性这种说法， 只是含义变了，它们和拥有 layout 的元素已经没有什么关系了。在 IE5.5 中方才引入了 MS 的这个专有属性 <a title=查看MSDN中的属性描述 href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/haslayout.asp"><code><u><font color=#0066cc>hasLayout</font></u></code></a>，也只是某种内部的标志位而已。</p>
<p>　　在 IE5.5 中，MSHTML Editing Platform(即可以通过设置<code>&lt;body contenteditable=true&gt;</code>来允许用户实时编辑、拖动 layout 元素以及调整其尺寸等)的文档中描述了三个和 layout 相关的重要特性：</p>
<div class=quote>
<blockquote title="来自MSDN规范： Editing Platform" cite=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmshtml/html/mshtmleditplatf.asp>
<p>　　如果一个 layout 元素中有内容，内容的排版布局将由它的边界矩形框决定。</p>
<p>　　拥有 layout 的意思基本上就是表示某元素是一个矩形。</p>
<p>　　从内部来说，拥有 layout 意思就是一个元素将自己负责绘制其内部内容。</p>
</blockquote>
<p class=blockquotesource>(<a title=查看MSDN规范 href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmshtml/html/mshtmleditplatf.asp"><u><font color=#0066cc>Editing Platform</font></u></a>)</p>
</div>
<p>　　和 layout 自身相关的内部工作机制直到2005年8月才有相应文档描述，当时由于 <a title="meet the WaSP" href="http://www.webstandards.org/"><u><font color=#0066cc>The Web Standards Project</font></u></a> 和微软的特别工作小组的原因，Markus Mielke [MSFT] 打开了深入讨论的大门：</p>
<div class=quote>
<blockquote title="来自MSDN规范：Filters and Transitions" cite=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/cols/dnexpie/expie20050831.asp>
<p>　　一般来说，在 Internet Explorer 的 DHTML 引擎中，元素是不对自己的位置安排负责的。虽然一个 div 或者一个 p 元素都在源码中有一个位置，在文档流有一个位置，但是它们的内容却是由它们最近的一个 layout 祖先(经常是 body)控制安排的。这些元素依赖它们祖先的 layout 来为他们处理诸如决定大小尺寸和测量信息等诸多繁重的工作。</p>
</blockquote>
<p class=blockquotesource>(<a title=查看MSDN中的文章 href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/cols/dnexpie/expie20050831.asp"><u><font color=#0066cc>HasLayout概述</font></u></a>)</p>
</div>
<h4 id=interpr>分析</h4>
<p>　　我们的分析试图解释在已知案例下发生了什么事情，这种分析也应该可以作为未知案例下的指导。但我们这种试图利用种种测试案例投石探路的黑箱测试方法，是注定无法消除黑箱的神秘感的——我们无法回答&#8220;为什么&#8221;的问题。我们只能去尝试了解整个&#8220;hasLayout&#8221;模式的工作框架，以及它会怎样影响网页文档的渲染。因此，最终我们只能提供一些<em>指导方针</em>(而且只能是指导方针，而不是绝对的解决方案)。</p>
<p>　　我们认为他们所指的是一个小窗体。一个 layout 元素的内部内容是完全独立的，而且也无法影响其边界外的任何内容。</p>
<p>　　而 MS 属性 layout 只是某种标志位：一旦它被设定，这个元素就会拥有其特殊的 layout&#8220;特性&#8221;，这包括体现在其自身以及其非 layout 孩子身上的浮动、清除浮动、层叠、计数等等诸多方面的特殊性能。</p>
<p>　　这种独立性也许正可以解释为什么 layout 元素通常比较稳定，而且它们可以让某些 bug 消失。这种情况的代价有二，一是偏离了标准，二是它没有考虑到今后可能因此出现的 bug 和问题。</p>
<p>　　MS 的&#8220;页面&#8221;模式，从符号学角度考虑，可以看做是由很多互不相关的小的区块构成，而 HTML 和 W3C 的模式则认为&#8220;页面&#8221;模式应该是叙述完备的，故事性的相关信息区块构成的。</p>
<h4 id=rev>各种情况的详细说明</h4>
<div class=alpha>
<h5 id=clear>清除浮动和自动扩展适应高度</h5>
<p>　　浮动元素会被 layou 元素自动包含。这是很多新手经常遇到的问题：在 IE 下完成的页面到了标准兼容浏览器下所有未清除的浮动元素都伸出了其包含容器之外。</p>
<ul>
    <li><a title="查看Eric Meyer的文章" href="http://www.complexspiral.com/publications/containing-floats"><u><font color=#0066cc>Containing Floats</font></u></a>
    <li><a title=查看PIE上的文章 href="http://positioniseverything.net/easyclearing.html"><u><font color=#0066cc>how to clear floats without structural markup</font></u></a> </li>
</ul>
<p>　　相反的情况：如果确实需要一个浮动元素伸出其包含容器，也就是自动包含不是想要的效果时，该怎么办？你很可能也会遇到这种头疼的问题，下面的深入讨论就是一个例子：</p>
<ul>
    <li><a title=因haslayout触发的多此一举的浮动包含问题 href="http://www.satzansatz.de/cssd/acidicfloat.html"><u><font color=#0066cc>acidic float tests</font></u></a> </li>
</ul>
<p>　　在IE中，一个浮动元素总是&#8220;隶属于&#8221;它的 layout 包含容器。而后面的元素会受这个 layout 包含容器影响而不是这个浮动元素影响。</p>
<p>　　这个特性和IE6的那个自动扩展以适应内部内容宽度的特性，都可以看成是受这个规则影响的：&#8220;由它的边界矩形框决定&#8221;。</p>
<p>　　更糟的问题：<code>clear</code> 无法影响其 layout 包含容器之外的 float 元素。如果依赖这个 bug 在 IE 中布局的页面要转到标准兼容浏览器中，只有全部重做。</p>
<p>　　更多相关信息查看本文 &#8220;<a href="http://www.sharkui.com/articles/article.php?id=38#engineer"><u><font color=#0066cc>和 CSS 规范类似的地方</font></u></a>&#8221; 这一部分。</p>
<h5 id=nextfloat>浮动元素旁边的元素</h5>
<p>　　当一个块级元素紧跟在一个左浮动元素之后时，其中的文字内容应该沿着浮动元素的右边顺序排列并会滑到浮动元素下方。但是如果这个块级元素有 layout，比如由于某种原因被设置了宽度，那么这个 layout 元素就会表现为一个矩形，其中文字不会滑向浮动元素下方。其宽度也被错误计算——从浮动元素的右边开始算起了，所以如果给它设置 <code>width: 100%</code> 将会导致显示时这个 block 的宽度加上了浮动元素的宽度而出现横向滚动条。这种表现就和规范中描述的相去甚远了。</p>
<p>　　与此类似，和浮动元素相邻的相对定位元素，它的位置偏移量应该参照的是父元素的补白(padding)边缘(例如，<code>left: 0;</code> 应该将一个相对定位元素叠放于它前面的浮动元素之上)。在IE中，偏移量 <code>left: value;</code> 是从浮动元素的右边距(margin)边缘开始算起的，这会因浮动元素所占的宽度变化导致水平方向的错位(一个解决方法是用 <code>margin-left</code> 代替，但是也要注意如使用百分值时会有一些怪异问题)。</p>
<p>　　根据规范所述，浮动元素应该与其后的盒子<em>交织</em>在一起。而对于没有交叉的二维空间中的矩形而言这是无法实现的。</p>
<p>　　可以(再次)访问下面这个页面：</p>
<ul>
    <li><a title=查看PIE上的文章 href="http://positioniseverything.net/explorer/threepxtest.html"><u><font color=#0066cc>three pixel text-jog</font></u></a> </li>
</ul>
<p>　　我们可以看到跟在一个浮动元素后的 layout 元素不会显示这个3px间隙的 bug，因为浮动元素外围的3px硬边无法影响一个 layout 元素的内部内容，所以这个硬边将整个 layout 元素右推了3px。好比一个防护罩，layout 可以保护其内部内容不受影响，但是浮动元素的力量却将整个防护罩推了开来。</p>
<p>　　更多相关信息查看本文 &#8220;<a href="http://www.sharkui.com/articles/article.php?id=38#engineer"><u><font color=#0066cc>和 CSS 规范类似的地方</font></u></a>&#8221; 这一部分</p>
<h5 id=list>列表</h5>
<p>　　无论是列表本身(<code>ol, ul</code>) 还是单个的列表元素(<code>li</code>)，拥有 layout 后都会影响列表的表现。不同版本 IE 的表现又有不同。最明显的效果就体现在列表符号上(如果你的列表自定义了列表符号则不会受这个问题影响)。这些符号很可能是通过某种内部机制附到列表元素上的(通常是附着在它们外面)。不幸的是，由于是通过&#8220;内部机制&#8221;添加的，我们无法访问它们也无法修正它们的错误表现。</p>
<p>　　最明显的效果有：</p>
<ul>
    <li>列表获得 layout 后，列表符号会消失或者被放置在不同的或者错误的位置。 </li>
</ul>
<p>　　有时它们又可以通过改变列表元素的边距而重新出现。这看起来似乎是以下事实导致的结果：layout 元素会试图裁掉超出其边界的内部内容。</p>
<ul>
    <li>列表元素获得 layout 之后，会有和上面一样的问题出现，更多参考 (<a title="查看Bruno Fassino的测试样例" href="http://www.brunildo.org/test/IEWlispace.php"><u><font color=#0066cc>extra vertical space between list items</font></u></a>) </li>
</ul>
<p>　　进一步又有一个问题就是(在有序列表中)任何具有 layout 的列表元素似乎都有自己独立的计数器。比如我们有一个含五个列表元素的有序列表，只有第三个列表元素有 layout。我们会看到这样：</p>
<p>　　1&#8230; 2&#8230; 1&#8230; 4&#8230; 5&#8230;</p>
<p>　　此外，如果一个有 layout 的列表元素跨行显示时，列表符号会底部对齐(而不是按照预料的顶部对齐)。</p>
<p>　　以上某些问题还是无法解决的，所以如果需要列表符号的时候最好避免让列表和列表元素获得 layout。如果需要限定尺寸，最好给别的元素设定尺寸，比如给整个列表外面套一个元素并设定它的宽度，又或者比如给每个列表元素中的内容设定高度等等。</p>
<p>　　另一个IE中列表的常见问题出现在当某个 <code>li</code> 中的内容是一个 <code>display: block</code> 的锚点(anchor)时。在这种情况下，列表元素之间的空格将不会被忽略而且通常会显示成额外的一行夹在每个 <code>li</code> 之间。一种避免这种竖直方向多余空白的解决方法是赋予这些锚点 layout。这样还有一个好处就是可以让整个锚点的矩形区域都可以响应鼠标点击。</p>
<h5 id=tab>表格</h5>
<p>　　<code>table</code> 总是有 layout 的，它总表现为一个已定义宽度的对象。在IE6中，<a title=查看MSDN href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/tablelayout.asp"><code><u><font color=#0066cc>table-layout: fixed</font></u></code></a> 通常和一个宽度设为100%的表格相同，同时这也会带来很多问题(一些计算方面的错误)。另外在IE5.5和IE6的quirks模式下<a title="查看 Philippe Wittenbergh 的文章" href="http://dev.l-c-n.com/tables_2/"><u><font color=#0066cc>还有一些别的需要注意的情况</font></u></a>。</p>
<h5 id=rp>相对定位元素(r.p.)</h5>
<p>　　注意，由于 <code>position: relative</code> 并不触发 hasLayout，所以很多诸如内容消失或错位的渲染错误就会因此而起。这些现象可能会在刷新页面、调整窗口大小、滚动页面、选中内容等情况下出现。原因是 IE 在据这个属性对元素做偏移处理时，却似乎忘了发出信号让其 layout 孩子元素进行&#8220;重绘&#8221;(而如果是一个layout元素，那么在其重绘事件的信号链中，这个传给其孩子的信号是会正常发出的)。</p>
<ul>
    <li><a title="查看 Ingo Chao 的文章" href="http://www.satzansatz.de/cssd/rpfloat.html"><u><font color=#0066cc>r.p. parent and disappearing floated child</font></u></a>
    <li><a title="查看 PIE 上的文章" href="http://positioniseverything.net/explorer/ie-listbug.html"><u><font color=#0066cc>disappearing list-background bug</font></u></a> </li>
</ul>
<p>　　以上是一些相关问题的描述。作为经验之谈，相对定位一个元素时最好给予其 layout。再有，我们也需要检查拥有这种结构的父元素是否也需要 layout 或者<code>position: relative</code>亦或二者都需要，如果涉及到浮动元素这点就十分重要。</p>
<h5 id=cb>绝对定位元素(a.p.)：<br><span>包含区块，什么是包含区块？</span></h5>
<p>　　理解 CSS 的包含区块概念很重要，它回答了绝对定位元素是相对哪里定位的问题：包含区块决定了偏移起点，包含区块定义了百分比长度的计算参考。</p>
<p>　　对于绝对定位元素，包含区块是由其最近的定位祖先决定的。如果其祖先都没有被定位，那么就使用初始包含区块 <code>html</code>。</p>
<p>　　通常情况下我们会用 <code>position: relative</code> 来设定任意包含区块。这就是说，我们可以让一个绝对定位元素所参考的原点和长度等不依赖于元素的排列顺序，这可以满足诸如&#8220;内容优先&#8221;这种可访问性概念的需要，也可以给复杂的浮动布局带来方便。</p>
<p>　　但是由于 layout 概念的存在，这种设计理念的效果在IE中就要打个问号了。因为在IE中绝对定位的元素是相对于其最近的 <em>layout 定位</em>祖先而做偏移的，而百分比的尺寸却是参考这个 layout 定位祖先的下一个 <em>layout</em> 祖先计算的。注意这里的小差别，还有刚才提到 <code>position: relative</code> 是不会触发 hasLayout 的。</p>
<p>　　假设一个无 layout 的父元素被相对定位了——我们就得给它赋予 layout 才能使偏移量起作用：</p>
<ul>
    <li><a title="查看 PIE 上的文章" href="http://www.positioniseverything.net/abs_relbugs.html"><u><font color=#0066cc>Absolutely Buggy II</font></u></a> </li>
</ul>
<p>　　假设一个未定位的父元素需要特定尺寸，而且页面设计是基于百分比宽度的——我们就可以放弃这个想法了，因为浏览器支持不佳：</p>
<ul>
    <li><a title="查看 Ingo Chao 的测试样例" href="http://www.satzansatz.de/cssd/tmp/apboxpercentagewidth.html"><u><font color=#0066cc>absolutely positioned element and percentage width</font></u></a> </li>
</ul>
<h5 id=filter>滤镜</h5>
<p>　　MS专有的滤镜属性 <a title="查看 MSDN 规范" href="http://msdn.microsoft.com/workshop/author/filter/filters.asp"><u><font color=#0066cc>filter</font></u></a> 是只适用于 layout 元素的。有些滤镜扩展了对象的边界。它们会显示出自身特有的<a title="查看 Ingo Chao 如何试图使它们正常工作" href="http://www.satzansatz.de/cssd/tmp/alphatransparency.html"><u><font color=#0066cc>缺陷</font></u></a>。</p>
<h5 id=reflow>对已渲染元素的重排(re-flow)</h5>
<p>　　当所有元素都已渲染完成时，如果有一个因鼠标经过而引起的变化产生(比如某个链接的 <code>background</code> 有变化)，IE会对其 layout 包含区块进行重排。有时一些元素就会因此被排到了新的位置，因为当这个鼠标经过发生时，IE已经知道了所有相关元素的宽度、偏移量等数据了。这在文档首次载入时则不会发生，那时由于自动扩张的特性，宽度还无法确定。这种情况会导致在鼠标经过时页面出现跳变。</p>
<ul>
    <li><a title='查看 Ingo Chao 关于"伪CSS"的相关文章' href="http://www.satzansatz.de/cssd/pseudocss.html#hoverjump"><u><font color=#0066cc>Jump on :hover</font></u></a>
    <li><a title="查看 PIE 上文章" href="http://www.positioniseverything.net/explorer/percentages.html"><u><font color=#0066cc>quirky percentages: the reflow</font></u></a> </li>
</ul>
<p>　　这些和重排问题相关的 bug 会给百分比边距和补白使用较多的流动布局带来不少麻烦。</p>
<h5 id=bgorigin>背景原点</h5>
<p>　　MS专有的这个 hasLayout 还会影响背景的定位和扩展。比如，根据 <a title="查看 W3C 规范" href="http://www.w3.org/TR/CSS21/colors.html#q2"><u><font color=#0066cc>CSS 规范</font></u></a>，<code>background-position: 0 0</code> 应该指元素的&#8220;补白边缘(padding edge)&#8221;。而在 IE/Win 下，如果 <code>hasLayout = false</code> 则指的是&#8220;边框边缘(border edge)&#8221;，当 <code>hasLayout=true</code> 时指的才是补白边缘：</p>
<ul>
    <li><a title="查看 Bruno Fassino 的文章" href="http://www.brunildo.org/test/BackgroundBorderLayout.html"><u><font color=#0066cc>Background, Border, hasLayout</font></u></a> </li>
</ul>
<h5 id=uncollapse>边距重叠</h5>
<p>　　<code>hasLayout</code> 会影响一个盒子和其子孙的边距重叠。根据规范，一个盒子如果没有上补白和上边框，那么它的上边距应该和其文档流中的第一个孩子元素的上边距重叠：</p>
<ul>
    <li><a title="查看 W3C 规范" href="http://www.w3.org/TR/CSS21/box.html#collapsing-margins"><u><font color=#0066cc>Collapsing Margins</font></u></a>
    <li><a title="查看 Eric Meyer 的文章" href="http://complexspiral.com/publications/uncollapsing-margins"><u><font color=#0066cc>Uncollapsing Margins</font></u></a> </li>
</ul>
<p>　　在 IE/Win 中如果这个盒子有 layout 那么这种现象就不会发生了：似乎拥有 layout 会阻止其孩子的边距伸出包含容器之外。此外当 <code>hasLayout = true </code>时，不论包含容器还是孩子元素，都会有边距计算错误的问题出现。</p>
<ul>
    <li><a title="查看 Bruno Fassino 的文章" href="http://www.brunildo.org/test/IEMarginCollapseLayout.html"><u><font color=#0066cc>Margin collapsing and hasLayout</font></u></a> </li>
</ul>
<h5 id=link>块级别的链接</h5>
<p>　　hasLayout 会影响一个块级别链接的鼠标响应区域(可点击区域)。通常 hasLayout = false 时只有文字覆盖区域才能响应。而 hasLayout = true 则整个块状区域都可响应。添加了 onclick/onmouseover 等事件的任意块级元素也有同样的现象。</p>
<ul>
    <li><a title="查看 Bruno Fassino 的文章" href="http://www.brunildo.org/test/IEABlock1.html"><u><font color=#0066cc>Block anchors and hasLayout</font></u></a> </li>
</ul>
<h5 id=inpage>在页面内使用键盘浏览：探索中</h5>
<p>　　当使用 tab 在页面中浏览时，如果进入了一个页内链接(in-page link)，那么接下来再按的 <kbd>tab</kbd> 键就不会正常继续了：</p>
<ul>
    <li><a title="查看 Jim Thatcher 的文章" href="http://jimthatcher.com/news.htm#haslayout"><u><font color=#0066cc>hasLayout Property Characterizes IE6 Bug</font></u></a>
    <li><a title="查看 Gez Lemon 的文章" href="http://juicystudio.com/article/ie-keyboard-navigation.php"><u><font color=#0066cc>Keyboard Navigation and Internet Explorer</font></u></a> </li>
</ul>
<p>　　<kbd>tab</kbd> 键会把用户带到(这通常是错误的)其最近的 layout 祖先中的第一个目标(如果这个祖先是由 <code>table</code>， <code>div</code>， <code>span</code> 或某些别的标签构成)。</p>
</div>
<h4 id=stack>堆叠，分层和 layout </h4>
<p>　　IE/Win 中似乎有两种分层和堆叠顺序：</p>
<ul>
    <li>一种是(伪)试图采用CSS的模式：<a title="查看 Aleksandar Vacic 的系列文章" href="http://www.aplus.co.yu/css/z-pos/"><u><font color=#0066cc>Effect of z-index value to RP and AP blocks</font></u></a>
    <li>还有一种是由&#8220;hasLayout&#8221;及其孪生兄弟&#8220;contenteditable&#8221;的行为产生的堆叠顺序。正如在上面相对定位的例子中展现的那样，在 layout 影响下的堆叠现象就好像 Harry Houdini (译者注：魔术师，以纸牌魔术成名)的拿手戏法儿一样。 </li>
</ul>
<p>　　两种堆叠模式虽互不相容，但却共存于IE的渲染引擎中。经验之谈：调试的时候，两种情况都要考虑到。我们可能会有规律地在下拉菜单或者类似的复杂菜单中看到相关问题，因为它们往往牵涉到堆叠，定位和浮动等诸多令人头疼的问题。给那些 z-index 定位的元素 layout 是一种可能的修正方法，不过也不限于此，这里只是提醒一下。</p>
<h4 id=contenteditable>混乱的 contenteditable</h4>
<p>　　如果给一个 HTML 标签设定 <code>contenteditable=true</code> 属性，比如<code>&lt;body contenteditable=true&gt;</code>，将会允许对该元素以及其 layout 子元素进行实时的编辑、拖动改变尺寸等操作。你可以把这属性用在浮动元素或者一个有序列表中的 layout 列表元素上看看效果。</p>
<p>　　为了对元素进行操作(编辑它们)，&#8220;contenteditable&#8221;和&#8220;hasLayout&#8221;为那些 <code>hasLayout</code> 返回 <code>true</code> 的元素引入了一套单独的堆叠顺序。</p>
<p>　　<a title="查看 MSDN 规范" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmshtml/html/mshtmleditplatf.asp"><u><font color=#0066cc>Editing Platform</font></u></a> 继承了 layout 概念，对 layout 的误解多是因 contenteditable 而起即可作为证明(那些某种程度上集成了IE编辑引擎的应用软件多暗含着对layout概念的某种强制向后兼容性)。</p>
<ul>
    <li><a title="查看 Anne van Kesteren 的blog条目" href="http://annevankesteren.nl/2005/07/more-contenteditable"><u><font color=#0066cc>More on contenteditable</font></u></a> </li>
</ul>
<h4 id=engineer>和 CSS 规范类似的地方</h4>
<p>　　你的 MSIE 页面在别的浏览器中一团糟？我们可没必要让这种事情发生。如果使用恰当，任何好的浏览器都能摆平 MSIE 的页面——只要你使用一些正确的 CSS。</p>
<p>　　利用 <code>hasLayout</code> 和&#8220;<a title="CSS 2.1 规范 - 9.4.1" href="http://www.w3.org/TR/CSS21/visuren.html#q15"><u><font color=#0066cc>新的块级格式内容</font></u></a>&#8221;之间的<em>细微</em>相似之处，我们可以有几种方法在标准兼容浏览器中重新实现 <code>hasLayout</code> 的&#8220;<a title="Visual formatting model details - 10.6.7" href="http://www.w3.org/TR/CSS21/visudet.html#root-height"><u><font color=#0066cc>包含浮动元素</font></u></a>&#8221;效果，和一些&#8220;<a title="Visual formatting model - 9.5" href="http://www.w3.org/TR/CSS21/visuren.html#floats"><u><font color=#0066cc>浮动元素旁边的元素</font></u></a>&#8221;所特有的效果。</p>
<ul>
    <li><a title="查看 Georg S?rtun 的系列文章" href="http://www.gunlaug.no/contents/wd_example_01.html"><u><font color=#0066cc>Reverse engineering series</font></u></a>
    <li><a title="查看 Philippe Wittenbergh 模拟的 hasLayout：overflow，display:table，新的块级格式内容" href="http://dev.l-c-n.com/IEW/simulations.php"><u><font color=#0066cc>Simulations</font></u></a> </li>
</ul>
<h4 id=quirk>Quirks 模式</h4>
<p>　　某些 <a title="Henri Sivonen: Activating the Right Layout Mode Using the Doctype Declaration" href="http://hsivonen.iki.fi/doctype/"><u><font color=#0066cc>doctype</font></u></a>，或者 <code>&lt;xml&gt;</code> 声明，在 IE6 中会触发&#8220;quirks模式&#8221;或曰向后兼容模式。在这种模式下，IE6 就像 IE5.5，并且和它老弟拥有一样的bug，一样的问题和一样的行为。</p>
<p>　　而对于IE7，<code>&lt;xml&gt;</code> 声明不会再改变渲染模式了；要触发 quirks 模式，我们不得不插入一个注释才行。(IE7 的 quirks 模式和 IE6 的 quirks 模式是否一样还有待验证)</p>
<pre class=code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- ... 让 IE7 运行在 quirks 模式 --&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;</pre>
<h4 id=conclusion>Layout — 结论</h4>
<p>　　整个 layout 概念和一些基本 CSS 概念是不兼容的，即包含，排列，浮动，定位和层叠等。</p>
<p>　　由于页面中元素或有或没有 layout，会导致 IE/Win 的行为和 CSS 规范相违背。</p>
<h4 id=bottomline>拥有 layout — 另外一个引擎？</h4>
<div class=quote>
<blockquote title="Dean Edward 关于IE7的一些说明" cite=http://dean.edwards.name/IE7/notes/#layout>
<p>　　IE 的对象模型看起来是文档模型和他们传统的应用程序模型的糅合。我之所以提到这点是因为它对于理解IE如何渲染页面很重要。而从文档模型切换到应用程序模型的开关就是给一个元素&#8220;layout&#8221;。</p>
</blockquote>
<p class=blockquotesource>(<a title=查看关于IE7的一些说明 href="http://dean.edwards.name/IE7/notes/#layout"><u><font color=#0066cc>Dean Edwards</font></u></a>)</p>
</div>
<p>　　有时候要解释清楚某种行为是不可能的：就比如 hasLayout，会根据它的状态选择两种不同渲染引擎的一种使用，而且每一种都有其自己的 bug 和怪异之处。</p>
<h4 id=absurd>不可消除的 bug</h4>
<div class=quote>
<blockquote title="Molly 说到..." cite=http://www.gunlaug.no/contents/molly_1_15.html>
<p>　　软件 bug 是由于在制作过程中对完整性和逻辑问题考虑不周等人为错误而导致的。这是人类的固有缺陷，目前还没有什么好的解决方法。</p>
<p>　　同样由于这种缺陷，任何试图不重写软件而修复 bug 的做法，都将会不可避免的导致软件中出现更复杂的bug。</p>
<p>　　所有依赖别的软件的软件——当然包括依赖操作系统，也会同样依赖他们的 bug。于是我们会从所有关联的软件中得到一连串的 bug，这也更说明找到一个无 bug 软件是几乎不可能的。</p>
</blockquote>
<p class=blockquotesource>(<a title="Molly 说到..." href="http://www.gunlaug.no/contents/molly_1_15.html"><u><font color=#0066cc>Molly, the cat?</font></u></a>)</p>
</div>
<p>　　　　本文创建于2005年6月30日，最后一次修改于2006年4月2日。</p>
<dl id=editors>
<dt>编者：
<dd><a title="Holly on PIE" href="http://positioniseverything.net/"><u><font color=#0066cc>Holly Bergevin</font></u></a>
<dd><a title="Satzansatz — CSS" href="http://www.satzansatz.de/css.html"><u><font color=#0066cc>Ingo Chao</font></u></a>
<dd><a title="Brunildo — CSS" href="http://www.brunildo.org/"><u><font color=#0066cc>Bruno Fassino</font></u></a>
<dd><a title="Big John on PIE" href="http://positioniseverything.net/"><u><font color=#0066cc>John Gallant</font></u></a>
<dd><a title="Web-carpenter and farm assistent" href="http://www.gunlaug.no/"><u><font color=#0066cc>Georg S?rtun</font></u></a>
<dd><a title="Empty Spaces" href="http://emps.l-c-n.com/"><u><font color=#0066cc>Philippe Wittenbergh</font></u></a> </dd></dl>
<dl id=support>
<dt>特别致谢给予此项目支持的：
<dd><a title="" href="http://dean.edwards.name/"><u><font color=#0066cc>Dean Edwards</font></u></a>, and <a title="bug hunter" href="http://www.gunlaug.no/contents/molly_1.html"><u><font color=#0066cc>Molly ?the cat?</font></u></a> </dd></dl>
<dl id=translation>
<dt>各种语言版本：
<dd><a href="http://www.satzansatz.de/cssd/onhavinglayout.html"><u><font color=#0066cc>Original(English)</font></u></a>
<dd><a title="" href="http://www.maujor.com/tutorial/haslayout.php"><u><font color=#0066cc>Brazilian Portuguese</font></u></a> by <a title="" href="http://www.maujor.com/"><u><font color=#0066cc>Mauricio Samy Silva</font></u></a>
<dd><a href="http://old9.blogsome.com/2006/04/11/onhavinglayout/"><u><font color=#0066cc>中文版本</font></u></a> by <a href="http://old9.blogsome.com/"><u><font color=#0066cc>old9</font></u></a> </dd></dl>
<dl id=discussion>
<dt>相关讨论：
<dd><a title="" href="http://dean.edwards.name/weblog/2005/06/layout/"><u><font color=#0066cc>dean.edwards.name/weblog/</font></u></a>
<dt>联系作者：
<dd><del class=spam>spam.</del>layout@satzansatz.de </dd></dl>
<dl id=licence>
<dt>版权说明：
<dd>本文基于<a href="http://creativecommons.org/licenses/by-nc-sa/2.0/" rel=license><u><font color=#0066cc>创作共用协议</font></u></a>发布。 </dd></dl>
<img src ="http://www.blogjava.net/Vencent/aggbug/117308.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2007-05-14 12:53 <a href="http://www.blogjava.net/Vencent/articles/117308.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Web  显示层技术评估  </title><link>http://www.blogjava.net/Vencent/articles/58380.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 15 Jul 2006 17:46:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/58380.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/58380.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/58380.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/58380.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/58380.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Web				显示层技术评估								名词界定								显示层的意思就是				PresentationLayer				，也翻译成表现层、展现层、展示层。								本文讨论的范围只包括采用				HTMLTemplate				的显示层技术，不包括				Echo				，				GWT(google ...&nbsp;&nbsp;<a href='http://www.blogjava.net/Vencent/articles/58380.html'>阅读全文</a><img src ="http://www.blogjava.net/Vencent/aggbug/58380.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-07-16 01:46 <a href="http://www.blogjava.net/Vencent/articles/58380.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>javascript事件综合</title><link>http://www.blogjava.net/Vencent/articles/37020.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Thu, 23 Mar 2006 04:25:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/37020.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/37020.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/37020.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/37020.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/37020.html</trackback:ping><description><![CDATA[javascript事件查询综合 <br /><span id="ArticleContent1_ArticleContent1_lblContent"><p> </p><p>javascript事件查询综合<br />click()   对象.click()   使对象被点击。<br />closed   对象.closed   对象窗口是否已关闭true/false<br />clearTimeout(对象) 清除已设置的setTimeout对象<br />clearInterval(对象) 清除已设置的setInterval对象<br />confirm("提示信息") 弹出确认框，确定返回true取消返回false<br />cursor:样式  更改鼠标样式 hand crosshair text wait help default auto e/s/w/n-resize</p><p>event.clientX  返回最后一次点击鼠标X坐标值；<br />event.clientY  返回最后一次点击鼠标Y坐标值；<br />event.offsetX  返回当前鼠标悬停X坐标值<br />event.offsetY  返回当前鼠标悬停Y坐标值</p><p>document.write(document.lastModified)  网页最后一次更新时间<br />document.ondblclick=x  当双击鼠标产生事件<br />document.onmousedown=x  单击鼠标键产生事件</p><p>document.body.scrollTop; 返回和设置当前竖向滚动条的坐标值，须与函数配合,<br />document.body.scrollLeft; 返回和设置当前横向滚动务的坐标值，须与函数配合，<br />document.title  document.title="message"; 当前窗口的标题栏文字<br />document.bgcolor document.bgcolor="颜色值"; 改变窗口背景颜色<br />document.Fgcolor document.Fgcolor="颜色值"; 改变正文颜色<br />document.linkcolor document.linkcolor="颜色值"; 改变超联接颜色<br />document.alinkcolor document.alinkcolor="颜色值"; 改变正点击联接的颜色<br />document.VlinkColor document.VlinkColor="颜色值"; 改变已访问联接的颜色<br />document.forms.length 返回当前页form表单数<br />document.anchors.length 返回当前页锚的数量<br />document.links.length 返回当前页联接的数量<br />document.onmousedown=x 单击鼠标触发事件<br />document.ondblclick=x 双击鼠标触发事件<br />defaultStatus  window.status=defaultStatus; 将状态栏设置默认显示</p><p>function  function xx(){...}  定义函数<br />isNumeric               判断是否是数字<br />innerHTML  xx=对象.innerHTML  输入某对象标签中的html源代码<br />innerText  divid.innerText=xx  将以div定位以id命名的对象值设为XX</p><p>location.reload(); 使本页刷新，target可等于一个刷新的网页</p><p>Math.random()           随机涵数,只能是0到1之间的数,如果要得到其它数,可以为*10,再取整<br />Math.floor(number) 将对象number转为整数，舍取所有小数<br />Math.min(1,2)  返回1,2哪个小<br />Math.max(1,2)  返回1,2哪个大</p><p>navigator.appName 返回当前浏览器名称<br />navigator.appVersion 返回当前浏览器版本号<br />navigator.appCodeName 返回当前浏览器代码名字<br />navigator.userAgent 返回当前浏览器用户代标志</p><p>onsubmit  onsubmit="return(xx())"  使用函数返回值<br />opener   opener.document.对象  控制原打开窗体对象</p><p>prompt   xx=window.prompt("提示信息","预定值"); 输入语句<br />parent   parent.框架名.对象 控制框架页面</p><p>return   return false   返回值<br />random   随机参数（0至1之间）<br />reset()   form.reset();   使form表单内的数据重置</p><p>split("")  string.split("")  将string对象字符以逗号隔开<br />submit()  form对象.submit()  使form对象提交数据</p><p>String对象的  charAt(x)对象 反回指定对象的第多少位的字母<br />       lastIndexOf("string") 从右到左询找指定字符，没有返回-1<br />       indexOf("string") 从左到右询找指定字符，没有返回-1<br />       LowerCase()  将对象全部转为小写 <br />       UpperCase()  将对象全部转为大写<br />substring(0,5)  string.substring(x,x)  返回对象中从0到5的字符<br />setTimeout("function",time) 设置一个超时对象<br />setInterval("function",time) 设置一个超时对象</p><p>toLocaleString() x.toLocaleString()  从x时间对象中获取时间，以字符串型式存在<br />typeof(变量名)   检查变量的类型，值有：String,Boolean,Object,Function,Underfined</p><p>window.event.button==1/2/3 鼠标键左键等于1右键等于2两个键一起按为3<br />window.screen.availWidth 返回当前屏幕宽度(空白空间)<br />window.screen.availHeight 返回当前屏幕高度(空白空间)<br />window.screen.width  返回当前屏幕宽度(分辨率值)<br />window.screen.height  返回当前屏幕高度(分辨率值)<br />window.document.body.offsetHeight; 返回当前网页高度<br />window.document.body.offsetWidth; 返回当前网页宽度<br />window.resizeTo(0,0)  将窗口设置宽高<br />window.moveTo(0,0)  将窗口移到某位置<br />window.focus()  使当前窗口获得焦点<br />window.scroll(x,y) 窗口滚动条坐标，y控制上下移动，须与函数配合<br />window.open()  window.open("地址","名称","属性") <br />   属性:toolbar(工具栏),location(地址栏),directions,status(状态栏),<br />  
menubar(菜单栏),scrollbar(滚动条),resizable(改变大小), 
width(宽),height(高),fullscreen(全                                   
屏),scrollbars(全屏时无滚动条无参 数,channelmode(宽屏),left(打开窗口x坐标),top(打开窗口y坐标)<br />                        window.location = 'view-source:' + window.location.href  应用事件查看网页源代码;</p><p><br />a=new Date();  //创建a为一个新的时期对象<br />y=a.getYear(); //y的值为从对象a中获取年份值 两位数年份<br />y1=a.getFullYear(); //获取全年份数 四位数年份<br />m=a.getMonth();  //获取月份值<br />d=a.getDate();  //获取日期值<br />d1=a.getDay();  //获取当前星期值<br />h=a.getHours();  //获取当前小时数<br />m1=a.getMinutes(); //获取当前分钟数<br />s=a.getSeconds(); //获取当前秒钟数</p><p><br />对象.style.fontSize="文字大小";<br />单位：mm/cm/in英寸/pc帕/pt点/px象素/em文字高<br />1in=1.25cm<br />1pc=12pt<br />1pt=1.2px(800*600分辩率下)</p><p>文本字体属性：<br />        fontSize大小<br /> family字体<br /> color颜色<br /> fontStyle风格，取值为normal一般,italic斜体,oblique斜体且加粗<br /> fontWeight加粗,取值为100到900不等,900最粗,light,normal,bold<br /> letterSpacing间距,更改文字间距离,取值为,1pt,10px,1cm<br /> textDecoration:文字修饰;取值,none不修饰,underline下划线,overline上划线<br /> background:文字背景颜色,<br /> backgroundImage:背景图片,取值为图片的插入路径</p><p><br />点击网页正文函数调用触发器：</p><p>1.onClick 当对象被点击<br />2.onLoad 当网页打开,只能书写在body中<br />3.onUnload 当网页关闭或离开时,只能书写在body中<br />4.onmouseover 当鼠标悬于其上时<br />5.onmouseout 当鼠标离开对象时<br />6.onmouseup 当鼠标松开<br />7.onmousedown 当鼠标按下键<br />8.onFocus 当对象获取焦点时<br />9.onSelect 当对象的文本被选中时<br />10.onChange 当对象的内容被改变<br />11.onBlur 当对象失去焦点<br />onsubmit=return(ss())表单调用时返回的值</p><p>直线          border-bottom:1x solid black<br />虚线          border-bottom:1x dotted black<br />点划线        border-bottom:2x dashed black<br />双线          border-bottom:5x double black<br />槽状          border-bottom:1x groove black<br />脊状          border-bottom:1x ridge black</p><p><br />1.边缘高光glow(color=颜色,strength=亮光大小)&lt;br&gt;<br />2.水平翻转fliph() 使对象水平翻转180度&lt;br&gt;<br />3.垂直翻转flipv() 使对象垂直翻转180度&lt;br&gt;<br />4.对象模糊blur(add=true/false direction=方向 strength=强度)<br /> add指定是否按印象画派进行模糊direction模糊方向strength模糊强度<br />5.对象透明alpha(opaction=0-100,finishopacity=0-100,style=0/1/2/3)<br /> opaction对象整体不透明值finishopacity当对象利用了渐透明时该项指定结束透明位置的不透明值style指定透明方式0为整体透明，1为线型透明，2为圆型透明，3为矩形透明<br />6.去除颜色chroma(color=颜色值)使对象中颜色与指定颜色相同区域透明<br />7.建立阴影dropshadow(color=阴影颜色,offx=水平向左偏离像素,offy=水平向下偏离像素)<br />8.去色gray()使对象呈灰度显示<br />9.负片效果invert()使对象呈底片效果<br />10.高光light()使对象呈黑色显示<br />11.遮盖mask(color=颜色)使整个对象以指定颜色进行蒙板一次</p><p>opacity 表透明度水平.0~100,0表全透明,100表完全不透明<br />finishopacity表想要设置的渐变透明效果.0~100.<br />style 表透明区的形状.0表统一形状.1表线形.2表放射形.3表长方形.<br />startx.starty表渐变透明效果的开始时X和Y坐标.<br />finishx,finishy渐变透明效果结束时x,y 的坐标.<br />add有来确定是否在模糊效果中使有原有目标.值为0,1.0表"否",1表"是".<br />direction设置模糊的方向.0度表垂直向上,45度为一个单位.默认值是向左270度.left,right,down,up.<br />strength 只能用整数来确定.代表有多少个像素的宽度将受到模糊影响.默认是5个.<br />color要透明的颜色.<br />offx,offy分别是x,y 方向阴影的偏移量.<br />positive指投影方式.0表透明像素生成阴影.1表只给出不透明像素生成阴影..</p><p>AddAmbient:加入包围的光源.<br />AddCone:加入锥形光源.<br />AddPoint加入点光源<br />Changcolor:改变光的颜色．<br />Changstrength:改变光源的强度．<br />Clear:清除所有的光源．<br />MoveLight:移动光源．</p><p>freq是波纹的频率，在指定在对象上一区需要产生多少个完事的波纹．<br />lightstrength可对于波纹增强光影的效果．显著0~100正整数，正弦波开始位置是0~360度．0表从0度开始，25表从90度开始．<br />strength表振幅大小．</p><p><br />hand                          style="cursor:hand"<br />crosshair                     style="cursor:crosshair"<br />text                          style="cursor:text"<br />wait                          style="cursor:wait"<br />default                       style="cursor:default"                    <br />help                          style="cursor:help"<br />e-resize                      style="cursor:e-resize"<br />ne-resize                     style="cursor:ne-resize"<br />n-resize                      style="cursor:n-resize"<br />nw-resize                     style="cursor:nw-resize"<br />w-resize                      style="cursor:w-resize"<br />s-resize                      style="cursor:s-resize"<br />sw-resize                     style="cursor:sw-resize "<br />se-resize                     style="cursor:se-resize"<br />auto                          style="cursor:auto" </p></span><img src ="http://www.blogjava.net/Vencent/aggbug/37020.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-23 12:25 <a href="http://www.blogjava.net/Vencent/articles/37020.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>判断中文输入--Javascript</title><link>http://www.blogjava.net/Vencent/articles/30716.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Tue, 14 Feb 2006 15:30:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/30716.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/30716.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/30716.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/30716.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/30716.html</trackback:ping><description><![CDATA[				function ischinanese(s){<br>&nbsp;var ret=true;<br>&nbsp;for(var i=0;i&lt;s.length;i++){<br>&nbsp;&nbsp;ret=ret &amp;&amp; (s.charCodeAt(i)&gt;=10000);<br>&nbsp;}<br>&nbsp;return ret;<br>}<img src ="http://www.blogjava.net/Vencent/aggbug/30716.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-02-14 23:30 <a href="http://www.blogjava.net/Vencent/articles/30716.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>prototype1.3.1源代码解读</title><link>http://www.blogjava.net/Vencent/articles/30301.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 11 Feb 2006 14:26:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/30301.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/30301.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/30301.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/30301.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/30301.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 作者：醒来编辑：robbinprototype.js/** * 定义一个全局对象, 属性 Version 在发布的时候会替换为当前版本号 */var Prototype = {  Version: '1.3.1',  // 一个空方法，其后的代码常会用到，先前的版本该方法被定义于 Ajax 类中。  emptyFunction: function() {}}/** * 创建一种类型，注意其属性...&nbsp;&nbsp;<a href='http://www.blogjava.net/Vencent/articles/30301.html'>阅读全文</a><img src ="http://www.blogjava.net/Vencent/aggbug/30301.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-02-11 22:26 <a href="http://www.blogjava.net/Vencent/articles/30301.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>prototype.js开发笔记</title><link>http://www.blogjava.net/Vencent/articles/30300.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 11 Feb 2006 14:25:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/30300.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/30300.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/30300.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/30300.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/30300.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 覆盖版本 1.3.11.&nbsp;Prototype是什么?或许你还没有用过它， prototype.js 是一个由Sam    Stephenson写的JavaScript包。这个构思奇妙编写良好的一段兼容标准的一段代码将承担创造胖客户端， 高交互性WEB应用程序的重担。轻松加入Web    2.0特性。如果你最近体验了这个程序包，你很可能会发现文档并不是它的强项之一。像所有在我之前的...&nbsp;&nbsp;<a href='http://www.blogjava.net/Vencent/articles/30300.html'>阅读全文</a><img src ="http://www.blogjava.net/Vencent/aggbug/30300.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-02-11 22:25 <a href="http://www.blogjava.net/Vencent/articles/30300.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>