jeudi 1 mars 2012

学习之DOCTYPE

前段时间在园子里看到一篇讲Doctype的文章:正确使用DOCTYPE,就想起了自己在做DotNetNuke开发时也遇到过同样的问题,确实,这个问题说大不大,说小不小。平时在DotNetNuke里,按默认选择的就行了。不过有时同时创建俩个portals,就有俩个不同的skin,它们的DOCTYPE有时候就不一样,这时如果搞不清楚DOCTYPE就调整CSS,要想得到很好的效果和兼容性就很难了。


所以不管怎样,弄清楚DOCTYPE,对前段的开发总是有帮助的。下面就是我找了网上的一些资料总结出来的,保存下来以备不时之需,也同样分享给大家。




要说Doctype,得从浏览器解析不同文档时所使用的模式开始说起,



  • 针对text/html content的模式(Modes for text/html Content),这个模式下又有主要以下三个模式,而对text/html内容进行模式选择依赖于DOCTYPE嗅探(doctype sniffing

    • 怪癖模式(quirks mode)不同的浏览器实现了不同的怪癖行为。Internet Explorer中的怪癖模式会让IE的行为与(包含非标准特性的IE5.5相同;其他浏览器中,怪癖模式是对标准模式的少量偏移。
    • 标准模式(standards mode):这个模式中,浏览器尝试给符合标准的文档在规范上的正确处理达到在指定浏览器中的程度。不同的浏览器遵循不同的阶段,所以效果上会有差别。它和怪癖模式主要影响CSS内容的呈现,但在某些情况下也会影响到JavaScript的解释执行。
    • 准标准模式(almost standards mode):这种模式下的浏览器特性有很多都是符合标准的,但也不尽然,不标准的地方主要体现在处理图片间隙的时候(在表格中使用图片时问题最明显)。
  • 针对application/xhtml+xml的模式(XML Mode),这个模式下不要使用DOCTYPE

    • 在Firefox,Safari,Chrome和Opera中,将HTTP Content-type设置成application/xhtml+xml会触发XML模式。这些浏览器会在某种程度上尽量正确地对待遵守规范的XML文档。
    • IE 6, 7和8及Mac IE 5不支持application/xhtml+xml。

  • 非Web模式(Non-Web Modes),这里不讨论,实际应用中也只有少数引擎有针对非web内容的模式。
这样我们可以很清楚的知道,DOCTYPE主要运用于web文档是text/html content的时候,而DOCTYPE可以决定浏览器在解析文档时使用那种模式。所以下面的文章内容只会限定在针对text/html content的三个模式里。
浏览器模式的不同,肯定会造成一些效果的不同。以下从三个方面来看看浏览器模式的影响:
  • 布局(Layout): text/html中的模式主要会影响CSS布局(layout)。例如,不能让样式被继承至表格内部是一种怪异的地方(quirk)。对某些浏览器的怪异模式,盒模型(box model)会变更到IE5.5盒模型。等等。在准标准模式中(对于那些包含此模式的浏览器来说),和标准模式不同的地方是对于只包含图像的单元格高度的计算。
  • 解析(Parsing):也有一些怪异的地方会影响HTML和CSS的解析(parsing),并使得解析规范的页面失败了。这些怪异的地方主要是由怪异的布局(layout)引起。但值得注意的是,对比标准模式,怪异模式主要体现在CSS的布局和解析中,而不是HTML解析中。
  • 脚本(Script):虽然怪异模式主要和CSS相关,但还是有一些和脚本(scripting)有关的。比如,Firefox的怪异模式中,HTML中的属性id可以从脚本的全局作用域中建立对象引用,就和IE一样。比起其他浏览器,怪异模式对脚本的影响在IE8中尤其明显。


现在来看看,浏览器是如何确定模式的(Doctype sniffing):

现在的浏览器用doctype嗅探(doctype sniffing)方式来为text/html文档确定浏览器引擎模式。这意味着模式将会根据HTML文档开头的文档声明(document type declaration)来选定。(不适用于XML文档。)Doctype嗅探的产生是基于以下的实际情况:当doctype嗅探出来的那会,当doctype嗅探出来的那会,绝大多数“怪异的”文档既没有文档类型声明,也没有引用老的DTD。HTML5认识到了这个事实,而将text/html中的doctype定义为专门为了模式转换。
一个典型的前HTML5文档类型声明包含字符串“<!DOCTYPE”,根元素的通用标识符(“html”),字符串“PUBLIC”,一个引号括起来的DTD公共标识符,也可能包含一个此DTD的系统标识符(一个URL),以及字符“>”。这些东西都用空格隔开。此文档类型声明放在文档中的根元素之前。

  • 对于标准模式,可以通过使用下面任何一种文档类型来开启:

<!-- HTML 4.01 严格型 --> 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 

"http://www.w3.org/TR/html4/strict.dtd"> 

<!-- XHTML 1.0 严格型 --> 
<!DOCTYPE html PUBLIC 
"-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 

  • 而对于准标准模式,则可以通过使用过渡型(transitional)或框架型(frameset)文档类型来触发,如下所示:



<!-- HTML 4.01 过渡型 --> 

<!DOCTYPE HTML PUBLIC 

"-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd"> 

<!-- HTML 4.01 框架集型 --> 
<!DOCTYPE HTML PUBLIC 
"-//W3C//DTD HTML 4.01 Frameset//EN" 
"http://www.w3.org/TR/html4/frameset.dtd"> 

<!-- XHTML 1.0 过渡型 --> 
<!DOCTYPE html PUBLIC 
"-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<!-- XHTML 1.0 框架集型 --> 
< !DOCTYPE html PUBLIC 
"-//W3C//DTD XHTML 1.0 Frameset//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> 

当然相同的模式不同的DOCTYPE声明之间,会有一些细微的差别,下文会提到。





好了,终于可以进入正题了,DOCTYPE:



  • DOCTYPE是什么?
简单地说,doctype就是位于html标签之前的一行声明,这个声明向浏览器指出了当前页面或文档使用了那种规范,(HTML-4 de transition ou strict, XHTML, etc...)。
更完整的DOCTYPE声明写法是:
<!DOCTYPE HTML PUBLIC "type_de_HTML" "adresse_de_DTD"> 其中:


    • type_de_HTML : 表明HTML的使用版本。
    • adresse_de_DTD : 指出了DTD(Document type declaration)的URL地址,用来描述文档的法定结构、元素和属性。


  • 为什么要声明DOCTYPE?
它指明了文档使用的(X)HTML版本,这是诸如浏览器之类的工具解析文档(processing the document)时最需要的信息。比如说,当我们使用Markup Validator来检查文档结构(Syntax)时,必须声明DOCTYPE。其实不用多说,上面的那些废话基本上都在说这个问题。



  • DOCTYPE不同的声明
    • HTML5 :
<!DOCTYPE html>
HTML5的新DOCTYPE标签,更加简单化。它不会让浏览器进入怪癖模式(Quirks mode)

    • HTML4.01 transitional

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
  • 文档是html的:不能被当作XML对待;
  • 没有<marquee><embed>, etc这些标签;
  • 这些元素areadtddplitheadtfootcolgroupcoltrth et td的关闭标签是可选的;
  • 标签不区分大小写 ;
  • 对于HTML的属性,当属性值只包括(a-zA-Z0-9-,_:) 时,引号可以省略。
  • <OPTION selected> 代替 <OPTION selected="selected">
  • 以下的元素或属性是允许的(在html页面中):
    • BASEFONT 和 FONT ;
    • CENTERUSTRIKE 和 S ;
    • BODY 元素的BALINKBACKGROUNDBGCOLORLINKVLINKTEXT 属性;
    • 表格元素的BGCOLORHEIGHTNOWRAPWIDTH 属性;
    • Image和Object的 BORDERHSPACEVSPACE 属性 ;
    • HR 元素的 CLEARNOSHADESIZEWIDTH 属性 ;
    • li元素的 COMPACTTYPE 属性, 和ol元素的 STARTVALUE 属性 ;
    • PRE 元素的 WIDTH 属性 ;
  • IFRAME 是允许的,但 FRAMESET 和 FRAME 不允许 ;

    • HTML4.01 strict
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd"> 
与HTML4.01 transitionnel不同的地方 :
  • 前面特别提出允许的元素和属性不再允许,他们应该在CSS里使用 ;
  • 链接的 target 属性不再被允许 ;
  • IFRAME, FRAMESET 和 FRAME 都不允许。

    • HTML4.01 frameset

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
   "http://www.w3.org/TR/html4/frameset.dtd">
规则基本上与HTML4.01 transitionnel相同, 但 BODY 元素不再存在. 它被可以包含多个 FRAME 元素的 FRAMESET 元素替代.

    • XHTML1.0 transitional :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
文档可以被当作HTML或者XML处理。
与HTML不同的syntax规则如下 :
  • 所有标签都应该关闭;
  • 所有的标签元素属性都应该是小写;
  • 只允许 <option selected="selected"> 这种写法
  • 所有的引号也是必须的 ;
简而言之: 可用的标签基本和HTML4.01 transitional一样, 但它的文法结构syntax要更严格一些.

    • XHTML1.0 strict :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
XHTML1.0 transitionnel一样, syntax的规则是严格的, 但与XHTML1.0 transitionnel不同的地方和HTML4.01 Strict 完全一样:
  • 前面特别提出允许的元素和属性不再允许,他们应该在CSS里使用 ;
  • 链接的 target 属性不再被允许 ;
  • IFRAME, FRAMESET 和 FRAME 都不允许。
简而言之: 可用的标签基本和HTML4.01 strict一样, 但它的文法结构syntax要更严格一些.

    • XHTML1.0 frameset

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
规则基本上与XHTML1.0 transitionnel相同, 但 BODY 元素不再存在. 它被可以包含多个 FRAME 元素的 FRAMESET 元素替代.
简而言之: 可用的标签基本和HTML4.01 frameset一样, 但它的文法结构syntax要更严格一些.

  • 如何选择DOCTYPE
推荐XHTML1.0 Strict;
如果你使用 iframe 或者 target属性, 使用 XHTML1.0 transitional.
如果你使用 frameset 和 frame, 使用XHTML1.0 frameset.
如果你使用 HTML5,直接使用<!doctype html>


  • 最后推荐一个创建(X)HTML结构的工具 :Squelettor

1 commentaire: