浏览器兼容之旅的第五站:IE常见Bug——part3

编辑推荐: 掘金是一个高质量的技术社区,从 CSS 到 Vue.js,性能优化到开源类库,让你不错过前端开发的每一个技术干货。 点击链接查看最新前端内容,或到各大应用市场搜索「 掘金」下载APP,技术干货尽在掌握中。

有关于IE的Bug系列,我们前面一共介绍了四个部分:

  1. 创建IE条件样式——《浏览器兼容之旅的第一站:如何创建条件样式》;
  2. 浏览器各种Hack写法——《浏览器兼容之旅的第二站:各浏览器的Hack写法》;
  3. IE下十个经典Bug——《浏览器兼容之旅的第三站:IE常见Bug——part1》;
  4. IE下另十个常见Bug——《浏览器兼容之旅的第四站:IE常见Bug——part2》。

今天继续我们浏览器兼容之旅的第五站——也是IE下的Bug。这些Bug相对来说并不常见,比如说“z-index”,"ie6下的fixed",“下拉选择项宽度”等Bug,这些Bug相对来说很少见,对于追求完美的用户来说,还是时常会碰到的,那么你对这些Bug是不是能药到病除呢?如果还不能,那就继续我们今天的内容吧。

一、修复IE下Select中Option的宽度

这个Bug是发生在<select>上的,而且是相当的明显,当你在<select>上设置了一个静态的宽度时,当其<option>选项内容超过设置的宽度时,其内容也将直接被截,这种现像只发生在Ie6-7中,在其浏览器中并无此Bug,如下图所示:

如何解决上图那样的Bug。我在CSS-TRICKSSelect Cuts Off Options In IE (Fix)使用了jQuery方法来解决。当元素在静态下(未触发select中的option选项时)使用有一个宽度值来设置<select>,在IE下时,鼠标移动到select的option选项中,宽度变成自动,以适合内容字段的宽度,当鼠标移出时又回到表态宽度的设置,具体实现的jQuery代码如下所示:

jQuery Code

		$(function() {
		    $("select").mouseover(function(){
		      $(this).data("origWidth", $(this).css("width")).css("width", "auto");
		    }).mouseout(function(){
		      $(this).css("width", $(this).data("origWidth"));
		    });
			});
	

二、修复Ie6下position:fixed的Bug

大家都知道position中取值为“fixed”时,IE6浏览器不能识别这个属性(IE6真是SB),这样一来给我们有时候的制作带来极大的了限制。对于不使用IE6的朋友来说也就没什么了,但对于还在苦战IE6的朋友来说,那还真是件难缠的事,于是我在浪中倒了一回,找到一个完美解决IE6不支持position:fixed的bug方法。

前几天在群中看到有朋友说通过html和body设置成如下形式:

		html{overflow: hidden;}
		body{height: 100%;overflow: auto;}
	

通过在html和body进行上面的设置能解决IE6下position:fixed的Bug,但这个方法存在一个极大的隐患:会使用页面上原有的position设置都变成fixed效果,比如说你页面上设置了position:absolute;或position:relative,此时他们都自动变成position:fixed。所以说这种方法解决了fixed的bug,但同时又增加了一个新的Bug,也等于没解决。

如此一来,我们还是使用原始的方法——通过CSS的expression表达式来解决IE6下的position:fixed效果。不过这种方法解决了问题,但也有一个不好的地方,极其占用你的性能资源,所以使用之时请考虑清楚,下面我们一起来看解决的方法。

IE6特有方法

		.ie6fixed {
			position:absolute;
			left:expression(eval(document.documentElement.scrollLeft));
			top:expression(eval(document.documentElement.scrollTop));
		}
	

IE6以外的浏览器

IE6以外的浏览器都识别这个属性,所以我们无需做其它的处理,按照正常方式书写就OK,比如下面的代码:

		html>body .ie6fixed {
			position: fixed;
			left:0;
			top:0;
		}
	

上面只是一个简单的例子,在实际应用中,上面的方法就能帮你解决月IE6下的fixed的Bug了,但还有一个问题,就是会出现闪屏的问题,那么可以按下面这个方法来解决:使用background-attachment:fixed为body或html设置一个background-image。而此处的background-image无需真实的图片,你可以这样使用“background-image:url(about:blank);background-attachment:fixed;”,这样就能解决闪屏的问题

下面看一个Demo吧

HTML Markup

		<body>
			<div class="ie6fixedLT ie6fixed">IE6完美兼容position:fixed</div>
			<div class="ie6fixedRT ie6fixed">IE6完美兼容position:fixed</div>
			<div class="ie6fixedLB ie6fixed">IE6完美兼容position:fixed</div>
			<div class="ie6fixedRB ie6fixed">IE6完美兼容position:fixed</div>
		
	

CSS Code

		.ie6fixed {border: 1px solid red; padding: 5px;}
		* 修正IE6振动bug */
		* html,* html body{background-image:url(about:blank);background-attachment:fixed}
 .ie6fixedLT{position:absolute;left:expression(eval(document.documentElement.scrollLeft));top:expression(eval(document.documentElement.scrollTop))}
 .ie6fixedRT{position:absolute;right:expression(eval(document.documentElement.scrollLeft));top:expression(eval(document.documentElement.scrollTop))}
 .ie6fixedLB{position:absolute;left:expression(eval(document.documentElement.scrollLeft+document.documentElement.clientWidth-this.offsetWidth)-(parseInt(this.currentStyle.marginLeft,10)||0)-(parseInt(this.currentStyle.marginRight,10)||0));top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-this.offsetHeight-(parseInt(this.currentStyle.marginTop,10)||0)-(parseInt(this.currentStyle.marginBottom,10)||0)))}
 .ie6fixedRB{position:absolute;right:expression(eval(document.documentElement.scrollLeft+document.documentElement.clientWidth-this.offsetWidth)-(parseInt(this.currentStyle.marginLeft,10)||0)-(parseInt(this.currentStyle.marginRight,10)||0));top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-this.offsetHeight-(parseInt(this.currentStyle.marginTop,10)||0)-(parseInt(this.currentStyle.marginBottom,10)||0)))}
		html>body	.ie6fixedLT{position:fixed;left:0;top:0}
		html>>body	.ie6fixedRT{position:fixed;right:0;top:0}
		html>body	.ie6fixedLB{position:fixed;left:0;bottom:0}
		html>body	.ie6fixedRB{position:fixed;right:0;bottom:0}
	

最后再次感谢胡尐睿给我们带来这么好的解决办法——《完美解决IE6不支持position:fixed的bug》另外大家还可以参考这里的Demo

三、DOCTYPE引起的Bug

DOCTYPE引起的IE的bug一般来说只会发生在初学者的身上,因为那时候他还不太了解这个DOCTYPE的作用。往往页你的页面头部少了这个DOCTYPE时,你的IE就会以怪异模式去解析,从而产生的Bug就无法想像了。所以你应该在每个(X)HTML页面的顶部放置一个DOCTYPE,现在常用的就是:

		<!DOCTYPE HTML>
	

四、避免百分比尺寸

百分比为单位对于IE6来说不怎么友好,容易混淆。除非你知道每一个父元素的尺寸,这样才能更好的避免,但你仍然可以在别的浏览器使用百分比,而在IE6下使用固定值,如:

		body {
			margin: 2% 0 !important;
			margin: 20px 0;/*只有IE6才能识别*/
		}
	

说到“!important”,他不被IE识别的,当然你也可以使用更高级的选择器来代替“!important”的功能,如min-height的写法,我们平时都一般是这样写的:

		#element {
			min-height: 100px;
			height: auto !important;
			height: 100px;
		}
	

其实我们还可以使用下面这样的方法来写:

		#element {
			min-height: 100px;
			height: 100px;
		}
		
		html>body #element {
			height: auto !important;/*IE6不识别*/
		}
	

五、IE6下多类名的Bug

