分享
 
 
 

CSS学习:On having layout

王朝html/css/js·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

英文原文在此:

http://www.satzansatz.de/cssd/onhavinglayout.htm

文中所有的 layout 这个单词都未作翻译,一来本身这个单词意思就比较多,翻成啥都觉得别扭,二来它也是专有的属性,所以就意会一下吧。水平有限,很多地方都是模模糊糊地意译,发现错误欢迎留言指出。

引用一段来自Dean Edwards的评价:

I recommend that every CSS designer and DOM scripter read this. Understanding “layout” gives a huge insight into lots of other IE bugs and idiosyncrasies.

(Dean Edwards)

4月16日修订的内容:

将quirks模式这一部分单独移动到一篇文章中讲述。

添加:边缘裁切。

添加:收缩包围(shrink-wrapping)现象。

5月17日修订的内容:

重写了了浮动元素旁边的元素这一部分。

部分章节小的修正:属性,有关内联级别元素,CSS hacks。

重新整理了部分章节的语言:定义,数据,问题种种,分析,清除浮动和自动扩展适应高度,绝对定位元素。

On having layout

本文修订中

当前版本:Rev. 7 2006–05–17 修订历史

各种语言版本

目录

介绍

Internet Explorer 中有很多奇怪的渲染问题可以通过赋予其“layout”得到解决。John Gallant 和 Holly Bergevin 把这些问题归类为“尺寸bug(dimensional bugs)”,意思是这些 bug 可以通过赋予相应元素某个宽度或高度解决。这便引出关于“layout”的一个问题:为什么它会改变元素的渲染特性,为什么它会影响到元素之间的关系?这个问题问得很好,但却很难回答。在这篇文章中,我们专注于这个复杂问题会有那些方面的表现,某一方面的具体讨论和范例请参考文中给出的相关链接。

hasLayout — 定义

“Layout”是一个 IE/Win 的私有概念,它决定了一个元素如何显示以及约束其包含的内容、如何与其他元素交互和建立联系、如何响应和传递应用程序事件/用户事件等。

这种渲染特性可以通过某些 CSS 属性被不可逆转地触发。而有些 HTML 元素则默认就具有“layout”。

微软的开发者们认为元素都应该可以拥有一个“属性(property)”(这是面向对象编程中的一个概念),于是他们便使用了 hasLayout,这种渲染特性生效时也就是将 hasLayout 设成了 true 之时。

术语

当我们说一个元素“得到 layout”,或者说一个元素“拥有 layout” 的时候,我们的意思是指它的微软专有属性 hasLayout 为此被设为了 true 。一个“layout元素”可以是一个默认就拥有 layout 的元素或者是一个通过设置某些 CSS 属性得到 layout 的元素。

而“无layout元素”,是指 hasLayout 未被触发的元素,比如一个未设定宽高尺寸的干净 div 元素就可以做为一个“无layout祖先”。

给一个默认没有 layout 的元素赋予 layout 的方法包括设置可触发 hasLayout = true 的 CSS 属性。参考默认 layout 元素以及这些属性列表。没有办法设置 hasLayout = false , 除非把一开始那些触发 hasLayout = true 的 CSS 属性去除。

问题种种

hasLayout 的问题不管新手还是老手,不管设计师或者程序员可能都遇到过。Layout 在显示盒子时有着不同寻常而且难以预料的效果,而且有时甚至会牵连到他们的孩子元素。

一个元素是否具有“layout”可能会引发如下的一些问题:

IE 很多常见的浮动 bug 。

元素本身对一些基本属性的异常处理问题。

容器和其子孙之间的边距重叠(margin collapsing)问题。

使用列表时遇到的诸多问题。

背景图像的定位偏差问题。

使用脚本时遇到的浏览器之间处理不一致的问题。

上面的列表只是列出一个大概,也不完善。下面的文章将尽可能详细彻底的描述有无“layout”所带来的各种问题。

Layout 从何而来

不同于标准属性,也不像某些浏览器的私有 CSS 属性,layout 无法通过某一个 CSS 声明直接设定 。也就是说没有“layout属性”这么一个东西,元素要么本身自动拥有 layout,要么借助一些 CSS 声明悄悄地获得 layout。

默认layout元素

下列元素应该是默认具有 layout 的:

<html>, <body> <table>, <tr>, <th>, <td> <img> <hr> <input>, <select>, <textarea>, <button> <iframe>, <embed>, <object>, <applet> <marquee>

属性

·下列 CSS 属性和取值将会让一个元素获得 layout:

position: absolute

