You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
// 或
<htmlxmlns="http://www.w3.org/1999/xhtml">
<!DOCTYPE>
DOCTYPE 声明(全称 Document Type Declaration)。通常情况下,DOCTYPE 位于一个 HTML 文档的最开始的位置,位于根元素 HTML 的起始标记之前。因为浏览器必须在解析 HTML 文档正文之前就确定当前文档的类型,以决定其需要采用的渲染模式,不同的渲染模式会影响到浏览器对于 CSS 代码甚至 JavaScript 脚本的解析(尤其是在 IE 系列浏览器中,由 DOCTYPE 所决定的 HTML 页面的渲染模式至关重要)。
<!DOCTYPE> 虽然是标记的写法,但是它不是 HTML 标记,也没有结束标记
<!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标记之前
不做 DOCTYPE 声明或声明不正确,可能导致 HTML 标记与 CSS 失效,从而令网页的布局变乱,造成网页在浏览器中不能正常的显示
早期浏览器对标准的错误实现、私有扩展的大量滋生和为了向前兼容以及早期标准本身的混乱等导致了那时的文档既没有 doctype 也没有对 DTD 的直接引用,也导致了新的标准难以得到应用和普及,因为浏览器无法区分它们。为了处理根据Web标准创作的网页和根据陈旧实践创作的网页,Todd Fahrner 在1998年提出了“came up with a toggle”方法1允许浏览器提供两套渲染模式: 即有完整的doctype的文档使用W3C的标准进行解析,否则使用旧的方式解析。
在 Internet Explorer 5 for Mac 工作的时代,Microsoft 的开发人员在更新浏览器版本时,针对当时的标准文档的支持进行了优化,但是这一优化致使旧的页面无法正确显示。或更确切地说,它们的渲染正确(根据规范),但是人们期望它们的渲染不正确。这些页面本身是根据当时主要的浏览器(主要是Netscape 4和Internet Explorer 4)的怪癖编写的。
HTML 4.01 基于SGML, <!DOCTYPE> 声明通过引用 DTD 来告诉阅读程序如何解析标识,而 DTD 规定了标记语言的规则,这样浏览器就能正确地呈现内容。
在 HTML 4.01 中有三种 <!DOCTYPE> 声明类型:Strict、Transitional 以及 Frameset类型
<!-- Strict DTD类型,干净的标记,免于表现层的混乱 --><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" " http://www.w3.org/TR/html4/strict.dtd"><!-- Transitional DTD 类型,用户使用了不支持层叠样式表(CSS)的浏览器以至于不得不使用 HTML 的呈现特性时 --><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" " http://www.w3.org/TR/html4/loose.dtd"><!-- Frameset DTD类型,除 frameset 元素取代了 body 元素之外,Frameset DTD 等同于 Transitional DTD --><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" " http://www.w3.org/TR/html4/frameset.dtd">
<!--[if gte IE 7]><script> alert("Congratulations! You are running Internet Explorer 7 or a later version of Internet Explorer.");</script><p>Thank you for closing the message box.</p><![endif]-->
<!DOCTYPE html>, is the simplest possible, and the one recommended by HTML5. Earlier versions of the HTML standard recommended other variants, but all existing browsers today will use full standards mode for this DOCTYPE, even the dated Internet Explorer 6. There are no valid reasons to use a more complicated DOCTYPE. If you do use another DOCTYPE, you may risk choosing one which triggers almost standards mode or quirks mode.3
HTML DTD 中大部分内容都是元素类型及其属性的声明,剩下是 SGML 语法本身的注释和一系列参数实体定义。
下面是 ul 元素类型声明的例子(属性声明等等语法就不再展示)
<!ELEMENT UL - - (LI)+>
<!ELEMENT 关键字开始一个声明,而 > 字符结束它
声明的元素类型为UL
两个连字符- -表示此元素类型的开始标记 <UL> 和结束标记 </ UL> 都是必需的
(LI)+ 声明此元素类型的内容模型为“至少一个LI元素”,这里的 + 与正则里的通配符很像
SGML 的语法不是本文的目标。对此感兴趣可以自行查找。
HTML5 没有 DTD
HTML 的某些早期版本(尤其是从HTML2到HTML4)基于 SGML,并使用 SGML 解析规则。但是,很少(如果有的话)Web浏览器对 HTML 文档实施过真正的 SGML 解析。过去,唯一严格将 HTML 作为 SGML 应用程序处理的用户代理就是验证器。由此产生的混乱-验证者声称文档具有一种表示形式,而广泛部署的Web浏览器可互操作地实现另一种表示形式-浪费了数十年的生产力。因此,HTML5 版本的 HTML 返回到非 SGML 基础。
这两个属性都是定义当前 HTML 页面的语言。它们的值都是 ISO 639-1 中定义标准两字符语言代码9。例如,英语 English 代码为 en,即写作 lang=en。如果希望指定某种语言的方言,可以在语言代码后面紧跟一个破折号和一个子代码名称。例如,简体中文 Chinese (Simplified) 的代码就是 zh-CN。
有两个语言属性,这也是 XHTML 遗留的问题,xml:lang属性是 XHTML 中新定义的,不能在HTML中使用,所以 HTML5 中可以直接省略。如果要保留,必须得保证它跟 lang 的属性值相同。
在一些比较早的 web 页面,检查源代码经常能看到 html 的首行是这样的代码,或者类似代码
<!DOCTYPE>
DOCTYPE 声明(全称 Document Type Declaration)。通常情况下,DOCTYPE 位于一个 HTML 文档的最开始的位置,位于根元素 HTML 的起始标记之前。因为浏览器必须在解析 HTML 文档正文之前就确定当前文档的类型,以决定其需要采用的渲染模式,不同的渲染模式会影响到浏览器对于 CSS 代码甚至 JavaScript 脚本的解析(尤其是在 IE 系列浏览器中,由 DOCTYPE 所决定的 HTML 页面的渲染模式至关重要)。
<!DOCTYPE>
虽然是标记的写法,但是它不是 HTML 标记,也没有结束标记<!DOCTYPE>
声明必须是 HTML 文档的第一行,位于<html>
标记之前<!DOCTYPE>
声明,<!DOCTYPE>
声明对大小写不敏感,不过推荐大写浏览器渲染模式(rendering modes)
早期浏览器对标准的错误实现、私有扩展的大量滋生和为了向前兼容以及早期标准本身的混乱等导致了那时的文档既没有 doctype 也没有对 DTD 的直接引用,也导致了新的标准难以得到应用和普及,因为浏览器无法区分它们。为了处理根据Web标准创作的网页和根据陈旧实践创作的网页,Todd Fahrner 在1998年提出了“came up with a toggle”方法1允许浏览器提供两套渲染模式: 即有完整的doctype的文档使用W3C的标准进行解析,否则使用旧的方式解析。
在 Internet Explorer 5 for Mac 工作的时代,Microsoft 的开发人员在更新浏览器版本时,针对当时的标准文档的支持进行了优化,但是这一优化致使旧的页面无法正确显示。或更确切地说,它们的渲染正确(根据规范),但是人们期望它们的渲染不正确。这些页面本身是根据当时主要的浏览器(主要是Netscape 4和Internet Explorer 4)的怪癖编写的。
微软首先采用了 Todd Fahrner 提出的解决方案。在呈现页面之前先查看“ doctype”,较旧的页面(依赖于较旧的浏览器的渲染功能)通常根本没有doctype,所以就像老式浏览器一样呈现这些页面。而为了“激活”新的标准支持,网页开发者必须通过在
<html>
元素之前提供正确的doctype。这就诞生了[doctype嗅探(doctype sniffing或doctype switching)](#Doctype Sniffing)很快所有主要的浏览器都有了两种模式:“混杂模式”(又叫怪异模式,Quirks mode)和“标准模式”(又叫严格模式,Standards mode 或者 Strict mode),用以把能符合新规范的网站和老旧网站区分开。
后来,Mozilla 发布 Netscape 1.1时,他们无意间破坏了数千页,这些页依赖于一两个特定的怪癖。他们的解决方案便是后来的“几乎标准的模式”。
目前现代浏览器的排版引擎都包含三种模式:
HTML 4.01 与 HTML5 的
<!DOCTYPE>
声明的差异HTML 4.01 基于SGML,
<!DOCTYPE>
声明通过引用 DTD 来告诉阅读程序如何解析标识,而 DTD 规定了标记语言的规则,这样浏览器就能正确地呈现内容。在 HTML 4.01 中有三种
<!DOCTYPE>
声明类型:Strict、Transitional 以及 Frameset类型HTML5 基于自己的标准,而不是 SGML,所以不需要引用 DTD。但是 HTML5 语法要求声明 DOCTYPE,以确保浏览器以标准模式渲染页面,此外再没有其他用途。
在 HTML5 中只有一种
<!DOCTYPE>
声明:<!DOCTYPE html>
除此之外,常见的还有 XHTML、MathMl 及 Svg 等文档类型声明 valid-dtd-list。
IE 条件注释
IE 条件注释在非 IE 浏览器中,可能完全被忽略,也可能被解释为普通 HTML 注释。但是在 IE 中(IE5 以上的版本才开始支持IE条件注释,所以只有 IE5 版本以上)它们才会起作用,而这就是 IE 条件注释的作用。所以这也是目前比较合适的在 DOCTYPE 之前写点什么又保证所有浏览器均为标准模式的做法。
关键词解释:
lt
:Less than,也就是小于的意思lte
:Less than or equal to,也就是小于或等于的意思gt
:Greater than,也就是大于的意思gte
:Greater than or equal to,也就是大于或等于的意思。!
:逻辑非,就是不等于的意思通常用 IE 条件注释根据浏览器不同载入不同 css,从而解决样式兼容性问题的。其实它可以做的更多。它可以保护任何代码块——HTML代码块、JavaScript 代码块、服务器端代码等等。如下代码只有在大于 IE7 版本的 IE 浏览器中才会弹出弹框并显示内容:
不推荐在 DOCTYPE 之前加入任何非空白内容,即使这些内容可能是注释,因为某些浏览器会进入Quirks模式。针对 IE 各版本的样式差异,更好的解决方案是使用以下 hack 方式:
先判断用户用的哪个 IE 版本,然后在标记上加上该版本的 class,这样可以方便 hack,css 文件则针对不同版本进行编写
DOCTYPE 声明的语法
<!DOCTYPE 根元素 可用性 "注册//组织//类型 标记 定义//语言" "URL">
PUBLIC
可公开访问的对象;SYSTEM
系统资源,如本地文件或 URL。-//W3C//DTD XHTML 1.0 Strict//EN
+
,表示组织名称已注册;-
: 表示组织名称未注册PS: 记住只要紧紧拥抱 HTML5 就行。现代开发没必要去记 HTML 4.01 和 XHTML 的
<!DOCTYPE>
声明,只要知道有这些东西就行,如果真的要用,很多编辑器都有提示或者模版。也可以现查现用常用的 DOCTYPE 声明。Doctype Sniffing
Doctype Sniffing (又叫 Doctype Switching)。现代浏览器使用 doctype Sniffing(doctype 嗅探)来确定
text/html
文档的引擎模式。也就是基于HTML文档开头的文档类型声明(或缺少文档类型声明)来选择模式。HTML4.01规范和ISO 8879(SGML)都没有说关于使用文档类型声明作为引擎模式转换的事情。而 Doctype 嗅探出现的背景可见上文"[那时的文档既没有 doctype 也没有对 DTD 的直接引用](#浏览器渲染模式(rendering modes))"
HTML5 并不基于SGML也没有DTD,但它为了向前兼容,接受了doctype嗅探这个事实,定义了在
text/html
中<!DOCTYPE>
是唯一的且唯一作用也只有模式转换声明,除此外没有什么别的用处。选择合适的 Doctype
以下是为新
text/html
文档选择文档类型的简单准则:标准模式,最新验证
<!DOCTYPE html>
推荐总是使用此文档类型。这样做会让目前还不支持 HTML5 的浏览器也采用标准模式解析,这意味着他们会解析那些 HTML5 中兼容的旧 HTML 标签的部分,而忽略他们不支持的 HTML5 新特性。(可以在支持 HTML5 的浏览器中验证
<video>
,<canvas>
和 ARIA 等新功能)标准模式,旧版验证目标
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
此文档类型也会触发“标准”模式,但是这是不太精确的旧版验证,因为它不了解一些 HTML5 新功能,也许应该及时更新文档了。
使用“标准”模式,但是在表布局中使用切片图像,并且不想对其进行修复
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
提供了几乎标准模式,如果以后再使用HTML5(并因此采用完整的标准模式),则基于表中切片图像的布局可能会中断,因此最好使现在就与标准模式兼容。
故意要使用 Quirks模式
不写文档类型声明。
如果非要对 IE 旧版本进行兼容,那么最好使用条件注释对旧版本应用特定的hack,而不是在Quirks模式下寻求通用性。
不建议给
text/html
的文档使用任何 XHTML 文档类型X-UA-Compatible
声明通俗讲,通过
X-UA-Compatible
声明可以实现 IE 浏览器版本模拟。但是只能模拟比当前版本更低的版本,并不能模拟高版本。使用时其必须放在<head></head>
标记内,并且应该尽可能靠前,除了 TITLE 元素和其它 META 元素外,它应该放在所有其它元素之前。X-UA-Compatible 语法
直接指定 IE 某个版本的标准文档模式
指定某个IE版本,但也允许例外
在IE版本号前面加上
Emulate
,代表,如果网页开头有<!DOCTYPE>
标记就使用该IE版本的标准文档模式,否则使用怪异模式(即等同于 IE=IE5),不建议使用该语法。使用最新版本文档模式
IE=edge
表示 IE 应该使用其渲染引擎的最新(Edge)版本,即使用其可用的最高模式,如用 IE8 访问就是 IE8 文档模式,用 IE9 访问就是 IE9 模式一种特殊的用法
安装了 Google Chrome Frame(谷歌浏览器內嵌框架) 则使用谷歌浏览器内核模式,否则使用最新的IE模式
X-UA-Compatible 用法
例如我们要往下兼容到 IE8
我们网页应该提前添加好标记:
然后开发者按 IE8 浏览器文档模式对 HTML/CSS/JS 代码进行兼容性处理,不使用超过 IE8 文档模式的特性
之后,我们就只需要维护一份 IE8 兼容代码,而用户无论是在 IE9 / IE10 / IE11 访问都是如同 IE8 访问一样(要往下兼容到 IE9 或者 IE10 都以此类推)
最后,为 IE8 以下版本添加旧版IE浏览器升级提示,或跳转到IE浏览器升级提示页,如在 X-UA-Compatible 声明代码下添加 IE 条件注释:
<!--[if lte IE 7]><script>window.location.href='http://support.dmeng.net/upgrade-your-browser.html?referrer='+encodeURIComponent(window.location.href);</script><![endif]-->
国内双核浏览器兼容思路
国内很多浏览器其实就是给 Chromium 内核和 IE 内核套层壳,国内大多浏览器都自称为双核引擎(基于 Webkit 的内核用于常用网站的高速浏览,基于 IE 的内核主要用于部分网银、政府、办公系统等网站的正常使用)。用户访问网页时双核浏览器根据网页内容自动选择内核。不过,双核浏览器也提供了类似 X-UA-Compatible 特性的
meta
标记,允许网页开发者通过标记选择内核使用 Chromium 内核(极速模式)
使用 IE 8/9/10/10 内核(IE标准模式,部分支持 HTML5)
使用 IE 6/7 内核(IE兼容模式,不支持 HTML5)
没有理由再在页面上添加 X-UA-Compatible
实际上,由于 IE11 以下版本都已停止更新5,如无特殊情况,无论是从代码工作量还是从用户安全的角度来讲,我们都不应该再兼容 IE11 以下版本。不仅 IE11 对该属性不再重视(甚至已经从明显的地方移除),其特殊用法使用谷歌浏览器内核模式中的谷歌浏览器内核插件也早已停止维护。
小结
在 HTML5 之前,为了获得正确的 doctype 声明,关键就是让dtd与文档所遵循的标准对应。例如,假定文档遵循的是xhtml 1.0 strict标准,文档的doctype声明就应该引用相应的dtd。
HTML5 时代,请使用HTML5文档类型
<!DOCTYPE html>
,该文档类型更短,更甜美,并在所有现代浏览器中触发标准模式。SGML 与 HTML
SGML
标准通用标记语言(SGML)是用于开发标记语言的语言。制定 SGML 的基本思想是把文档的内容与样式分开。
一个SGML文件通常分三个层次:结构、内容和样式。结构为组织文档的元素提供框架,内容是信息本身,样式控制内容的显示。
SGML 中定义的每种标记语言都称为 SGML 应用程序。SGML 应用程序通常具有以下特征:
SGML 声明。SGML声明指定哪些字符和分隔符可以出现在应用程序中,例如 SGML HTML 4声明
文档类型定义(Document Type Definition, DTD)。DTD 定义了标记构造的语法,例如 HTML 4.01 Strict DTD
DTD 还可以包括其他定义,比如数字和命名字符实体(常见的有
<
代表符号<
,>
代表符号>
,又如å
代表 å,以及水
表示汉字 “水”等等)描述归因于
markup
的语义的规范。该规范规定了 DTD 中无法表达的语法限制(相当于 DTD 的补充)包含数据(内容)和标记的文档实例。其实就是加上标记处理后的文件。
HTML DTD
HTML DTD 中大部分内容都是元素类型及其属性的声明,剩下是 SGML 语法本身的注释和一系列参数实体定义。
下面是
ul
元素类型声明的例子(属性声明等等语法就不再展示)<!ELEMENT
关键字开始一个声明,而>
字符结束它- -
表示此元素类型的开始标记<UL>
和结束标记</ UL>
都是必需的(LI)+
声明此元素类型的内容模型为“至少一个LI元素”,这里的+
与正则里的通配符很像HTML5 没有 DTD
HTML5 是没有对应的 DTD 的。HTML5 的设计者认为 DTD 的表达能力太有限,因此使用 HTML5 验证器(https://validator.nu/ 和w3c的副本https://validator.w3.org/nu/ 以及WHATWG的验证器https://whatwg.org/validator/)的模式进行验证,而不再是基于 DTD 的验证。
而且,HTML5 的设计使其不可能编写 DTD。例如,在 HTML5 中任何以
data-
开头并符合某些通用规则的属性名称都应是有效的,开发者可以写出无数个不同的这样的属性。然而在 SGML 中,要求每条属性都需要单独列出,想要实现data-
这一特性,那么 DTD 就必须是无限的。这显然是做不到的。根元素
一个 HTML 页面是一系列嵌套的元素。页面的整个结构就像一棵树。最外面的元素是页面上所有其他元素的祖先,被称为“根元素”。HTML 页面的根元素始终为
<html>
。根元素示例:这个标记没有错。它是有效的 HTML5。但是 HTML5 中不再需要其中的一部分,因此可以通过删除它们来节省一些字节。
xmlns
属性上面代码表示此页面中的元素位于 XHTML 命名空间
http://www.w3.org/1999/xhtml
中,但是HTML5 中的元素始终在此命名空间中8。因此不再需要显式声明它,无论此属性是否存在,HTML5 页面在所有浏览器中的工作方式都将完全相同。删除
xmlns
属性后根元素:lang
和xml:lang
属性这两个属性都是定义当前 HTML 页面的语言。它们的值都是
ISO 639-1
中定义标准两字符语言代码9。例如,英语 English 代码为en
,即写作lang=en
。如果希望指定某种语言的方言,可以在语言代码后面紧跟一个破折号和一个子代码名称。例如,简体中文 Chinese (Simplified) 的代码就是zh-CN
。有两个语言属性,这也是 XHTML 遗留的问题,
xml:lang
属性是 XHTML 中新定义的,不能在HTML中使用,所以 HTML5 中可以直接省略。如果要保留,必须得保证它跟lang
的属性值相同。在 XHTML 文档中,
lang
属性已从 XHTML 1.1 中删除。但是,XHTML规范建议在 XHTML 1.0 文档的<html>
元素中同时使用lang
属性和xml:lang
属性,以在不同的浏览器之间获得最大的兼容性。如果网页定义为 XHTML1.1 或者XML格式,那么可以使用xml:lang
属性(因为xml:lang
属性是在XML中确定语言信息的标准用法)。只有
lang
属性在 HTML5 中有效,所以 HTML5 最佳的根元素书写如下:当
lang
属性用于<html>
元素中时,它将作用于整个文档;而在用于其他元素中时,它将仅作用于这些元素的内容。如果一个页面用到了多种语言,那么可以给相应的元素类型添加lang
属性,它会覆盖添加在<html>
上的lang
属性值参考链接
DOCTYPE 与浏览器模式分析
你所未必知道的关于标记细节
怪异模式和标准模式
Quirks Mode
Dive Into HTML5
About conditional comments
Activating Browser Modes with Doctype
DTD文档类型声明doctype
X-UA-Compatibility Meta Tag and HTTP Response Header
Why use X-UA-Compatible IE=Edge anymore?
IE 兼容性标记 X-UA-Compatible 解释和用法
浏览器内核控制标记meta说明
DTD Tutorial
Where is the HTML5 Document Type Definition?
On SGML and HTML
SGML
The lang and xml:lang attributes
The text was updated successfully, but these errors were encountered: