前端编程提高之旅(三)----浏览器兼容之IE6

来源:互联网 发布:大学生java培训课程 编辑:程序博客网 时间:2024/06/03 14:52

           在爱奇艺实习期间,乐帝主要负责移动端活动页面的制作,由于移动浏览器是随着智能手机兴起的,这就决定了移动端不会重蹈浏览器兼容问题的覆辙,一开始就比较好的支持web标准,而纵观整个互联网行业,移动web开发还处于起步阶段,在很长一段时间pc端web作为主要的服务形式还会继续。从小来说作为一名前端开发人员,不了解浏览器兼容也会贻笑大方。这篇文章基于《IE7web标准之道》,对浏览器兼容做一个概览。

   时间到了2014年,大概很少人会想到IE7发布之后,时隔这么多年IE6仍然占据市场7%的浏览器份额。如果开发面向大众的产品,7%的份额仍然不可忽视。百度提供了一个统计界面可查看浏览器份额,IE8和chrome占据了主要市场,在未来的一段时期内IE6仍然“发挥余热”。那么来看看IE6兼容问题。

   1.没有那么多选择器

<style type="text/css"> a[target="_blank"]{ padding-right:16px; background:url('http://images.cnblogs.com/cnblogs_com/justinyoung/common/outLink.gif') no-repeat right; } </style> </head> <body> <p> <a href="#" title="我不会跳转到其他网站,不会再新窗口打开">我不会跳转到其他网站,不会再新窗口打开</a> </p> <p> <a href="http://www.163.com" title="我会跳转到其他的网站,会在新窗口打开" target="_blank">我会跳转到其他的网站,会在新窗口打开</a> </p> </body> 

    这段代码给出了链接是否会跳转走的提示样式,像这样的选择器,如乐帝入行不久的人,用的都比较自然,读史使人明智,不读浏览器的进化史,不知IE6有多原始,IE6对比较复杂的css选择器都不支持,所以开发面向IE6的代码时,css选择器“简单粗暴”是比较好的方式。

<style type="text/css"> #txtName{ border:1px solid #eee; } #txtName:hover{ border:1px solid black; } </style> </head> <body> <input type="text" id="txtName" /> </body> 

   IE6是不支持任意元素实现伪类的。这一点比较现代的css伪类选择器的确使网页效果更绚丽。至于还有哪些不能用请参考(此页面)。

  2.IE6到现代浏览器引起布局混乱的原因

   w3c只是说,超出容器的内部不会被剪切。但是它并没有说,超出来的内容可以“撑开”容器。所以下面这个例子中IE7和FireFox的解释和渲染是正确的,而IE6则是错误的(因为它错误的认为,只有让容器内的内容“撑开”容器,才能让容器内的内容在超出时不被剪切)。

<style type="text/css"> #div1{ border:1px solid red; width:50px; /*word-wrap: break-word; *//*不允许内容撑开父容器,否则会出现IE6与其他浏览器布局显示不一致,造成混乱的问题,overflow: hidden;会影响内容正常显示*/ } </style> </head> <body> <div id="div1"> alonglonglonglonglonglonglonglonglongword from <a href="http://justinyoung.cnblogs.com/" title="">http://justinyoung.cnblogs.com/</a> </div> 

  上图是用IEtest模拟IE6情况下,上述代码显示情况,下图则是现代浏览器的显示情况。不难看出,IE6对内容不会被剪切的理解的确出现了问题。
   出现bug的条件:
  1. 无论是“宽度”的内容过长,还是“高度”的内容过长,都会引发此bug。
  2. 无论是文字、图片,还是任意有宽度和高度概念的“可见元素”,它们的“过宽”和“过高”都会引发此bug。
  3. 任意有宽度和高度概念的“可见元素”,它们在默认状态下的“overflow”样式的值都是“Visible”(即使你没有设置这个样式)
   从条件不难看出,图片或者文字内容超出父级div原有设置大小,都会触发bug。
    解决方案:
  • 设置外层div的css属性“word-wrap: break-word”解决。
  • 用“overflow: hidden”解决。
  • 就是根据宽度,将文本截取成多段,在每段后面强制加上换行符。
   以上三种方法都有各自劣势,第一种会造成二次伤害:浏览器显示进一步不一致。第二种方案影响对内容的查看。第三种方案添加了交互。低三种方案函数如下:
