13  标准网页布局的

标准的最大挑战不在于技术本身,而在于处理。所谓浏览器兼容问题,就是当我们使用不同的浏览器(如IE 7、IE 6、Firefox等)访问同一个页面时,可能会出现不一致的情况,出现这种现象的原因有很多种,但根本原因就是浏览器对于技术支持的标准不同造成的。

IE浏览器对于标准技术的支持是很不完善的,这些问题可以分为两种:一种是IE支持某种技术或功能,但是实现该功能的方法和途径与标准技术不同;另一种是IE浏览器自身的解析机制存在很多Bug,导致页面解析效果与标准不同。

本章将兼顾IE 6、IE 7和FF三种主流版本或类型浏览器进行讲解,其中IE 6浏览器用户数最多,IE 7的用户将逐步超越和代替IE 6,而FF浏览器代表了标准浏览器的主流。

1  兼容不同类型浏览器的基本方法

不同类型浏览器对于技术的支持是不完全统一的,如果再加上浏览器对于解析时存在各种Bug,CSS就变得异常复杂。

解决浏览器兼容问题的方法,这些方法被称之为Hack(即补丁的意思)。所谓Hack,就是利用各种过滤方法专门为特定类型浏览器定义样式,即称之为过滤器(Filter),从而实现在不同类型浏览器中呈现相同的渲染效果。

过滤器是一种形象的称呼,实际上它就是各种浏览器支持或不支持某种声明或样式的特殊用法。例如,IE 6以下版本浏览器不支持!important关键字,我们就可以利用这个关键字专门为IE 6及其以上版本浏览器或者非IE浏览器定义样式,从而过滤掉IE 6以下版本浏览器在解析时存在的问题。

2

1  标准网页布局的兼容性处理

1.1  常用过滤器

目前全球设计师发现并总结出来的过滤器非常多,要记住这些过滤器是很繁琐的,读者可以参阅http://centricle.com/ref/css/filters/

3

1  标准网页布局的兼容性处理

1.1  常用过滤器

http://www.communis.co.uk/dithered/css_filters/css_only/index

4

1  标准网页布局的兼容性处理

1.1  常用过滤器

IE 7版本浏览器专用过滤器

如果专门为IE 7版本浏览器定义样式,则可以使用如下过滤器。该过滤器还可以兼容即将上市的IE 8版本浏览器。

<style type="text/css">

*+html body {

background:blue;

}

</style>

 

兼容原理:

“*”符号在IE浏览器中被认为是根节点,所以它可以包含html元素,而对于非IE浏览器来说,文档根节点应该是html,而不是“*”,所以当使用“*”通用符号包含html元素时,非IE浏览器会认为它是非法的,从而忽略这个选择器所定义的样式。同时IE 6及其以下版本浏览器不支持相邻选择器(+),所以也会忽略该选择器定义的样式。

5

1  标准网页布局的兼容性处理

1.1  常用过滤器

IE 6及其以下版本浏览器专用

 

<style type="text/css">

* html body {

background:red;

}

</style>

 

不过从语法角度分析,IE 7应该支持*通用符号包含html元素,但事实上并不支持,所以这也是一个很有趣的过滤器。

6

1  标准网页布局的兼容性处理

1.1  常用过滤器

IE 7和非IE浏览器专用

<style type="text/css">

html>body {

background:green;

}

</style>

 

兼容原理:

因为IE 6及其以下版本浏览器不支持子选择器,所以会忽略该过滤器定义的样式。

7

1  标准网页布局的兼容性处理

1.1  常用过滤器

非IE浏览器专用

style type="text/css">

html>/**/body {

background:yellow;

}

</style>

 

在IE 8中存在问题,需要使用其他方法。

 

 

8

1  标准网页布局的兼容性处理

1.2  使用IE条件语句过滤

IE条件语句是IE浏览器自定义的一套逻辑语句,利用这些语句可以更加有效的为IE系列版本浏览器定义样式。

IE条件语句实际上就是HTML注释语句,只不过在注释标识符中增加了一组关键字,这一组关键字对于IE浏览器来说是有效的,但是对于其他浏览器来说,则被视为注释信息完全忽略。由于IE浏览器能够根据条件语句中设置的条件决定解析的版本,从而实现利用条件为不同IE版本浏览器定义样式的目的。

<!--[if IE]>

<h1>所有IE版本浏览器可识别</h1>

