当前位置: 首页 > 图文教程 > 网页制作 > HTML/XHTML教程 > IE7与web标准设计系列教程:修正引起页面布局混乱的祸首

HTML/XHTML教程
一些不太常用的XHTML标签用法以及实例
网页中图片的设置涉及的三个问题
商业HTML邮件的制作建议
HTML Marquee 字符片段滚动
DOCTYPE 文档类型声明(网页爱好者必看)
纯HTML标签你熟悉多少?
HTML元素的ID和Name属性的区别
HTML meta的大作用
HTML标签tbody的用法与说明
HTML 特殊字符转换表
HTML基础 HTML的组成结构
HTML基础之HTML内容细则
Shtml 精简教程
浅谈html table 标签
html Frame、Iframe、Frameset 的区别
HTML 网页页面切换的各种变换效果
HTML的10个表格相关标记
让IE8启动IE7兼容模式的代码
HTML 结构化实现方法
xhtml的块级标记小结

HTML/XHTML教程 中的 IE7与web标准设计系列教程:修正引起页面布局混乱的祸首


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-04   浏览: 636 ::
收藏到网摘: n/a

原文链接:http://www.cnblogs.com/JustinYoung/archive/2008/02/25/IE7_wsRoad_overflow.html

前言

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

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

“不堪入目”的网页截图

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


图:这是在IE6中显示的效果截图,“十分完美”(点击查看完整大图)


这是在IE7中显示的“不堪入目”的效果截图(点击查看完整大图)

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

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


图:这是在IE6中显示的效果截图,还算“整齐”(点击查看完整大图)

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


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

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

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

补充资料:虚拟测试页面在FireFox中的显示结果。初学者不建议阅读(请直接转至第三页学习


图:这是在FireFox中显示的效果截图,已经乱的“令人抓狂”了(点击查看完整大图)

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

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


图:这是在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 <a href="http://justinyoung.cnblogs.com/" _fcksavedurl=""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共存方法(别人是别人的,我是我的)》)。


显然只有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开发中我常用到的小工具》

截图:


图:利用“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 <a href="http://justinyoung.cnblogs.com/" title="">http://justinyoung.cnblogs.com/</a>
</div>

</body>
</html>

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


利用“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 <a href="http://justinyoung.cnblogs.com/" title="">http://justinyoung.cnblogs.com/</a>
</div>

</body>
</html>

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


在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中显示一致了!


终于能即满足要求,又在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/>
可能有网站标题,就像<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>
</html>

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


利用min-height和css hack让容器在IE7和FireFox中自适应高度(点击查看完整大图)

后记

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