欲练CSS ,必先解决IE的一些细节分析

更加坏的事情是,即使你仅仅针对IE设计,不考虑其它浏览器,由于IE模型绝对可以说是一只让人难以捉摸其脾气的怪物,所以你单纯为IE设计也会遇到众多难题,发现很多的效果总是绕来绕去都难以实现。

我们都知道,XHTML+CSS的目标就是实现内容与表现分离,理论上对于任何特定一份内容,我们都可以通过CSS实现任何我们想要的表现形式,或者细致地说是布局形式。虽然现实与这个目标有一定差距,但是CSS已经能够满足大多数常见的布局需求,这有CSS Zen Garden为证。然而如果你用的是IE,因为它难以捉摸,所以如果你想用一种简单优雅的CSS去让IE能够实现“任何你想要的布局形式”,那是不可能的,只有复杂繁缛的CSS才能够在IE上满足你的需求。我曾经提到过一种理论,“一个人对一个研究方向是否感兴趣很可能是完全靠偶然事件决定的,这就好像人第一次打羽毛球,如果你赢了几盘你就会感兴趣,如果你一直都赢不了你就会没兴趣”。IE在需要复杂繁缛的CSS这一点上,就足以令大多数的入门者却步。你总感觉到不得要领,你自然没兴趣学下去。

举一个例子说明这个问题,例如你不知道IE有hasLayout这回事,一个元素是否hasLayout对它的布局方式有重大影响,于是你肯定用最简单的思维去思考CSS,认为不同的CSS规则之间应该是松耦合的。“CSS应该被设计为简单优雅的”,你肯定会这样想,没错,它确实被设计为这样,不过IE不是这样去实现CSS罢了。我们用下面的代码去证明IE在quirks mode与standards mode之间的区别:
<div style="background-color: red; height: 30px">
  <div>Hello</div>
  <img style="float: left; width: 200px; height: 160px" src="blank.gif" />
  <div>Hello</div>
</div>

首先,我们用quirks mode看看结果如何,并且一个初学者看到这样的结果会去如何理解CSS规则。在quirks mode中,我们可以看到背景为红色的<div />包含了上面1行的文本,以及下面向左浮动的<img />(自然也就包括在浮动块右边的文本),在这里,我们可以建立两种认识:

  1. 容器是完整包含内容的,当内容的总高度比容器大的时候,容器就会自然伸展以确保容纳内容。
  2. 浮动块也属于上述条件所要求通过伸展以确保容纳内容。

以上规则是完全错误的,一个懂得标准CSS以及理解quirks mode的设计师将会如此解释他的理解:

  1. 因为IE在quirks mode中会将height理解为min-height,所以它认为<div />的高度不小于height指定的30px即可。而根据CSS标准,当height设置为30px时,高度就一定是30px,超出部分如何处理则由专门的CSS规则决定。
  2. 因为<div />被设置了height属性,在IE中这就让它hasLayout了,这就导致它一定要包含所有的内容,包括浮动块。而根据CSS标准,浮动块是无需被完全包含的,它就浮动在那里,除非遇到设置了clear属性的元素,否则后继内容只会侧移避让。

好了,相信这个对比足以说明问题的严重性了,通过IE的效果去理解CSS,最终只会让你的理解与真实的CSS相差甚远。详细的standards mode与quirks mode带来的标准执行差别,可以参考这篇文章:CSS Quirks mode and strict mode

然后肯定有人要问我,如果通过doctype确保使用的是standards mode,那是不是就没问题了呢?standards mode确实会让IE对CSS的解释合理很多,但事情并没有那么简单,这你可以通过实践去慢慢体会。你可以尝试在standards mode中设计CSS,并且尽力保持它们在IE/FF/Opera/Safari这4大主流浏览器中显示一致,随着设计的进行,你会发现这不是那么容易做到的。或许你不乐意花时间去fix其中的一些小问题,宁愿任由其中一些浏览器的用户看到比较丑陋的布局,但至少你已经了解到一个和上面例子类似的道理:不同浏览器即使同样在standards mode,其对CSS的理解仍然有所差异,而差异当中最多只可能有一个是正确的,甚至可能全部都是错误的。这篇CSS contents and browser compatibility就列举了众多浏览器对CSS支持的差异,一份CSS总会因为其中有一些规则在某些浏览器上是不支持的或者是buggy的,而导致你难以保持它们在不同浏览器上显示一致。

接下来可能还有人会问我,既然IE的市场份额最大(特别是在入门级的用户当中),又或者说我的客户指定使用IE作为客户端,仅仅针对IE设计CSS不好吗?为什么要针对FF之类的标准浏览器设计CSS然后再为IE进行fix?因为IE难以捉摸的脾气,让你无法将它的行为理解为一种简单优雅的规则,然后让你陷入CSS规则高度耦合的困境中。请看下面的例子:
<div style="background-color: red; border: 2px black solid">
  <img style="float: left; width: 200px; height: 160px" src="blank.gif" />
  <div>Hello</div>
</div>
<div>Hello</div>

现在,你在IE中看到的效果应该是左边出现<img />,然后两个<div />内的Hello都向右偏移以避让<img />这个浮动块了,其中上面的<div />仅仅占用移行的高度,因为它没有声明高度,所以就是自然高度,也就是一样,这些都很好理解,所有规则都是解耦的。然后向例子中增加对第一个<div />的width属性复制,看看结果会如何:
<div style="background-color: red; border: 2px black solid; width: 600px">
  <img style="float: left; width: 200px; height: 160px" src="blank.gif" />
  <div>Hello</div>
</div>
<div>Hello</div>

这时候第一个<div />完全容纳了<img />,把第二个<div />挤到下面了。这该怎么解释呢?我们可没有设置它的height属性哦,难道又犯之前例子所说的因为hasLayout而必须容纳所有内容?正解,这就是IE难以驯服的地方,一个应该是完全独立的width属性,设置之后引起了高度以外的其它影响,这让人无法尝试以一种简单优雅的方式去理解IE的行为。这就证明了,如果你要学习如何为IE设计CSS,就先要学习标准CSS,再加上对IE怪异行为的理解,比仅仅学习如何为一个标准浏览器设计要难多了。这时候你是不是想说,“如果客户愿意放弃IE,甚至全世界都愿意放弃IE,那就实在太美好了”,没错,这才是正确的想法,一心想着仅针对IE设计以求方便只会让你走火入魔。

最后,如果你已经有了一定的CSS基础,对CSS规则都理解无偏差,却缺乏组合CSS规则的想象力,无法做到所谓的“实现任何你想要的布局效果”,这也就是说,你的内功已练成,仅仅差一些表面的套路,这时候我推荐你去看《CSS Mastery/精通CSS》。看完这本书,相信你只会觉得自己缺乏布局的创造能力,而不会有布局却不知道如何实现。另外,如果你关注CSS方面的内容,可以考虑订阅我的blog:

过年之后,我可能会写一些与ASP.NET+CSS有关的文章,因为现在ASP.NET+CSS的开发并不方便,即使用了ASP.NET 2.0 CSS Friendly Control Adapters也如此,因此需要根据自己的实际情况定制配对的Control Adapter才能解决问题,这就是我接下来要研究的事情。

(0)