<![endif]-->

 

9

1  标准网页布局的兼容性处理

1.2  使用IE条件语句过滤

IE条件语句以中括号([])为起止标识符,其中包含一个条件语句。条件语句放在注释标识符内,且与注释标识符内部相邻,语法格式如上面示例。

在条件语句中可以增加修饰性关键字,如lte、lt、gte、gt和!,这些关键字作用说明如下:

lte:小于或等于某个版本的IE浏览器。

lt:小于某个版本的IE浏览器。

gte:大于或等于某个版本的IE浏览器。

gt:大于某个版本的IE浏览器。

!:不等于某个版本的IE浏览器。

 

10

2  流动布局的兼容性处理

不同浏览器对于CSS的解析是不同的,这种不同源自不同浏览器的解析机制不同,所以在设计之初读者就应该养成良好的兼容处理习惯,学会直面主流浏览器存在不不,避免后面兼容处理的难度和成本。

目前市场上不同类型或版本的浏览器很多,但是如果从用户数、标准度等方面来比较,其实浏览器市场仅包括两大类型:IE类型和非IE类型浏览器。当大家提及某个页面不兼容,或者出现布局问题,多因为它无法兼容标准浏览器,或者仅支持IE浏览器。而非IE浏览器多建立在标准解析机制之上,所以它们都能够很好支持标准。

本章将以FF(Firefox)浏览器作为非IE的代表,

 

11

2  流动布局的兼容性处理

2.1  关于不同浏览器的默认值问题

提及页边距,IE浏览器默认为body元素的margin-left属性进行定义,默认值约为10像素;而对于FF浏览器来说,默认为body元素的padding-left属性进行定义,默认值约为8像素。与此类似的默认值差异设置还包括:

列表样式:IE默认使用margin-left属性定义,值约为40像素;而FF默认使用padding-left属性定义,值约为40像素。

网页居中样式:IE默认使用text-align属性,值为center;而FF默认使用margin属性,设置左右边界为auto。

鼠标指针样式:IE默认使用cursor属性定义,值为hand;而FF默认使用cursor属性,值为pointer。

12

2  流动布局的兼容性处理

2.2  列表兼容性处理—有序列表高度问题

所谓有序列表高度问题:就是当为有序列表定义高度时,列表序号将显示无效。该现象存在于所有版本的IE浏览器中,非IE浏览器不存在该问题。

如果定义项目符号为拉丁字母等其他有序符号,在IE中会统一显示为点号项目符号,而在非IE下会显示为定义的字母序号显示。

 

解决方法:

避免使用height定义列表项的高度,改为line-height属性间接定义高度。

 

 

2  流动布局的兼容性处理

2.3  列表兼容性处理—列表宽度问题

这个问题存在于所有版本的IE浏览器中。当为列表框定义一个宽度时,在某种情况下,项目符号会突然消失,而在非IE下却能够正常显示。

方法一,定义项目符号位置在内部显示。

方法二,为列表项定义左侧边界大小为2个字体宽度。

方法三,为列表框定义左侧补白为2个字体宽度。

2  流动布局的兼容性处理

2.4  列表兼容性处理—项目符号变异问题

这个问题存在于所有版本的IE浏览器中。当为列表结构中某列表项定义宽度或高度等特殊属性时,有序项目符号会发生混乱,而在非IE下却能够正常显示。

对于此类问题目前还没有好的方法,不过可以通过间接方法来实现。也就是说如果要定义列表项的宽度,不妨给列表项包裹一个外套,然后为外套定义宽度来实现。但是这样做会破坏列表结构的语义性,最佳方法应该是避免为列表项定义高度和宽度,除非不隐藏项目符号的显示。

还有一种方法:取消列表结构的默认项目符号,使用背景图像来定义项目符号,这种做法会更为灵活和个性。

2  流动布局的兼容性处理

2.5  列表兼容性处理—列表行双倍高度问题

个问题存在于IE 6及其以下版本浏览器中。当为列表项中嵌套超链接元素,且定义超链接(a元素)为块状显示(块状显示的目的是可以定义超链接的大小),这时在IE 6及其以下版本浏览器中列表行会显示双倍高度,而在IE 7和非IE下却能够以正常行高显示。

方法一,为列表项定义宽度、高度或边框。

