IE7的web标准之道——3:(修正)引起页面布局混乱的祸首


IE7的web标准之道

IE历来被web标准的拥护者所诟病,而当FireFox横空出世以后,更多的网页制作者开始关注web标准设计。看着FireFox的市场占有率不停的上升,微软终于推出了IE7。但IE7是否真的能够力挽狂澜,是否真的能够得到用户的信任,是否真的能够得到网页设计者的认可呢?

且看《IE7的web标准之道》系列文章,和你一起见证IE7的改变!

前言

现在,最令网页设计者头痛的问题就是网页在各个浏览器中的兼容性。而兼容性差最长见的,也是最令人恐惧的便是“页面布局混乱”。常常一个页面在IE6下显示的非常完美,而到了IE7(或者FireFox)中,则惨的“不堪入目”。到底是什么让这些页面那么的“水土不服”呢?

其实,这些都是IE6酿下的恶果,IE6对web标准的支持过于不足,甚至理解的有偏差,才导致了这些页面的“脆弱”。而IE7则修正了很多的那种“IE6对css解释和渲染”的bug。这种bug有很多。今天,这里只讲其中一个,但是确是最重要的一个,很多的“十分”混乱的页面都是它造成的。可以不客气地说,它简直就像“页面布局混乱黑帮”的幕后黑手,是引起页面布局混乱的祸首之一,而且是最大的一个。 它就是潜伏在网页背后的“‘overflow:visible’IE6渲染bug”。

“不堪入目”的网页截图

如果只是简单的说“‘overflow:visible’IE6渲染bug”,你可能完全没有印象。但是看看下面的这些“不堪入目”的网页截图,便能引起你心中那无限的伤感……

IE7的web标准之道
图:这是在IE6中显示的效果截图,“十分完美”(点击查看完整大图)
展开这里,查看在IE7中显示的效果截图
IE7的web标准之道
这是在IE7中显示的“不堪入目”的效果截图(点击查看完整大图)

上面的两张截图,是我2007年在高达软件公司的真实项目截图。可以看出,在IE7下的显示已经严重变形,虽然不影响软件的功能使用,但是已经严重的影响了用户的使用体验(没有人喜欢拖动横向滚动条)。

再看看下面的这个网页截图,它是我们今天将要使用的例子(源代码在下方有提供),是一个标准的“上左右下”带侧边栏的虚拟网页。

展开这里,查看、运行、保存【虚拟示例网页源代码】
提示:可以先在文本框内,根据需要修改代码后再运行
IE7的web标准之道
图:这是在IE6中显示的效果截图,还算“整齐”(点击查看完整大图)

而当你展开下面这个折叠区域,去看这个页面在IE7下显示的效果图的时候,可能便会大吃一惊了。

展开这里,查看在IE7中显示的效果截图
IE7的web标准之道
图:这是在IE7中显示的效果截图,已经“不堪入目”了(点击查看完整大图)

我们惊讶的看到,网页“头部”变“矮”了,最后两句重要的句子“消失”了;侧边栏变“窄”了,那个重要的网址的后半部消失了(其实是被右面绿色的区域遮盖住了);而最令人沮丧的是,右面“缺了个大口子”。原本整齐的布局,已经完全消失,出现的是一个“一塌糊涂”的页面。

到底是什么,将一个原本好好的页面“糟蹋”成这样?且看下面的详细讲解……

补充资料:虚拟测试页面在FireFox中的显示结果。初学者不建议阅读
IE7的web标准之道
图:这是在FireFox中显示的效果截图,已经乱的“令人抓狂”了(点击查看完整大图)

为什么在FireFox又有这么令人抓狂的显示呢?原来,这便是IE7的web标准之道的精髓了。随着web标准的推广和认可度的提高,IE7必须向web标准靠拢,但是有必须兼顾到,那些现在在IE6中还显示正常的亿万个已经存在的页面。这样矛盾就产生了——遵循标准就意味着页面会显示的乱七八糟,甚至无法浏览;但是如果太过于兼容IE6的那些烂摊子网页,又必然会离web标准越来越远。于是IE7走出了自己的web标准之道——绝对重视web标准,又稍微兼顾IE6的烂摊子。于是,IE7显示的那个页面虽然已经乱了,但是还不像在FireFox中显示的那样令人抓狂。

