On having layout(7)

hasLayout 会影响一个盒子和其子孙的边距重叠。根据规范,一个盒子如果没有上补白和上边框,那么它的上边距应该和其文档流中的第一个孩子元素的上边距重叠:

Uncollapsing Margins

在 IE/Win 中如果这个盒子有 layout 那么这种现象就不会发生了:似乎拥有 layout 会阻止其孩子的边距伸出包含容器之外。此外当 hasLayout = true 时,不论包含容器还是孩子元素,都会有边距计算错误的问题出现。

Margin collapsing and hasLayout 块级别的链接

hasLayout 会影响一个块级别链接的鼠标响应区域(可点击区域)。通常 hasLayout = false 时只有文字覆盖区域才能响应。而 hasLayout = true 则整个块状区域都可响应。添加了 onclick/onmouseover 等事件的任意块级元素也有同样的现象。

Block anchors and hasLayout 在页面内使用键盘浏览:探索中

当使用 tab 在页面中浏览时,如果进入了一个页内链接(in-page link),那么接下来再按的 tab 键就不会正常继续了:

Keyboard Navigation and Internet Explorer

tab 键会把用户带到(这通常是错误的)其最近的 layout 祖先中的第一个目标(如果这个祖先是由 table, div, span 或某些别的标签构成)。

收缩包围(shrink-wrapping)现象

给已经有 width: auto 的元素添加某些属性会导致它们在计算自身宽度时使用一种收缩包围的算法。比如这些属性 float: left|right, position: absolute|fixed, display: table|table-cell|inline-block|inline-table.

这些属性造成的现象在IE/Win中也存在,当然这是只对那些它支持的属性而言。但是当一个应该收缩包围的元素中包含一个拥有“layout”的块级元素时,在绝大多数情况下,这个孩子元素的宽度会尽可能地扩展而与其中包含的内容无关,同时也阻止了父元素的收缩包围现象。

例子一个浮动的纵向导航无序列表并没有收缩包围,因为其中的链接为了消除列表的多余空白bug并扩展可点击区域而拥有了 layout:a {display: block; zoom: 1;}。  

这时收缩包围现象只有在以下情况仍然有效:拥有 layout 的孩子元素同时也被赋予了一个特定宽度,或者这个孩子元素本身也是一个具有收缩包围特性的元素,比如浮动元素。

边缘裁切

通常而言,当一个盒子包含了诸如伸出其边缘的内容这种更复杂的结构时,这个容器就经常需要“hasLayout”来避免一些渲染错误。但使用这种常用方法又会在边界处理时左右为难,因为一个获得“layout”的元素会变成某种的盒子。

内部的内容盒子会被裁切,比如使用负边距向外移动时。

Clipping of negative margined blocks in a hasLayout container

被裁掉的部分当内容盒子触发了“layout”时可以再次出现,但在 IE6 中需要同时拥有 position: relative 才行。IE7 在这方面要略有改观,它不再需要额外的 position: relative 了。

堆叠,分层和 layout

IE/Win 中似乎有两种分层和堆叠顺序:

一种是(伪)试图采用CSS的模式:Effect of z-index value to RP and AP blocks 还有一种是由“hasLayout”及其孪生兄弟“contenteditable”的行为产生的堆叠顺序。正如在上面相对定位的例子中展现的那样,在 layout 影响下的堆叠现象就好像 Harry Houdini (译者注:魔术师,以纸牌魔术成名)的拿手戏法儿一样。

两种堆叠模式虽互不相容,但却共存于IE的渲染引擎中。经验之谈:调试的时候,两种情况都要考虑到。我们可能会有规律地在下拉菜单或者类似的复杂菜单中看到相关问题,因为它们往往牵涉到堆叠,定位和浮动等诸多令人头疼的问题。给那些 z-index 定位的元素 layout 是一种可能的修正方法,不过也不限于此,这里只是提醒一下。

混乱的 contenteditable

如果给一个 HTML 标签设定 contenteditable=true 属性,比如<body contenteditable=true>,将会允许对该元素以及其 layout 子元素进行实时的编辑、拖动改变尺寸等操作。你可以把这属性用在浮动元素或者一个有序列表中的 layout 列表元素上看看效果。

为了对元素进行操作(编辑它们),“contenteditable”和“hasLayout”为那些 hasLayout 返回 true 的元素引入了一套单独的堆叠顺序。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzdfzg.html