li {border-bottom:1px solid #CCC;}         /* 增加底边线  */

或者

li { width:100%;}       /* 满宽显示 */

或者

li { height:1.1em;} /* 以行高大小定义高度 */

 

 

16

2  流动布局的兼容性处理

2.5  列表兼容性处理—列表行双倍高度问题

方法二,使用zoom属性。

zoom是IE的私有属性,它能够定义元素的缩放比列。但是它也能够使列表项恢复到正常行高。例如,下面代码可以轻松修正列表项的双倍行高问题,且对于其他版本浏览器没有副作用。

 

17

2  流动布局的兼容性处理

2.6  列表兼容性处理—列表项错行问题

这个问题存在于FF浏览器中。当为列表项中嵌套块状元素,且项目符号在内部显示时,FF浏览器中会出现错行问题,而在IE等其他浏览器中却不会出现这类问题。

方法一,定义项目符号显示在列表项的外面。

如果显示在列表项内部,FF会根据块状元素仅能够在一行内显示的原则,从而错行显示。此时即使定义块元素宽度不为100%,它也会错行显示。

li a{/* 列表项包含的块元素 */

display:block; /* 块状显示 */

width:80%; /* 宽度 */

}

 

18

2  流动布局的兼容性处理

2.6  列表兼容性处理—列表项错行问题

方法二,定义块元素为行内块状显示,可以清除块状占据一行的问题。

li a{/* 列表项包含的块元素 */

display:inline-block; /* 行内块状显示,清除满行显示 */

}

 

 

19

2  流动布局的兼容性处理

2.7  默认高度问题

这个问题存在于IE 6及其以下版本浏览器中。当定义元素的高度小于元素默认行高时,高度将始终保持默认行高。

解决方法:

定义元素内字体大小为0,这样就清除了行高对于高度的影响。但是不能够定义行高为0,因为字体大小默认为16像素,所以还会影响高度设置,而当字体大小为0时,行高也就没有了。

#bar {font-size:0;}

20

2  流动布局的兼容性处理

2.7  默认高度问题

如果就这个问题继续探索。当我们定义元素高度为1像素时,则你又会发现:在IE 6及其以下版本中显示为2像素高度,而IE 7和非IE下显示为1像素。

使用CSS定义的overflow属性来裁切多出的高度,代码如下。

#bar {overflow:hidden;} /* 裁切多出区域 */

 

21

2  流动布局的兼容性处理

2.8  盒模型高和宽的计算问题

这个问题存在于IE 5.5及其以下版本浏览器中。IE 5.5及其以下版本浏览器认为height和width属性应该包含内容区域的大小、补白区域大小和边框区域大小,通俗说就是元素实际显示的大小。而根据CSS标准,height和width属性值不应该包含补白区域大小和边框区域大小,它仅代表内容区域的大小。

解决此问题方法有多种,但最安全、有效的方法就是使用IE条件语句。把IE条件语句放在原来样式表的底部即可(代码如下),这样就在IE 5.5及其以下版本浏览器中显示与IE 6等其他版本浏览器相同的大小效果。

22

2  流动布局的兼容性处理

2.9  最小高度和宽度问题

这个问题存在于IE 6及其以下版本浏览器中,准确说这个问题不是Bug,而只是暂时功能不支持,或者说不完善,即IE 6及其以下版本浏览器不支持min-height和min-width属性的问题。

所以,解决方法是:专门为IE 6及其以下版本浏览器定义一个高度,具体代码如下:

* html #box {/* IE6及其以下版本浏览器过滤器 */

height:100px;                                                         /* 定义高度为100像素 */

}

 

23

2  流动布局的兼容性处理

2.10  超链接兼容处理—失控的子标签问题

这个问题存在于IE 6及其以下版本浏览器中。当在超链接中嵌套一个子标签时,如果希望利用超链接来动态控制子标签的显示样式,就会出现控制失效问题。

这个问题是IE 6及其以下版本浏览器解析超链接的机制造成的,解决方法是:在超链接的鼠标经过状态时定义一个高度,由于a元素默认为行内元素,定义高度后不会影响其显示,但定义高度之后能够触发它正确解析子标签<span>的显示或隐藏。

 

24

2  流动布局的兼容性处理

2.11  超链接兼容处理—背景图像代替文本问题

超链接a元素默认为行内显示,由于行内元素不识别盒模型的宽度和高度,所以当为它定义大小时是无效的。如果我们希望使用背景图像来代替超链接文本就会存在很大的问题,实际上设计师经常要面临这样的问题,因为使用背景图像能够设计更具个性的超链接效果。

