IE中HTML元素的一些特殊的“性质”

<html> 元素,XHTML 文档中的根元素,再熟悉不过了。不过最近折腾一个布局,发现在 IE 中,它不是那么简单的角色,有一些很特殊的“性质”,总结一下备查:

IE6 标准模式:

  • 不管给它设置什么样的高度和宽度,它的大小都始终充满整个视区。
  • 不管给他设置什么样的 paddingborder,同样,大小始终充满整个视区。
  • margin 会被忽略。
  • initial containing block 是视区矩形减去 <html>border 宽度

用 CSS3 来表述,我们可以把 IE6 中的 <html> 看成 heigh:100%; width:100%; box-sizing:border-box; 的一个特殊元素,而且这些属性不可变

IE7 标准模式:

IE7 虽说修复了 IE6 的若干 CSS bug,但对于 <html> 的理解,要比 IE6 复杂得多。IE6 虽然诡异但可以改的属性毕竟少,所以还算简单。IE7 的 <html> 倒是可以接受更多的属性了,但算法却不按照规范老老实实的来,所以搞明白它要比 IE6 头疼得多。

  • 首先是自动扩展特性。

    <html> 元素在 y 方向上比较简单,和 IE6 对普通元素 height 的理解方式类似——如果内容高度超过 <html> 的高度,或者 <html> 没有定高(即默认值 auto),那么 <html> 会自动扩展自身高度以包含其中内容。

    而在 x 方向上有些诡异,问题主要集中在对 <body> 宽度的理解,这里分两种情况讨论:(不是说 <html> 么,怎么又说到 <body> 的宽度了?因为 <html> 要自动扩展,必须要知道 <body> 有多宽才好扩展嘛。)

    • 第一种情况:<html>width 如果是非 0 值之外的一切值(包括默认值 auto),那么 <body> 的宽度由以下规则决定:

      • 1. 如果 <body>width 是个固定值,那宽度就是这么多。
      • 2. 如果 <body>width 是默认值 auto,那宽度会充满 <html> 的内容空间。
      • 3. 如果 <body> 本身有收缩包围特性,比如被设置了 position:absolute 或者 display:inline(奇怪的是 float 却不满足这一条,它满足2),那么就根据内容的宽度来定。
    • 第二种情况:如果 <html>width 是 0,那第 1、3 点和上面的情况相同,而第 2 点,如果 <body>width 是默认值 auto那宽度根据内容自适应,但有一个奇怪的现象,就是如果 <body> 同时具有不为 0 的 border 或者 padding 时,它的宽度就不会根据内容自适应而会变成第一种情况下的第 2 点——充满 <html> 的内容空间,由于这时 <html> 的宽度是 0,所以 <body> 宽度也坍缩成 0。
  • 其次是 <html> 的宽高设置会奇怪地影响 <body> 的百分比参考(或者说 <body> 的 containing block)。

    在 y 方向上,如果 <html>height 是默认值 auto,那么 <body>height 如果取一个百分比的值,将会被忽略。但一旦 <html>height 值有了一个具体高度,哪怕是 0,<body> 的百分比高度就会被应用了。不过诡异的是,这个百分比高度的计算参考并不是刚刚设置的 <html> 的高度,而是视区高度减去 <html>margin+border+padding 高度之和。

    而在 x 方向上,如果 width 取默认值 auto,和 y 方向不同,<body> 的百分比宽度将不会被忽略,但其计算参考依旧和 y 方向一样诡异,为视区宽度减去 <html>margin+border+padding 宽度之和。如果 width 有了具体取值,它就会取而代之作为 <body> 的百分比宽度参考。

  • 再次,当 <body> 设置为 position:absolute 时,<html>border-color 会失效。这是另外一个奇怪的 bug。
  • 最后,initial containing block 采用视区矩形,这个基本正常。但无法使 <html> 创建绝对定位元素的 containing block,不过也许 <html> 创建的 containing block 就是视区矩形,谁知道呢。

好乱,整理下来除了头大还是头大,不知道以后回过头再看还能不能看明白。IE7 啊 IE7……想说爱你不容易……

IE5 以及 Quirks 模式

  • <html><body> 所有宽高设置都会被忽略而保持充满视区。
  • <html> 不接受 paddingmargin
  • <body> 接受 paddingmargin 但负值 margin 没有视觉效果,不过会在计算其他相应参数时带入。
  • <body>border, background 等属性会向上转移给 <html> 元素。
  • initial containing block 是 <body>padding 边缘。

用处