附:测试页面在Opera(版本9.25)中的显示效果截图(写文章的时候Opera正好有了新的升级版本)——

IE7的web标准之道
图:这是在Opera中显示的效果截图,“乱的程度”和FireFox是一样的(点击查看完整大图)
“非也,非也”

“千万别用IE7,IE7太垃圾了,浏览页面会出现布局混乱,一些在IE6中显示好好的页面,用IE7浏览布局就会混乱。”这种言论在网上会经常见到,好像是IE7才导致了那些页面的混乱。其实,非也,非也。

悟空说:“师父快快回避,且待我一棒打死这妖精!”
八戒说:“师父,那个姑娘俊俏的很,怎么会是妖怪呢?大师兄他骗人的!”
唐僧说:“那位施主,只是一平常人家的姑娘,定然不会是什么妖魔鬼怪。悟空你休得胡言论语。”
白骨精说:“ohYeah!2比1,看来这下安全了!”

那些IE7浏览时会出现布局混乱的页面,就如同利用妖术变了身的白骨精一样,在八戒和唐僧的凡眼看来就是个俊俏的姑娘。但是,在猴哥的“火眼金睛”下便立刻现了形。而那些布局和样式隐藏着bug的页面,在IE6的袒护和包庇下,化身成“完美页面”,招摇过市。但是在IE7的严厉的审核下,自然“原形毕露”、“bug层出”,从而导致布局混乱。但是,令人遗憾的却是——IE7被那些不知情的“凡骨俗胎”的人们咒骂、贬低、踩在脚底……这是一出悲剧!

表面原因——放纵的孩子和严厉的父亲

在2007年5月份的时候,我曾经写过一篇文章,叫做《IE6与IE7,放纵的孩子与严厉的父亲》。当时技术水平和对web标准的认知有限,所以写出来的这篇文章,虽然从表面合理的解释了造成布局混乱的原因,但是并没有说到根本上去。可谓“只知其一,不知其二”,但是这里依然推荐你阅读一篇。因为“先知其一,再知其二”将更有助于这“其二”的原因。

“其二”原因——IE6对“overflow:visible”的误解

为了兼顾到对overflow可能还不是很了解到朋友,这里是关于overflow样式的一些资料:W3C关于overflow的资料。请注意W3C对于visible参数的解释——

Visible: "This value indicates that content is not clipped, i.e.,it may be rendered outside the block box(注:后面这句可能是后续版本补充上来的)".

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

点击展开示例源代码
<! 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" >
        #div1
{
        border
: 1px solid red ;
        width
: 50px ;
        
}
    
</ style >
</ head >
< body >

< div  id ="div1" >
 alonglonglonglonglonglonglonglonglongword from 
< href ="http://justinyoung.cnblogs.com/"  title ="" > http://justinyoung.cnblogs.com/ </ a >
</ div >

</ body >
</ html >

下面是上面示例分别在IE6,IE7,FireFox(版本2.0.0,12)和Oepra(版本9.25)中的显示效果截图(IE6和IE7共存的方法,可以参考文章《IE6和IE7共存方法(别人是别人的,我是我的)》)。

IE7的web标准之道
显然只有IE6的渲染结果是“另类”的(点击查看完整大图)

从图片中我们可以看到IE7和FireFox的渲染结果是一样,IE6是个“坏孩子”,就不多说了,而Oepra的渲染结果和FireFox以及IE7也是有点差距的。但是这不是因为对overflow样式的理解有误差造成的,所以这里也不再扯开话题了。

何以称之为“祸首”