这种方法利用补白来间接定义元素的大小,并借助font-size属性来间接隐藏字体,从而实现背景图像代替文本的设计效果。

 

 

25

3  浮动布局的兼容性处理

3.1  浮动被流动包含问题

这是所有浏览器都存在的问题,即当一个自然流到的元素包含一个浮动的元素时,则包含元素会自动收缩,而不是被浮动元素撑开。既然所有浏览器都有这个问题,那么法不责众,这个问题也就算不上问题了,或者说它仅是一种现象。

解决方法:

可以使用增加清除浮动元素,强制包含框张开以包含浮动的子元素。

 

26

3  浮动布局的兼容性处理

3.1  浮动被流动包含问题

但是如果在IE 6及其以下版本中不完全支持这种方法。而更有趣的是,如果在IE 7浏览器中改变窗口宽度小于包含的浮动元素所定义的宽度时,你会发现包含框所定义的背景色突然没有了,真是让人莫名其妙。

方法:

#wrap { /* 包含框样式 */

background:#FFCCFF;

zoom:1; /* 使用私有属性缩放100%来触发布局 */

}

或者:

#wrap { /* 包含框样式 */

background:#FFCCFF;

border:solid 1px red;      /* 定义边框来触发布局 */

}

 

27

3  浮动布局的兼容性处理

3.2  包含框不能自适应高度的问题

这个现象本应属于流动布局问题,因为与上一节示例存在问题有点类似,故放在这儿进行讲解。该问题存在于所有浏览器中。当为包含框内的元素定义上下边界时,包含框不能够自适应高度以包含子对象。

存在原因:

如果嵌套元素的边界没有被相互阻隔,则就会出现边界重叠现象。例如,被包含元素的上边界会自动与包含框的上边界重叠,被包含元素的下边界会自动与包含框的下边界重叠。

解决方法:

为包含框定义边框或者补白,从而阻断相互嵌套元素的上下边界接触,防止发生重叠现象,则阻断边界接触。

 

28

3  浮动布局的兼容性处理

3.3  浮动布局中栏目内容被隐藏的问题

这个问题存在于IE 6及其以下版本浏览器中。有人把这个问题称之为躲猫猫或捉迷藏。之所以这样称呼,是因为在特定条件下栏目内容看起来消失了,只有重新刷新页面时才能够出现,或者用鼠标拖选可以使其显示。

 

29

3  浮动布局的兼容性处理

3.3  浮动布局中栏目内容被隐藏的问题

出现这个Bug的原因比较特殊,一般需要几个前提条件:

第一,包含框中包含有浮动元素和流动元素,且包含框定义了背景色。

第二,浮动元素后面为一些流动元素,浮动元素的高度应该大于后面流动元素的高度。

第三,在流动元素的下面是一个清除元素(即元素定义清除浮动属性),或者是一个被定义了宽度且宽度足以促使元素只能够显示在浮动元素的底部,而不是环绕在浮动元素的两侧。

当满足上面三个条件,则中间的流动元素(环绕在浮动元素两侧的元素)看起来似乎消失了,原来它们都隐藏到了父元素的背景后面,只有在刷新页面时才重新出现。

 

3  浮动布局的兼容性处理

3.3  浮动布局中栏目内容被隐藏的问题

 

方法一,学会在浮动元素后面增加清除元素。所谓清除元素,就是定义了clearr属性的元素,这样就可以避免浮动元素对后面布局的影响。

方法二,在结构嵌套中应遵循最少的层次来满足页面设计需要,使页面结构简单,容易控制与管理,尽可能的减小由于不必要的嵌套引来的Bug。

 

3  浮动布局的兼容性处理

3.4  同时设置边界和浮动布局的问题

这个问题存在于IE 6及其以下版本浏览器中。出现这个问题需要具备两个前提条件:

第一,元素同时被定义了边界和浮动显示,且浮动方向和定义边界方向在一个方向。

第二,浮动边相邻的是一个流动元素或包含框,而不是浮动元素。

当满足这两个条件之后,所定义的边界会加倍显示。

解决该问题方法比较简单:

3  浮动布局的兼容性处理

3.5  半个像素问题