这个Bug我整了好久才明白其意思,记得前面在《CSS3 选择器——基本选择器》介绍过IE6下不支持“.className1.className2”这样的选择器,其实并不是说不支持其语法,只是在IE6下对这个有不同的解析。

在编写CSS时,使用多个类是一种很好的写法,比如说在一个基类上写一些默认样式,然后加上一个额外的类来写不同的样式。这是一种技术,我也经常这样使用。比如说有了一div.box的基本模块,然后给其增加附加的类,并为这个基本模块设置新的样式,我这样说可能不太好理解,我们来看下面的代码:

HTML Markup

		<div class="box">
			<div class="header">My Friends</div>
			<div class="content">Graham Blache</div>
		</div>
		<div class="box featured">
			<div class="header">My Friends</div>
			<div class="content">inside box and featured</div>
		</div>
	

CSS Code

		.box {border: 1px solid #e1dfd6;margin-bottom: 10px;}
		.box .header {padding: 6px 30px 0 10px;margin: 0 0 5px 0;background: #f2f0dd;}
		.box.featured {background-color: #f5fbea;}
		.box.featured .header {background-color: #e9f5ce;}
	

这样一来,你的<div class="box featured">就会同时具有“.box”和.box.featured两个类的样式,其实这样在IE6下同样具有这两个类的样式,如下图看示:

但是你仔细测试后,你会发现IE6下会有一个很怪的问题,如:

		.box.featured{background-color: #f5fbea;}
		.featured{background-color: #f5fbea;}
	

上面两行代码,在IE6是不会有区别的,换句话说“.box.featured”在IE6下能同时运用在<div class="box featured">;和<div class="featured">两个元素中,而别的浏览器上只能应用在<div class="box featured">,这就是IE6下多类的一个Bug。他无法区分.box.featured和.featured。具体来看他们的区别:

大多数情况下之下是不会有什么问题的,下面我们来看一个有问题的实例:

HTML Markup

		<ul class="test">
			<li class="odd"><a href="">item1</a></li>
			<li class="even"><a href="">item2</a></li>
			<li class="odd current"><a href="">item3</a></li>
			<li class="even"><a href="">item4</a></li>
			<li class="odd"><a href="">item5</a></li>
			<li class="even current"><a href="">item6</a></li>
			<li class="odd"><a href="">item7</a></li>
		</ul>
	

CSS Code

		.test a {display:block;height: 1em;}
		.test .odd a{background-color: #ccc;color:orange;}
		.test .even a{background-color: lime;color:green;}
		.test .odd.current a{background-color: #000;color:#fff;}
		.test .even.current a{background-color: #fff;color: #000;}
	

效果

从图中我们就可以知道,IE6下出问题了,因为他没法区分".odd.current"和".odd",最终以最后的“.current”结尾的样式覆盖前面的样式。大家注意了在IE6底下对".className1.className2"解析是以后面的类为主,比如说你的样式中存在“.className1{}”和".className2"以及".className1.className2";那么在ie6下".className1.className2"将会“.className2”样式为主。比如我们将上面的代码改一下:

			.test a {display:block;height: 1em;}
			.test .odd a{background-color: #ccc;color:orange;}
			.test .even a{background-color: lime;color:green;}
			.test .odd.current a{background-color: #000;color:#fff;}
			.test .even.current a{background-color: #fff;color: #000;}
			.test .current.odd a{background-color: red;color:#fff;}
			.test .current.even a{background-color: blue;color: #000;}
	

从上图中,可以明白了他们的区别吧,要是还没有明白,可以自己在尝试几回,所以在后面使用多类的写法,还是要多注意,如果你要兼容IE6的话。安全的解决之法:其一单独为他们创建类,并设置相对应的样式;其二将其中一个类定义到其父元素之上,通过等 级继承关系来设置,这样就不会出现上述的现像。。如果大家对这个Bug还没有理解清楚,可以点击《Multiple Classes in IE》和《The two CSS Selector bugs in IE6》。

六、IE6浮动引起的Bug

这里要说两个浮动引起的bug,先来看第一个浮动引起的问题

HTML Markup

		<ul>
			<li><a href="#">HELLO WORLD</a></li>
			<li><a href="#">HELLO WORLD</a></li>
			<li><a href="#">HELLO WORLD</a></li>
			<li><a href="#">HELLO WORLD</a></li>
			<li><a href="#">HELLO WORLD</a></li>
			<li><a href="#">HELLO WORLD</a></li>
		</ul>
	

CSS Code

		li {
			float: left;
			display: block;
		}
		li a {
			display: block;
			height: 30px;
			margin-right: 10px;
		}
	

上面的代码展现的是:在一个没有设定宽度的浮动元素时,哪果其子元素触发了hasLayout,并且没有设定宽度,那么他们都会以100%宽度展示,占据整个宽度。就如上面代码,工元素触发了haslayout,但是没有设定宽度,在IE6里会产生换行,如下图所示:

欲解决这样的Bug我们可以这样做:

方法一:

给a或者li一个明确的宽度

方法二

给a和li同时一个float设置。

上面的代码还会有另外一个bug出现,当li没有设置明确的宽度时,而其容器的宽度不足够展示时,在别的浏览器都会下沉到另一行,可是在IE6下却会让li里面的文本换行,导致布局混乱,下面是产生这个Bug的css代码:

		ul {
			list-style: none;
		}
		li {
			float: left;
		}
		li a {
			margin-right: 10px;
		}
	

如下图所示:

欲解决上面的bug你可以参考下面的方法:

给元素加上withe-space:nowrap(具体使用方法可以参考《CSS3 Word-wrap》);其二在li上显式的设置一个宽度值。

七、IE6下的100%高度的Bug

在IE6下,如果要给元素定义100%高度,必须要明确定义它的父级元素的高度,如果你需要给元素定义满屏的高度,就得先给html和body定义 height:100%;。

八、浮动层错位

当内容超出外包容器定义的宽度时,在IE6中容器会忽视定义的width值,宽度会错误地随内容宽度增长而增长。浮动层错位问题在IE6下没有真正让人满意的解决方法,虽然可以使用overflow:hidden;或overflow:scroll;来修正, 但hidden容易导致其他一些问题,scroll会破坏设计;JavaScript也没法很好地解决这个问题。所以建议是一定要在布局上避免这个问题发 生,使用一个固定的布局或者控制好内容的宽度(给内层加width)

九、绝对定位元素的1像素间距bug

IE6下的这个错误是由于进位处理误差造成(IE7已修复),当绝对定位元素的父元素高或宽为奇数时,bottom和right会产生错误。唯一的 解决办法就是给父元素定义明确的高宽值,但对于液态布局没有完美的解决方法。

十、3像素间距bug

在IE6中,当文本(或无浮动元素)跟在一个浮动的元素之后,文本和这个浮动元素之间会多出3像素的间隔。给浮动层添加 display:inline 和 -3px 负值margin。给中间的内容层定义 margin-right 以纠正-3px

十一、IE6调整窗口大小的 Bug

当把body居中放置,改变IE浏览器大小的时候,任何在body里面的相对定位元素都会固定不动了。解决办法:给body定义 position:relative;就行了。

今天又收集了IE6的十一种Bug,那么今天我们三个系列下来总供收集了差不多三十种不同的IE的Bug以供大家参考,下面提供几个链接以供大家参考,也是涉及IE的bug的处理方法:

  1. Explorer Exposed!
  2. 处理IE下的hover状态下image放大的Bug——《IE6 中 a:hover 的bug
  3. 打败 IE 的葵花宝典:CSS Bug Table
  4. Ultimate IE6 Cheatsheet: How To Fix 25+ Internet Explorer 6 Bugs
  5. Internet Explorer CSS Bugs

到今天为此有关于IE下的Bug的系列就算全部介绍完成了,希望这个系列对大家平时中处理 IE的兼容问题有所帮助。

如需转载烦请注明出处:W3CPLUS

返回顶部