<script type="text/javascript">    // <![CDATA[    if(document.getElementById && !document.all) wordWarp4ff(6)/*数值6根据宽度需要发生变化*/    function wordWarp4ff(intLen){    var obj=document.getElementById("div1");    var strContent=obj.innerHTML;    var strTemp="";    while(strContent.length>intLen){    strTemp+=strContent.substr(0,intLen)+" "; //每六个字符加一个空格分隔,添加到临时的字符串中    strContent=strContent.substr(intLen,strContent.length);    }    strTemp+=" "+strContent;    obj.innerHTML=strTemp;    }    // ]]></script>

   纵向伸展的bug
   纵向伸展bug解决方案:只要我们让IE7和FireFox,也能像IE6中那样根据内容,自适应高度即可。如何才能让容器在IE7和FireFox中能够自适应高度呢?其实很简单,也是IE7的重要改进之一,使用“min-height”样式。虽然IE7中已经支持“min-height/min-width”和"max-height/max-width"样式。但是IE6却不认识这些"min-"、"max-"开头的样式,所以,我们还需要使用一个css hack为IE6设置一个“height”,只让IE6认识,IE7和FireFox都不认识。
<style>* { margin: 0; padding: 0; }#header {    width: 600px;    /*height:50px;注释掉下面两句,放出这一句,在FireFox和IE7中便能呈现bug*/    min-height:50px;/*只设置最小高度,让IE7和FireFox自适应高度*/    _height: 50px;/*采用只有IE6才认识到css hack,让不认识min-height的IE6也有很好的兼容性。*/    background-color: red;    margin:0 auto;/*居中显示*/}#body{    width:600px;    margin:0 auto;/*居中显示*/    background-color:blue;}#footer{    width:600px;    margin:0 auto;    background-color:#666;    clear:both;/*clear:both,让footer在新的一行显示,很多朋友对clear理解的不够透彻,我以后会特意出篇文章介绍这个样式,有兴趣的朋友可以关注我的博客http://justinyoung.cnblogs.com*/}</style></head><body><div id="header">    这里是头部的内容。<br/>    可能有网站标题,就像<a target="_blank" href="" title="">博客园</a>博客的标题、副标题。<br/>    也可能有导航栏在这里<br/>    <strong>注意这句话在IE7中的显示1</strong><br/>    <strong>注意这句话在IE7中的显示2</strong><br/></div><div id="body">  这里是主体的内容,随便你写啦。我就写上我的博客地址吧——<a target="_blank" href="http://justinyoung.cnblogs.com/" title="IE7的web标准之道">YES!B/S!</a> <p> 专注于B/S模式的项目。姓名:杨正祎(Justin Young),程序员,专注于B/S模式的项目开发,擅长于Web标准页面设计。</p>  <p>欢迎你们来为我的博客做客哦,里面有很多关于web标准方面的文章哦。请你们多多指教。</p>  <p>最后还要非常华丽的署名——杨正祎</p>  <p>日期当然也不能少啦——2008-2-21</p></div><!--end: body --><div id="footer"> 这里是footer,就放一些版权信息吧。&copy;<a target="_blank" href="http://justinyoung.cnblogs.com/" title="IE7的web标准之道">YES!B/S!</a></div><!--end: footer --></body>

   3.IE6重复文字bug
   
<!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=utf-8" /> <meta name="Keywords" content="YES!B/S!,web标准,杨正祎,博客园,实例代码" /> <meta name="Description" content="这是一个简单YES!B/S!文章示例页面,来自杨正祎的博客,http://justinyoung.cnblogs.com/" /> <title>YES!B/S!文章示例页面</title> </head> <body> <div style="width:200px;"> <div style="float:left;"></div> <!-- 如果是IE6,你将多看到一个“影”字 --> <div style="float:left;width:200px;">歌剧院的魅影</div> </div> </body> </html>

   上图是上述代码,在IEtest里IE6情况下显示情况,下面是现代浏览器展示情况,不难看出多出来一个字,即重复字bug。
   出现bug条件:
  • 一个容器包含2两个具有“float”样式的子容器。
  • 第二个容器的宽度大于父容器的宽度,或者父容器宽度减去第二个容器宽度的值小于3。(说到3,这里稍微多说一句——IE7还修正了IE6中的一个bug,bug名字就叫做“3像素bug”)
  • 在第二个容器前存在注释(这也是为什么此bug也叫做“IE6注释bug”的原因)。
  乐帝查看了注释bug在ietest不能复现这样的问题,有待考证。
  解决方案:
  • 改变结构,不出现【一个容器包含2两个具有“float”样式的子容器】的结构。
  • 减小第二个容器的宽度,使父容器宽度减去第二个容器宽度的值大于3,例如将本文示例中第二个子容器的宽度改为197px。
  • 去掉所有的注释。
    ——此解决方案的评论:最直接的做法,但是“没有注释的代码”,的确不是一个好的代码写作习惯。
  • 修正注释的写法。将 <!-- 这里是注释内容 -->写成<!--[if !IE]>这里是注释内容<![endif]-->
    ——此解决方案的评论:还不错的解决方案,但是并不是每个人都对<!--[if !IE]>这里是注释内容[endif]-->这种注释写法很欣赏。
  • 在第二个容器后面加一个或者多个<div style="clear"></div>来解决。
    ——此解决方案的评论:另人感觉很不爽的解决方案。但是的确能解决。影响网页效率
    以上解决方案中,都是针对bug出现的条件针对性的修改,个人认为最后一条解决方案较好。
   4.IE6 div元素一直被select元素覆盖
   文章中引用了另外一篇作者文章,这里面给出了出现这种情况的案例。
<style type="text/css">#divUp{    z-index:99;    position:absolute;    background-color:red;    width:100;    height:18;    overflow:hidden;    height:60px;}#ddlTest{    width:200;    z-index:1;}</style><body><div id="divUp">aaaaaaa<br>bbbbbbb<br>ccccccc</div><br/><select id="ddlTest"><option>test0<option>test1<option>test2<option>test3</select></html>

   上图分别是在IE6情况下和现代浏览器情况下,select与div不同上下层情况。可以看出IE6情况下,select元素不会随着z-index而隐藏到div下面。
   解决方案:
    在下拉列表上方加一个iframe,然后让div层浮在iframe上方,同时设置z-index值(div最大),这样,就能使div“盖住”下拉列表。
<style type="text/css">body{    font-size:small;}#zindexDiv{position:absolute;z-index:50;width:expression(this.nextSibling.offsetWidth);height:expression(this.nextSibling.offsetHeight);top:expression(this.nextSibling.offsetTop);left:expression(this.nextSibling.offsetLeft);/*background-color:green;在ff中将这句话放出来,你就会明白京叭、狼狗、主人的比喻*/}#divUp{z-index:99;position:absolute;background-color:red;width:100;height:18;overflow:hidden;height:60px;}#ddlTest{width:200;z-index:1;}</style><body><iframe id="zindexDiv" frameborder="0"></iframe><div id="divUp">aaaaaaa<br>bbbbbbb<br>ccccccc</div><br/><select id="ddlTest"><option>test0<option>test1<option>test2<option>test3</select></html>

  5.置换元素与行距的bug
 文章首先给出了置换元素的定义。然后请看示例代码:
<style type="text/css">#lineheight_bug {line-height: 39px;font-size:14px;background:url('http://images.cnblogs.com/cnblogs_com/justinyoung/2008_1q/rule.gif') no-repeat;padding:0;padding-left:20px;height:435px;width:530px;border:1px solid red;}</style></head><body><div id="lineheight_bug"><p>这是一个用来演示line-height bug的实例。它来自《IE7的web标准之道——6:(修正)置换元素与行距bug》一文。而这篇文章是属于《IE7的web标准之道》系列文章的。《IE7的web标准之道》系列文章是个文章系列,主要讲解了IE7相对于IE6各个方面的修正和改进。 <img src="http://images.cnblogs.com/cnblogs_com/justinyoung/common/wedgits_red.gif" alt="这就是置换元素的一种" /> 对于网页设计者从将网页设计从IE6平稳的过渡到IE7平台有一定的指导意义。现在《IE7的web标准之道》系列文章已经出道第六篇了。前面五篇的标题分别是:《IE7的web标准之道——1:前言(兼目录)》 ,《IE7的web标准之道——2:(改进)更丰富的CSS选择符》 ,《IE7的web标准之道——3:(修正)引起页面布局混乱的祸首 》 , 《IE7的web标准之道——4:(修正)歌剧院魅影bug 》 以及《IE7的web标准之道——5:(修正)上去了!终于上去了! 》。如果你有兴趣,可以访问http://justinyoung.cnblogs.com/。谢谢。</p></div></body>
  如上图所见,文字中因为多了一个图标,使得下面所有的文字都发生了向上的位移,造成严重的后果。
  引起bug的原因:
   之所以出现了这种bug,是因为IE6错误的将带有置换元素的那行文字的上下半间距,和相邻的上下两行的下上半间距合并到了一起。于是,带有置换元素的那行文字的上下行距就被减少了一半,所以页面出现了混乱。
  解决方案:
    对那些置换元素设置margin-top和margin-bottom。以便把被“压缩”的行间距“撑开”。