这个问题存在于所有IE浏览器版本中。我们知道像素值是没有小数值的,但是当在布局中使用百分比设置单位,就会存在计算的像素值出现小数部分。对于小数值问题,不同类型浏览器取舍方法不同:

IE将根据四舍五入的方法进行计算。例如,假设值为10.5像素,则IE在解析时会根据四舍五入的方法,计算为11像素,而对于值为10.4像素,则计算结果为10像素。

FF等标准浏览器对于小数值一般采取忽略不计的方法,多出的值将按元素顺序进行分配。例如,包含框宽度为11像素,平分为3个子元素,则每个子元素平分3像素,多出的2像素按顺序分给第1、2个子元素。如果包含框宽度为10像素,则每个子元素平分3像素,多出的1像素分给第1个子元素。

3  浮动布局的兼容性处理

3.5  半个像素问题

解决方法:

这是一个比较特殊的问题,最佳方法当然是避免此类问题的出现,即不要设置包含框宽度为一个奇数值。不过在布局中很多取值是无法预定的,所以使用下面这个方法是最安全的。即为包含的子元素定义清除右侧浮动。

13-44

这样它就能够强迫所有的子元素并列显示。其实clear:right;声明是一个比较神奇的工具,对于IE浏览器来说,不管所包含的子元素宽度有多大,它都能够强迫子元素在同一行内显示。

3  浮动布局的兼容性处理

3.6   3像素问题

这个问题存在于IE 6及其以下版本浏览器中。当浮动元素与流动元素并列显示时,它们之间会存在3像素的间距。

解决方法:

利用IE 6及其以下版本浏览器的过滤器,专门为它们定义样式实现与标准浏览器的兼容。

3  浮动布局的兼容性处理

3.7  多出字符问题

这个问题存在于IE 6版本浏览器中。当多个浮动元素中间夹杂有HTML注释语句时,如果浮动元素宽度为100%,则就会在下面一行多显示一个上一行最后一个字符。

解决方法:可以清除注释语句即可。

4  定位布局的兼容性处理

4.1  定位参照物的问题

这个问题存在于IE 6及其以下版本浏览器中。当定义行内元素为包含块时,且包含块包含的绝对定位元素以百分比为单位进行定位时,就会出现参照物混乱现象。

解决此类问题的方法很简单,直接为span增加zoom属性,该属性能够触发span自动布局,而从促使绝对定位元素以span元素为参照物进行定位。

4  定位布局的兼容性处理

4.2  定位元素的结构与层叠问题

这个问题存在于所有IE版本中。当定位元素位于不同的结构中时,它们之间的层叠顺序就不能够简单使用z-index属性来控制。定位元素的层叠顺序还要受结构关系的影响。

问题原因:

IE浏览器能够根据相同结构层次的定位元素进行比较,如果不在同一个结构层次,则先比较相同层级的父元素,谁的父元素z-index属性值大谁就在上面,而不管其子元素的z-index属性值有多大。

在上面示例中,蓝盒子的层叠顺序为1,而红盒子的包含块层叠顺序为0(默认值),由于蓝盒子与红盒子的包含块属于同一个层级,所以蓝盒子就会覆盖红盒子的包含块。这样即使红盒子的层叠顺序值为多大都将被覆盖在下面。这个规则对于非IE浏览器来说是无效的。

解决方法:为红盒子的包含块定义较大的层叠值。

4  定位布局的兼容性处理

4.3  定位元素丢失问题

这个问题存在于IE 6及其以下版本浏览器中。当在一个包含块内并列浮动几个元素,它们的宽度之和整好等于包含块的宽度,这时如果在包含块内嵌入绝对定位元素,则该定位元素就会丢失。

方法一,通过为每个栏目收缩一个像素边界,从而显示丢失的绝对定位元素。

方法二,受上面方法的启发,我们也可以不定义负边界,而直接为包含块定义多出3像素。这个3像素是根据所包含的栏目块来定的,如果仅包含两个栏目块,则应该是2像素。

4  定位布局的兼容性处理

4.3  定位元素丢失问题

方法三,上面两种方法都是通过加宽或收缩边界的方法,为定位元素腾出一点空间,从而诱发它显示出来。我们也可以为包含的最后一个子栏目使用绝对定位,从而避免浮动元素占满整个包含块的空间。

方法四,我们也可以在浮动元素和绝对定位元素之间增加一个清除浮动元素,从而强迫定位元素与浮动元素位于不同行中,从而显示出来。