前几天@老赵还在微薄上问一个< textarea >和< div >设置了同样的宽度,但最后解析出来不一样的问题。最后的原因是由于设置了html 4.0的DTD导致的。
也许说到DTD大家可能都知道DTD是文档类型定义的意思,那么具体的用法大家有没有了解过?也许你的很多问题可能就是DTD的差异导致的。今天,带大家来一起详细的探讨下,看看这个究竟是个神马东西。
定义和用法
DTD是一种保证html文档格式正确的有效方法,可以通过比较html文档和DTD文件来看文档是否符合规范,以及元素和标签使用是否正确。一个DTD文档包含元素的定义规则、元素间关系的定义规则、元素可使用的属性、可使用的实体和符号规则。
DTD要通过<!DOCTYPE>标签来申明, <!DOCTYPE>位于文档中的最前面的位置,处于 标签之前。此标签可告知浏览器文档使用哪种 HTML 或 XHTML 规范。
按照W3C的标准,我们需要在html的最开始申明文件的DTD类型。如果漏写DTD申明,Firefox仍然会按照标准模式来解析网页,但在IE中就会触发怪异模式。在table布局时代,盒模型和CSS我们都接触的比较少,所以DTD申明并不是很重要,被我们忽视了。到了CSS布局时代,DTD的申明就变得非常重要了。为了避免怪异模式给我们带来不必要的麻烦,我们要养成书写DTD申明的好习惯
以下面这个 <!DOCTYPE> 标签为例:
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
在上面的声明中,声明了文档的根元素是 html,它在公共标识符被定义为 “-//W3C//DTD XHTML 1.0 Strict//EN” 的 DTD 中进行了定义。浏览器将明白如何寻找匹配此公共标识符的 DTD。如果找不到,浏览器将使用公共标识符后面的 URL 作为寻找 DTD 的位置。
感兴趣的同学可以打开http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd这个地址看看,这个DTD有979行的xml代码。
来看如下代码
<!--=================== Generic Attributes ===============================-->
<!-- core attributes common to most elements
id document-wide unique id
class space separated list of classes
style associated style info
title advisory title/amplification
-->
<!ENTITY % coreattrs
"id ID #IMPLIED
class CDATA #IMPLIED
style %StyleSheet; #IMPLIED
title %Text; #IMPLIED"
>
以上代码规定了标签的通用属性(id、class、style、title)
再比如下面这段代码
<!--================== The Anchor Element ================================-->
<!-- content is %Inline; except that anchors shouldn't be nested -->
<!ELEMENT a %a.content;>
<!ATTLIST a
%attrs;
%focus;
charset %Charset; #IMPLIED
type %ContentType; #IMPLIED
name NMTOKEN #IMPLIED
href %URI; #IMPLIED
hreflang %LanguageCode; #IMPLIED
rel %LinkTypes; #IMPLIED
rev %LinkTypes; #IMPLIED
shape %Shape; "rect"
coords %Coords; #IMPLIED
>
这些代码规定了锚除了基本通用属性外的一些其他属性,如charset\type\name\href\hreflang\rel\rev等等,具体的诸如#IMPLIED <!ELEMENT这些用法可以参考这里
此外这个DTD还制定了一些其他的规范,如
- /
- ,还有哪些是block元素:
- 下面必须至少有一个
<!-- Unordered list -->
<!ELEMENT ul (li)+>
<!ATTLIST ul
%attrs;
>
<!ENTITY % block
"p | %heading; | div | %lists; | %blocktext; | fieldset | table">
通过以上一些代码片段我们知道了,DTD其实是一种约束规则,一个规范,规定了一个文档中有哪些元素,一个元素中有哪些属性以及元素之间的使用规则。
DTD的类型
<!DOCTYPE HTML
PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<!DOCTYPE HTML
PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<!DOCTYPE HTML
PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<!DOCTYPE HTML>
其实大家很容易发现主要有三种类型:strict(严格)、transitional(过度)、frameset(框架)。严格类型的DTD包含了大部分的html元素和属性,但一些过时的元素已经不再支持(font\u\s\iframe等);过度的包含了所有的html元素和属性,过时的一些元素也支持;框架的DTD是为需要使用框架时所用到的DTD,如无框架,不会用到。
其实大家会发现在public里还有html的版本类型,对于html版本类型不同而导致的不同的DTD,可以很容易理解:xhtml比html在更来得严谨(如xhtml区分大小写html不区分大小写)。
当然最后的有点特殊的xhtml 1.1版本的DTD,这个版本没有具体什么类型,直接是xhtml11.dtd,它对html元素的支持性似乎更加严格,感兴趣的同学可以读读它的源文件。
最后一个<!DOCTYPE HTML>真是简洁啊!不管你看的舒服不舒服,我反正看的很舒服。这个是html5的DTD头,不一定说用到html5最新的标签才可以用这个DTD的头,以前的
现在大家正常用的是xhtml过度的DTD,但目前的情况时越来越多的网站已经开始精简dtd,如百度、雅虎、谷歌等已经精简啦。携程的还是很长的xhtml的过度DTD,啥时决定精简我们这种小人物也不好说。。