绝对定位元素的包含区块(containing block)就会经常在这一方面出问题。

float: left|right

由于 layout 元素的特性,浮动模型会有很多怪异的表现。

display: inline-block

当一个内联级别的元素需要 layout 的时候往往就要用到它,这也可能也是这个 CSS 属性的唯一效果——让某个元素拥有 layout。“inline-block行为”在IE中是可以实现的,但是非常与众不同: IE/Win: inline-block and hasLayout

width: 除 “auto” 外的任意值

很多人遇到 layout 相关问题发生时,一般都会先尝试用这个来修复。

height: 除 “auto” 外的任意值

height: 1% 就在 Holly Hack 中用到。

zoom: 除 “normal” 外的任意值 (MSDN)

MS专有属性,无法通过校验。 不过 zoom: 1 可以临时用做调试。

writing-mode: tb-rl (MSDN)

MS专有属性,无法通过校验。

·在 IE7 中,overflow 也变成了一个 layout 触发器:

overflow: hidden|scroll|auto

这个属性在之前版本 IE 中没有触发 layout 的功能。

overflow-x|-y: hidden|scroll|auto

overflow-x 和 overflow-y 是 CSS3 盒模型中的属性,尚未得到浏览器的广泛支持。他们在之前版本IE中没有触发 layout 的功能。

·另外 IE7 的荧幕上又新添了几个 haslayout 的演员,如果只从 hasLayout 这个方面考虑,min/max 和 width/height 的表现类似,position 的 fixed 和 absolute 也是一模一样。

position: fixed

./.

min-width: 任意值

就算设为0也可以让该元素获得 layout。

max-width: 除 “none” 之外的任意值

./.

min-height: 任意值

即使设为0也可以让该元素的 haslayout=true

max-height: 除 “none” 之外的任意值

./.

以上结论借助 IE Developer Toobar 以及预先测试得出。

有关内联级别元素

对于内联元素(可以是默认即为内联的比如 span 元素,也可以是 display: inline 的元素)

·width 和 height 只在 IE5.x 下和 IE6 或更新版本的 quirks 模式下触发 hasLayout 而对于 IE6,如果浏览器运行于标准兼容模式下,内联元素会忽略 width 或 height 属性,所以设置 width 或 height 不能在此种情况下令该元素具有 layout。

·zoom 总是可以触发 hasLayout,但是在 IE5.0 中不支持。

具有“layout” 的元素如果同时也 display: inline ,那么它的行为就和标准中所说的 inline-block 很类似了:在段落中和普通文字一样在水平方向和连续排列,受 vertical-align 影响,并且大小可以根据内容自适应调整。这也可以解释为什么单单在 IE/Win 中内联元素可以包含块级元素而少出问题,因为在别的浏览器中 display: inline 就是内联,不像 IE/Win 一旦内联元素拥有 layout 还会变成 inline-block。

脚本属性 hasLayout

我们这里称 hasLayout 为“脚本属性”是为了和我们熟知的 CSS 属性相区别。

注意一旦一个元素拥有了 layout,就没有办法再将其设成 hasLayout = False 了。

hasLayout-property 可以用来检测一个元素是否拥有 layout:举个例子,如果它的 id 是“eid”,那么只要在

IE5.5+ 的地址栏里输入 javascript: alert(eid.currentStyle.hasLayout) 即可检测它的状态。

IE的 Developer Toolbar 可以实时检查一个元素的当前样式;如果 hasLayout 是 true ,那么它的值显示为 “-1”。 我们可以通过实时修改一个元素的属性将“zoom(css)”设置为“1”来触发 hasLayout 以便调试。

另外一个需要注意的是“layout”会影响脚本编程。如果一个元素没有“layout”,那么clientWidth/clientHeight 总是返回0。这会让一些脚本新手感到困惑,而且这和 Mozilla 浏览器的处理方式也不一样。不过我们可以利用这一点在 IE5.0 中检测“layout”:如果 clientWidth 是零那么这个元素就没有 layout。

CSS hacks

下面用于触发 haslayout 的 hack 已经经过 IE6 及以下版本测试。今后版本的IE有可能会对此做不同处理。如果新版本浏览器发布我们会重新整理这部分内容。

John Gallant 和 Holly Bergevin 在2003年发布的 Holly hack

/* \*/ * html .gainlayout { height: 1%; } /* */

·可以让 IE5+ 的任意元素获得 layout,除了标准兼容模式 IE6 中的内联元素。

·一般都很有效,除了在某些极少情况下,需要用 height:0 或者 1px 更好一些。