#lineheight_bug img{_margin:17px 0;_vertical-align: middle;}

  6.float双倍margin bug
      这个bug引发的条件极其简单,只要对块状容器元素设置了float和与float相同方向的margin值就会出现。
<!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=utf-8" /><meta name="Keywords" content="YES!B/S!,web标准,杨正祎,博客园,示例代码" /><meta name="Description" content="这是一个简单YES!B/S!文章示例页面,来自杨正祎的博客,http://justinyoung.cnblogs.com/" /><title>YES!B/S!文章示例页面</title><style type="text/css">body{background:url('http://images.cnblogs.com/cnblogs_com/justinyoung/myPic/rule.gif') no-repeat;margin:0;padding:0;}.floatbox {float: left;width: 100px;height: 100px;background-color:deeppink;margin-top: 20px;margin-left:100px;}</style></head><body><div class="floatbox"></div></body></html>

    从上面网页中的网格刻度线不难看出IE6双边距bug问题。
   解决方案:
    1.只要对产生bug的容器设置一个“display:inline;”样式就可以了。作者详细分析使用这种方法不会引起额外的问题。
.floatbox {    float: left;    width: 100px;    height: 100px;    background-color:deeppink;    margin-top: 20px;    margin-left:100px;        display:inline; /*多设置这个样式即可消除bug!*/}
  2.通过CSS hack修正bug
   即用只针对IE6的hack写法,多写一遍margin-left
.floatbox {    float: left;    width: 100px;    height: 100px;    background-color:deeppink;    margin-top: 20px;    margin-left:100px;        _margin-left:50px;/*只对IE6其作用的CSS hack,对数值减半*/}
  7.内容隐藏的文章,乐帝的IEtest没有复现,这里不予讨论。

  8.边线的混乱问题
<!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=utf-8" /><meta name="Keywords" content="YES!B/S!,web标准,杨正祎,博客园,实例代码" /><meta name="Description" content="这是一个简单YES!B/S!文章示例页面,来自杨正祎的博客,http://justinyoung.cnblogs.com/" /><title>YES!B/S!文章示例页面</title><style type="text/css">.divOuter {/*其实divOuter不是必须的,这里纯粹是为了提升视觉冲击力,你完全可以将其去掉*/border:5px dashed green;padding:10px;}.divInner {border:3px solid red;padding:10px;}.testDiv1 {border:1px dotted deeppink;margin-top:10px;}.testDiv2 {border:1px solid blue;margin-top:-1px;/*这个是重点*/}</style></head><body><div class="divOuter"><div class="divInner"><div class="testDiv1">我是divInner里的第1个Div区域。我的margin-top是正数。</div><div class="testDiv2">我是divInner里的第2个Div区域,我的margin-top是负值。</div></div></div></body></html>
 出现bug条件:
  • 两个块状元素(#testDiv1和#testDiv2)
  • 第二个块状元素(#testDiv2)有一个负值的margin-top
  • 然后把这两个块状元素放在一个大的块状元素中(#divInner)
  • 当然,为了他们都有可见的边框线(否则乱了你也看不到)
  解决方案:
  1. 对#divInner设置一个position:relative;
  2. 对#testDiv2也设置一个position:relative;
  3. 对#testDiv2设置一个负值的top,例如top:-1px;
     这里的解决方案总而言之就是采用相对定位,而不是margin-top实现定位,绕过问题也是解决办法。


0 0
原创粉丝点击