相关推荐

  • 欲练CSS ,必先解决IE的一些细节分析

    更加坏的事情是,即使你仅仅针对IE设计,不考虑其它浏览器,由于IE模型绝对可以说是一只让人难以捉摸其脾气的怪物,所以你单纯为IE设计也会遇到众多难题,发现很多的效果总是绕来绕去都难以实现. 我们都知道,XHTML+CSS的目标就是实现内容与表现分离,理论上对于任何特定一份内容,我们都可以通过CSS实现任何我们想要的表现形式,或者细致地说是布局形式.虽然现实与这个目标有一定差距,但是CSS已经能够满足大多数常见的布局需求,这有CSS Zen Garden为证.然而如果你用的是IE,因为它难以捉摸,

  • nginx 部署 vue 项目找不到js css文件的解决方法

    很多时候 npm run build 之后, index.html 文件中webpack 自动插入的 js 文件 css 文件的相对目录总是不对,发布到服务器上之后,nginx 找不到文件. vue-cli@3 在 vue-cli@3 中你需要为你 webpack 插入到 index.html 中 的所有文件添加一个 baseUrl. 你需要在项目的根目录新建一个 vue.config.js, 添加如下内容: ... module.exports = { baseUrl: isProd ? '/

  • CSS中box(盒模式)的分析

    本篇用box的图例,对CSS中box(盒模式)的分析,为学习CSS的读者建立了清楚的模型. W3C定义的盒模式如下: width和height定义的是Content部分的宽度和高度,padding border margin的宽度依次加在外面.背景会填充padding和content部分.但是由于浏览器设计上的问题,不同浏览器显示效果会有些不同.左右Margin加倍的问题当box为float时,IE6中box左右的margin会加倍 左面的inner的左面margin明显大于5px.这时候,定义

  • Go语言开发必知的一个内存模型细节

    目录 引言 内存模型定义是什么 happens-before 是什么 A 不一定 happens-before B Go 语言中的 happens-before 定义 Go Channel 实例 例子 1 例子 2 例子 3 例子 4 总结 引言 在日常工作中,如果我们能够了解 Go 语言内存模型,那会带来非常大的作用.这样在看一些极端情况,又或是变态面试题的时候,就能够明白程序运行表现下的很多根本原因了. 当然,靠一篇普通文章讲完 Go 内存模型,不可能.因此今天这篇文章,把重点划在给大家讲解

  • asp.net2.0中css失效的解决方法

    1,CSS文件路径不正确这个问题属于Web开发中的基础问题,一般采用相对路径会出现这样的问题,或者样式文件写在了母版页里面,在内容页与母版页不在同一级目录下时会出现这样的问题.此时你要清楚Web中相对路径的规则,如果你不清楚,可以采用绝对路径的写法试试就知道是不是路径的问题了. 2,CSS规则写法错误这个问题谁也帮不你,只能自己学习CSS的相关知识了. 3,文件编码问题有时候,CSS样式放在aspx文件里有效,而放在独立的文件中无效,这样的问题如果不是路径问题,则就是编码问题造成的,可以将CSS

  • bootstrap和jQuery.Gantt的css冲突 如何解决

    bootstrap是广泛使用的一个前端框架,而jQuery.Gantt在目前也是一个很好用的用于绘制甘特图的插件. 这次在同时使用它们时,发现甘特图显示异常,如图 不加载bootstrap.css,甘特图就不会出问题,很容易就定位出现bootstrap的css冲突问题. 但是要实际定位到具体是哪个样式所导致的却花了一些功夫. 1.先看了甘特图里与bootstrap的重复样式,有一个.row,于是我把gantt插件的row全部修改成了ganttrow,发现没效果. 2.再是看了bootstrap中

  • 部署到iis后无法加载运行CSS文件的解决方法

    解决方法: 打开或关闭window功能中的Internet信息服务里的万维网服务=>常见HTTP功能=>静态内容

  • CSS对Web页面载入效率的影响分析总结

    我们罗列了十几条相关的知识与注意点,大家可以系统的探讨一下,让我们编写的Web页面打开更加流畅. 请不要告诉我,你看不懂E文,只是你不愿意看!!! 1.How the style system breaks up rules  The style system breaks rules up into four primary categories. It is critical to understand these categories, as they are the first line

  • jsp、css中引入外部资源相对路径问题分析

    在jsp页面中添加base,可用相对路径: 复制代码 代码如下: <%     String path = request.getContextPath();     String basePath = request.getScheme() + "://"             + request.getServerName() + ":" + request.getServerPort()             + path + "/&quo

  • jQuery解决浏览器兼容性问题案例分析

    本文实例分析了jQuery解决浏览器兼容性问题的方法.分享给大家供大家参考,具体如下: 问题: 当用户在名为abc的input控件按下回车键时,触发另一控件imgLogin的click事件 在IE 中 document.getElementById('abc').click();能够调用abc的click事件 但是在FF中却不行. 解决方法: 必须以下这样: var evt = document.createEvent("MouseEvents"); evt.initEvent(&qu

随机推荐