这个总结是从一开头的布局问题引出来的,那个布局问题就是用处之一,等下重写一个 post 来整理。但那个布局只用到了很少一部分特性,应该还有更多的潜力可以挖,慢慢研究吧。

另外上面总结的东西都是简单试验试推出,所以很可能有理解错误的地方,如果阅读本文的朋友发现了,希望可以留言告知。

时间: 2024-09-12 20:00:39

IE中HTML元素的一些特殊的“性质”的相关文章

c++-类中某元素的快速排序

问题描述 类中某元素的快速排序 怎么改正可以再排列类中元素nodes[i].degree_num时排列i?我的程序只能排列degree_num 先开始试了第二幅图注解掉的绿色代码,出现了图一情况 我传递的数组 i 0 1 2 3 4 5 6 7 8 a[i] 10 9 8 7 6 5 4 3 2 a[i].degree_num 1 1 1 4 3 1 1 3 1 如何对快速排序改变一下使得能按照第三行重新排列数组内的值第二行 解决方案 a[i]是第2行 a[i].degree_num是第三行 手

index-lua的元表怎么遍历不到,而且为什么也不能改变表中的元素的值呢,求详解?

问题描述 lua的元表怎么遍历不到,而且为什么也不能改变表中的元素的值呢,求详解? local function tab(t) local proxy = {} local mt = { __index = t, __newindex = function(t, k, v) error("attempt to update readonly a table") end } setmetatable(proxy, mt) return proxy end local days = tab

Hibernate配置文件中映射元素详解

详解 本文中将讲述Hibernate的基本配置及配置文件的应用,这对于正确熟练使用Hibernate是相当关键的. 配置文件中映射元素详解 对象关系的映射是用一个XML文档来说明的.映射文档可以使用工具来生成,如XDoclet,Middlegen和AndroMDA等.下面从一个映射的例子开始讲解映射元素,映射文件的代码如下. <?xml version="1.0"?><!--所有的XML映射文件都需要定义如下所示的DOCTYPE.Hibernate会先在它的类路径(c

使用HTML5的JS选择器操作页面中的元素

使用HTML5的JS选择器操作页面中的元素. 文件命名为:querySelector.html,可在Chrome浏览器中预览效果. <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>使用HTML5的JS选择器操作页面中的元素</title> </head> <body>

在XML文档中替换元素名称的做法

不要小看这个操作,其实是不太容易的.请注意,我们是要替换掉元素的名称,而不是元素的值. XML的内容在内存中是一个DOM树,要替换掉一个元素,其实是要新建一个元素,并且将原先元素的所有子元素都复制过来.在LINQ TO XML中用ReplaceWith来实现 using System; using System.Linq; using System.Xml.Linq; namespace ConsoleApplication1 { class Program { static void Main

用firebug查看网页中的元素信息

  在火狐浏览器中,使用firebug可以实时查看网页页面中各个元素的各个信息,包括元素的尺寸,css样式等,如下图所示,我选中了ps这个小图片,在firebug中显示了该小图片的代码信息,在左上角有个快速信息(图片大小样式等),而在右下方,则是选中元素的具体的css样式. firebug的强大超乎想像,这个网页元素查看功能只是其中的小功能. 选项设置

PHP删除数组中特定元素的两种方法

这篇文章介绍了PHP中删除数组中特定元素的两种方法,有需要的朋友可以参考一下   方法一: 复制代码 代码如下: <?php $arr1 = array(1,3, 5,7,8); $key = array_search(3, $arr1); if ($key !== false)     array_splice($arr1, $key, 1); var_dump($arr1); ?> 输出: array(4) { [0]=> int(1) [1]=> int(5) [2]=>

python实现从字典中删除元素的方法

  本文实例讲述了python实现从字典中删除元素的方法.分享给大家供大家参考.具体分析如下: python的字典可以通过del方法进行元素删除,下面的代码详细演示了这一过程 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # Create an empty dictionary d = {} # Add an item d["name"] = "Fido" assert d.has_key("name") # Del

php求正负数数组中连续元素最大值示例

 问题是给出数组,该数组由正负数字组成,找出该数组中连续元素组成的子数组的最大值.下面是PHP实现的示例,需要的朋友可以参考下 php实现正负数数组最大子序列,要求给出数组,该数组由正负数字组成,找出该数组中连续元素组成的子数组的最大值. 这其实得算是个背包变种吧.   代码如下: <?php $list = array(1,-3,-5,-7,8,9,-11,5);   $cur = 0; $term = 0; $res = 0; $begin = 0;   foreach($list as $