NNNの博客

DTD详解🔔

前几天@老赵还在微薄上问一个< 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还制定了一些其他的规范,如

    /
      下面必须至少有一个
    1. ,还有哪些是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的头,以前的

神马的也可以用这个头,
不也属于html5支持的标签不是吗?

现在大家正常用的是xhtml过度的DTD,但目前的情况时越来越多的网站已经开始精简dtd,如百度、雅虎、谷歌等已经精简啦。携程的还是很长的xhtml的过度DTD,啥时决定精简我们这种小人物也不好说。。

转自:http://www.smallni.com/dtd/