第十一章 网页兼容的处理
对于一个网页设计师来说,众多浏览器间的CSS兼容问题从来都是非常棘手的。由于不同的浏览器(常见的包括IE6,IE7,Firefox等)对CSS的解析和认知的不同,严重造成了浏览器页面效果的不一致,使得我们在进行DIV+CSS页面排版时,不得不时刻考虑到常见浏览器间的CSS兼容性问题。
11.1 解决浏览器兼容的原理
什么是CSS Hack呢?
为解决浏览器间的CSS兼容性问题,设计师们针对不同浏览器写不同的CSS code的过程,就是一个Hack的过程了。在这个过程中,不但要做到浏览器的兼容性,更要合理地做到CSS代码的绝对优化,尽可能少地人为制造冗余的代码,使CSS代码尽可能简练易读也是非常重要的工作之一。
为什么要用CSS Hack呢?
答案很简单,通过对CSS代码的兼容性问题的解决,使得我们写出的页面能在不同的浏览器中达到统一的页面效果。不会出现IE浏览器中完好的页面拿到FF中去就横七竖八千疮百孔的事情。
CSS Hack的原理是什么?
根据不同浏览器对CSS样式的支持程度,解析结果和识别CSS的优先级不同,设计师们就可以根据这些不同浏览器的特点来书写不同的CSS样式代码。IE6能识别下划线_和星号*,IE7能识别星号*,不能识别下划线_,而firefox两个都不能识别,如此,就可以针对IE6.IE7和FF通过对这些特殊符号的使用写不同的代码了。
div{background:green; /* for FireFox */
*background:red; /* for IE7 */
_background:blue; /* for IE6 */
}
该样式显示的效果是:在FireFox中背景色为green;在IE7中背景色为red;在IE6中背景色为blue。
CSS解析的过程:CSS读取的顺序是由上至下,由左至右。在FireFox下,FireFox不能识别*和_,将下面的两行代码过滤掉不作任何解析,执行background:green;完后结束;在IE7下的解析结果为div{ background:green; *background:red; },根据CSS的优先级可以确定后面出现的样式会优先于前者被调用,即实现*background:red;的解析;在IE6下,因为三种样式代码都可以解析,解析结果为div{ background:green; *background:red; _background:blue;},但同样根据CSS的优先级,只会把最后一个样式读取,即_background:blue;被应用。
此外,!important声明也可以很好地提升指定样式规则的应用优先权。在IE6和FF中用!important声明可以提高优先级别,但在IE6中的!important声明会被之后的同名属性定义替换。所以,通过*和!important声明两者的搭配也可以很好地解决IE6,IE7和FF三者之间的兼容性问题。
区别IE6与FF:background:red; *background:blue;
区别IE6与IE7:background:green !important;background:blue;
区别IE7与FF:background:red; *background:green;
区别FF,IE7,IE6:background:red; *background:green !important; *background:blue;
注:IE都能识别*;FF不能识别*;IE6能识别*,但不能识别 !important;IE7能识别*,也能识别!important;FF不能识别*,但能识别!important;
书写的顺序都是FireFox的写在前面,IE7的写在中间,IE6的写在最后面。
除了做CSS HACK,我们在写CSS的时候要尽量避免可能会出现不兼容的写法,例如margin-top和padding-top,我们知道使用margin-top在IE8里面可能会不兼容,所以我们尽量使用padding-top。同样的,如果你使用高,则尽量记得在height属性的后面加上overflow属性。下面我们汇总尽量多的浏览器兼容的解决办法给大家。
11.2 浏览器兼容处理汇总
1、 解决IE7和IE7以上版本的兼容问题。
在<head>的后面插入如下代码:
<meta http-equiv="x-ua-compatible" content="ie=7" />
这句话的意思是当浏览器的版本高于IE7时以IE7的模式加载网页。
2、解决IE6不支持png图的问题。
打开http://www.chinalooke.com/js/ie6.js下载JS文件到站点js目录下,把以下代码放到head之间。
<!--[if lte IE 6]> <script src="js/ie6.js" type="text/javascript"></script>
<script type="text/javascript">
DD_belatedPNG.fix('div, ul, img, li, input , a');</script>
<![endif]-->
把上面的代码放在head之间。
3、解决IE6不支持除a标记以外的标记的伪类。
打开
http://www.chinalooke.com/UploadFiles/clubfiles/2011-03/2011030414170752881.rar
将下载下来的文件解压到站点根目录下。
在css文件的body{}中加入behavior:url("hover.htc");
4、解决border的边界显示不完整的方法
如果我们对盒子定义了border值,那么在盒子的左右两边会出现断断续续的情况,解决的办法是在盒子中加入background属性和值,背景颜色和背景图片都可以。
5、解决左右高度自适应
有时候我们需要盒子的左右两个子盒子的内容随着任意一个盒子的高自适应,做法是在大盒子里不定义高,但一定加入overflow:hidden,同时左右两个子盒子都写一个底部内边距和底部外边距,一正一负相互抵消,如padding-bottom: 1980px; margin-bottom: -1980px;值一定要写得很大,超过预计的内容的高度即可。代码实例如下。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>解决左右高度自适应</title>
<style type="text/css">
.main { width: 800px; margin: 0 auto; margin-top: 20px; color: #FFF; overflow: hidden;}
.left {float: left; width: 550px; background: #f00; border: 1px solid #666; padding-bottom: 980px; margin-bottom: -980px;}
.right {float: right; width: 240px; background: #090; border: 1px solid #666; padding-bottom: 980px; margin-bottom: -980px; }
</style>
</head>
<body>
<div class="main">
<div class="left">
左边
</div>
<div class="right">
<p>右边</p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p>fdsfdsfdsf </p>
<p>fdsfdsfdsf </p>
</div>
</div>
</body>
</html>
6、解决IE6下左浮动左边距为双倍的问题。
在IE6下,如果向左浮动的第一个盒子如果同时存在左外边距,那么显示的真实结果是设定值的两倍,如 .left{float:left;margin-left:10px;},那么这个盒子在IE6下左边距为20px,解决这个问题的办法有两种,一种是在里面加入display:inline,另外一种是再加一个IE6优先的_margin-left:5px;将值减半。
7、解决IE6的最小高度问题
在IE6下,盒子的最小高度不能少于12px,解决的办法是在高后面加入overflow:hidden或者是加入font-size:1px;
8、解决盒子真实宽高的计算问题
在IE下面盒子的真实宽和高分为已经定义宽和高以及没有定义宽和高两种情况。
当盒子已经定义宽和高的时候,真实的宽和高=padding值+border值+width值
当盒子没有定义宽和高的时候,真实的宽和高=父级的宽和内容的高
9、解决图片以及表单项的垂直居中问题
对于单行文本中出现了图片img和表单项input会使得其与文字垂直方向不能居中对齐的解决办法就是在CSS中对图片或表单赋予一个属性 vertical-align:middle; 这个方法在第九章中详细讲解过。
10、解决IE6下的图片下面有空隙的问题
解决IE6下的图片下面有空隙的问题只需要在在图片控制属性下加入vertical-align属性或者直接display转成外联元素。
11、解决英文不断行的问题
在盒子里加入word-wrap:break-word属性可以解决IE中英文不断行的问题。
12、解决ie6、7、8不支持json,解决方法:引入json2.js
加在head之间
<!--[if lt IE 9]>
<script src="__PUBLIC__/js/klxsx/json2.js"></script>
<![endif]-->
13、解决了IE8不支持数组的indexOf方法
今天,测试报过来一个js bug, 在IE8下有个js错误,但是在其它浏览器下(Firefox, Chrome, IE9)下面都很正常。后来调试发现原因是在IE8下,js数组没有indexOf方法。
在使用indexOf方法前,执行一下下面的js, 原理就是如果发现数组没有indexOf方法,会添加上这个方法。
if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(elt /*, from*/) { var len = this.length >>> 0; var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from) : Math.floor(from); if (from < 0) from += len; for (; from < len; from++) { if (from in this && this[from] === elt) return from; } return -1; }; }
以上列举的不兼容的问题解决方法只是众多兼容问题中的冰山一角,特别是HTML5和CSS3的出现让IE的兼容问题更加错综复杂,我们只有养成良好的编程习惯,在不断的实践中总结和避免兼容问题的处理方法,才能写出高质量代码的网页。
对于良好的编程习惯建议如下:
1、 CSS{}中的内容最好一个属性和值作为一行,不要担心写出来的CSS太长。
2、 在HTML中编写结构的时候要成对的写上注释,方便自己查找错误。
3、 每引入一个选择符都要用IE测试器以及火狐刷新测试,保证结构准确无误。
4、 尽量避免会造成兼容的写法,同时做到代码精简。