·和 overflow: hidden 不相容,除非在 IE6 的标注兼容模式下(因为这时如果父元素没有定高,那么height: 1% 会被变回 height: auto)。

或者我们可以用 underscore hack:

.gainlayout { _height: 0; }

另外,更具有向后兼容性的方法是使用 条件注释(conditional comments):

<!--[if lte IE 6]>

<style>

.gainlayout { height: 1px; }

</style>

<![endif]-->

在条件注释中链接一个专门对 IE/Win 做修正的外部样式表文件,也不失为一个安全有效的好方法:

<link rel="stylesheet" href="allbrowsers.css" type="text/css" />

<!--[if lte IE 6]>

<link rel="stylesheet" href="iefix.css" type="text/css" />

<![endif]-->

我们更倾向于使用 height: 0 和 1px —— 并主张始终使用 height 除非它和别的什么东西冲突 (overflow: hidden)。对于取值,我们则倾向于避免 1% ,因为它可能会(虽然很少)引起一些问题

height 不能应用于标准模式下的内联元素。在这种情况下我们可以用 display: inline-block 或 zoom: 1。

我们曾看过一些把 Holly hack 真的当作 holy(神圣的) hack 盲目使用的情况,比如对浮动元素使用或者对已经具有特定宽度的元素也使用这个 hack。要记住这个 hack 的目的不是要给某个元素加一个高度,而只是要触发 hasLayout = True 而已。

不要给所有元素设置 layout:* {_height: 1px;}。所谓过犹不及,获得 layout 不等于获得灵丹妙药,它只是用来改变渲染模式。

Hack整理

但是浏览器总是会变的,我们需要面对很多问题,比如一些依赖 IE6 的 bug 所做的 hack 会在 IE7 或更高版本的新浏览器中因 bug 修复而失效(甚至有害)的问题;比如新版本浏览器中类似的布局 bug 依然存在但用于 hack 的过滤器比如 * html 却不能正常工作的问题。这种情况下,MS专有属性 zoom 就可以考虑使用了。

<!--[if lt IE 7]><style>

/* IE 6 + IE5.5 + IE5.0 所用样式*/

.gainlayout { height: 0; }

</style><![endif]-->

<!--[if IE 7]><style>

.gainlayout { zoom: 1;}

/* 或者其他任何以后可能需要的东西 */

</style><![endif]-->

·zoom: 1; 可以让 IE5.5+ 的任何元素(包括内联元素)获得 layout,但是在 IE5.0 中无效。

·没有其他附带效果(内联元素会变成 inline-block,这个当然)。

·如果需要通过验证,应该用条件注释将 zoom 隐藏起来。

其实当我们考虑到“向后兼容”时是很自相矛盾的,我们强烈建议页面设计者回过头看一下自己页面中用的到的明显的或是不明显的“hacks”,并用条件注释针对不同浏览器重新处理以保万无一失。

关于IE Mac 的小问题

IE Mac 和 windows 下的 IE 是完全不同的两个东西,它们各自拥有自己的渲染引擎,IE Mac 就全然不知“hasLayout”(或contenteditable)所谓何物。相比之下 IE Mac 的渲染引擎要更标准兼容一点,比如 height 就是被当作 height 处理,没有别的效果。因此针对“hasLayout”的 hacks 和别的解决方法(特别是通过使用 height 或 width 属性的)往往对 IE Mac 来说是有害的,所以需要对其隐藏。更多的关于 IE Mac 相关的问题可以在 IE Mac, bugs and oddities pages 找到。

MSDN 文档

MSDN 中涉及到 hasLayout 这个 MS 属性的地方寥寥无几,而具体解释 layout 和 IE 渲染模型之间关系的则少之又少。

在IE4的时候,除了未经绝对定位也未指定宽高的内联元素,几乎所有元素都有某种 layout(MSDN)。在这种早期的layout概念中,像 border, margin, padding 这些属性被称作“layout属性”,它们是不能应用到一个简单的内联元素上的。换句话说,“拥有layout”就可以粗略理解成:“可以拥有这几个属性”。

MSDN 上仍然使用 layout 属性这种说法, 只是含义变了,它们和拥有 layout 的元素已经没有什么关系了。在 IE5.5 中方才引入了 MS 的这个专有属性 hasLayout,也只是某种内部的标志位而已。

在 IE5.5 中,MSHTML Editing Platform(即可以通过设置来允许用户实时编辑、拖动 layout 元素以及调整其尺寸等)的文档中描述了三个和 layout

[1] [2] [3] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有