这篇文章的题目中,将这个bug称之为“引起页面布局混乱的祸首”。能被称之为“祸首”,自然有其“强悍”的地方。那它到底强悍在什么地方呢?其实,很简单,就3条——

  1. 无论是“宽度”的内容过长,还是“高度”的内容过长,都会引发此bug。
  2. 无论是文字、图片,还是任意有宽度和高度概念的“可见元素”,它们的“过宽”和“过高”都会引发此bug。
  3. 任意有宽度和高度概念的“可见元素”,它们在默认状态下的“overflow”样式的值都是“Visible”(即使你没有设置这个样式)。
补充资料:利用“IE Developer Toolbar”得到元素样式的默认值

有些朋友可能会问,你怎么知道任意有宽度和高度概念的“可见元素”,它们在默认状态下的“overflow”样式的值都是“Visible”的呢?

其实方法很简单,利用IE Developer Toolbar这个工具就可以知道了。下面的文章和截图,可能会对你有帮助——

文章: 《介绍两个,b/s开发中我常用到的小工具》

截图:

IE7的web标准之道
图:利用“IE Developer Toolbar”得到元素样式的默认值(点击查看完整大图)
如何修复bug

其实这个bug,我们还是有办法修复的,但都不是很完美的解决方案,想要取得较好的效果,还需要一些技巧。下面便是我工作中总结的一套解决方案。小弟才疏,众多不对之处,还请各位高手指教。

修正这个bug首先要洗脑一下,因为错误的认识将不利于你对解决方法的理解。

  1. 虽然,那个虚拟的示例网页在IE6中能够“完美的”显示,但是它并不是正确的。我们不能通过css hack的方法让它在FireFox和IE7中显示“靠近”IE6,而是应该“拔下”IE6的那层虚假的“皮”,重新塑造网页,从而让它在IE6、IE7和FireFox中都能正常显示。
  2. 就算让网页在IE6、IE7和FireFox中,都可以正常显示了,但却未必就是最终想要的效果。
  3. 为了达到最终想要的结果,可能需要使用不推荐使用的措施——css hack。
如何解决“横向撑开”问题
用“word-wrap: break-word”解决

导致布局混乱的主要原因,是IE6对overflow的visible的错误解释,才导致宽度被“撑开”才造成的。所以,我们必须采取措施,让IE6中容器不能那么“放纵孩子”才可以。方法就是使用“word-wrap: break-word”样式(IE特有,FireFox不起任何作用),强制要求容器内的内容不允许“撑开”父容器。下面的示例可能有助于理解。

点击展开示例源代码
<! 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" >
        #div1
{
        border
: 1px solid red ;
        width
: 50px ;
        word-wrap
:  break-word ;
        
}
    
</ style >
</ head >
< body >

< div  id ="div1" >
 alonglonglonglonglonglonglonglonglongword from 
< href ="http://justinyoung.cnblogs.com/"  title ="" > http://justinyoung.cnblogs.com/ </ a >
</ div >

</ body >
</ html >

利用“word-wrap: break-word”可以让IE6中的“孩子”乖乖的待在“父亲”的允许访问内。如下图所示——

IE7的web标准之道
利用“word-wrap: break-word”后,即使在IE6中,容器也不再被“撑开”(点击查看完整大图)
用“overflow: hidden”解决

显然,用“word-wrap: break-word”又导致了IE(IE6和IE7)和FireFox的显示结果新的不一致。那还有没有其他的办法呢?“擒贼先擒王”,既然是“overflow: visible”导致的bug,那直接改变“overflow”的值不就可以了吗?所以,使用“overflow: hidden”便能让IE6、IE7和FireFox显示一直。下面的这个示例,可能会有助于你的理解——

点击展开示例源代码
<! 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" >
        #div1
{
        border
: 1px solid red ;
        width
: 50px ;
        overflow
:  hidden ;
        
}
    
</ style >
</ head >
< body >

< div  id ="div1" >
 alonglonglonglonglonglonglonglonglongword from 
< href ="http://justinyoung.cnblogs.com/"  title ="" > http://justinyoung.cnblogs.com/ </ a >
</ div >

</ body >
</ html >

下面是在IE6、IE7和FireFox中的现实效果截图。

IE7的web标准之道
在IE6、IE7和FireFox中终于显示一致了(点击查看完整大图)
一个大问题与残缺的美丽

从截图看,网页在IE6、IE7和FireFox中的确显示一致了(就布局显示而言)。但是,却发现了一个大问题!那就是——这并不是我想要的结果呀。假使这里的div是一个侧边栏,我们只是要求,它老老实实的那么“宽”,不要乱“撑”宽度就可以了,内容我们还是要看的呀,你不能把内容都剪切了不让我看呀。

如何让“很长度文字”换行显示呢?其实在前面我们已经使用到了,那就是“word-wrap: break-word”。虽然它是IE的特有样式,但是足以先解决IE6和IE7中的问题。但是FireFox中没有这个样式,那FireFox下如何使“很长文字”自动换行显示呢?我们遗憾的发现FireFox并没有提供类似的样式供我们使用,目前唯一的解决方案是利用JavaScript实现。原理很简单,就是根据宽度,将文本截取成多段,在每段后面强制加上换行符。下面的实现示例可能会有助于你的理解——

点击展开示例源代码
<! 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" >
        #div1
{
        border
: 1px solid red ;
        width
: 50px ;
        word-wrap
:  break-word ;
        
}
    
</ style >
</ head >
< body >

< div  id ="div1" >
alonglonglonglonglonglonglonglonglongword from http://justinyoung.cnblogs.com/

</ div >


< 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 >
</ body >
</ html >

看着下面的截图,终于能即满足要求,又在IE6、IE7和FireFox中显示一致了!

IE7的web标准之道
终于能即满足要求,又在IE6、IE7和FireFox中显示一致了(点击查看完整大图)

但是,如同残缺的美丽,惊艳的美隐藏着巨大的缺憾。令人遗憾是——如果容器中的内容,不是文字,而是图片时,这种方法将无能为力。只能将容器放宽,或者缩小图片,当然,你也可以使用“overflow: hidden”将超出的内容剪切掉。另一个遗憾是——在FireFox中,div1容器里面的标签和样式也将失去,只留下文本……

另一个“焦油坑”——“纵向撑开”

上面解决方法,只是“横向”的、宽度的问题,其实“‘overflow:visible’IE6渲染bug”,同样也会引起纵向的、高度方面的页面布局混乱。解决“纵向撑开bug”和解决“横向撑开bug”需要采用完全不同的解决方案。但是,相比“纵向撑开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都不认识。通过这篇文章 《实例讲解符合中国特色的和网络现状的实用CSS Hack(附源码)》 便可以找到应该使用的css hack。下面的示例可能会有助于你理解此解决方法——

点击展开示例源代码
<! 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 >
{  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 />
    可能有网站标题,就像
< target ="_blank"  href =""  title ="" > 博客园 </ a > 博客的标题、副标题。 < br />
    也可能有导航栏在这里
< br />
    
< strong > 注意这句话在IE7中的显示1 </ strong >< br />
    
< strong > 注意这句话在IE7中的显示2 </ strong >< br />
</ div >
< div  id ="body" >

  这里是主体的内容,随便你写啦。我就写上我的博客地址吧——
< 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; < target ="_blank"  href ="http://justinyoung.cnblogs.com/"  title ="IE7的web标准之道" > YES!B/S! </ a >
</ div > <!-- end: footer  -->
</ body >
</ html >

下面是修正后页面的效果截图,在IE6、IE7和FireFox总都是令人满意的显示结果。

IE7的web标准之道
利用min-height和css hack让容器在IE7和FireFox中自适应高度(点击查看完整大图)
后记

对于最容易引起网页布局混乱的“‘overflow:visible’IE6渲染bug”,上面从多个方向和角度进行了讲解。虽然有些方面还不能有完美的解决方案,但是在更理性的解决方案出现之前,暂时也是没有办法的事情,只能留个遗憾在那里,因为我们还要继续前进……

相关文章列表
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值