DOCTYPE,或稱為 Document Type Declaration(文件類型聲明,縮寫 DTD)。通常情況下,DOCTYPE 位於一個 HTML 文件的最前面的位置,位於根元素 HTML 的起始標籤之前。因為瀏覽器必須在解析 HTML 文件正文之前就確定目前文件的類型,以決定其需要採用的渲染模式,不同的渲染模式會影響到瀏覽器對於 CSS 程式碼甚至 JavaScript 腳本的解析。尤其是在 IE 系列瀏覽器中,由 DOCTYPE 決定的 HTML 頁面的渲染模式至關重要。
先來看看當一個 HTML 文件在沒有 DOCTYPE 時,頁面在各瀏覽器中會如何渲染及解析。我們嘗試產生一個在最頂端沒有 DOCTYPE 的 HTML 文件:
<html> <head></head> <body> <script> document.write(document.compatMode); </script> </body> </html>
這個頁面在所有的瀏覽器中均傳回一致的結果,頁面上印出了「BackCompat」。 document.compatMode 屬性最初由微軟在IE 中創造出來,這是一個唯讀的屬性,傳回一個字串,只可能存在兩個回傳值:
值得注意的是,IE 的版本號一路從 6.0 升至了目前的 9.0,但升級僅限於標準模式。對於混雜模式,IE 的版本號永久的凍結在 5.5,這也算是為了向後相容的巨大犧牲。也就是說即使我們使用著最新最高級的IE9,但若我們不書寫DOCTYPE 或使用了能夠觸發混雜模式的DOCTYPE,那我們所面對的瀏覽器仍相當於是那個十幾年前的老古董IE5.5 。而其他那些瀏覽器的混雜模式和標準模式之間卻沒有想 IE 中這麼大的差異。
附註:IE6 增強的CSS:CSS Enhancements in Internet Explorer 6
近似標準模式(Almost Standards Mode)從字面意思上看與標準模式非常類似,但確實有小的差別。主要體現在對於表格單元格內垂直方向佈局渲染差異。 IE8 開始、Firefox、Chrome、Safari、Opera 7.5 開始,這些瀏覽器的標準模式更加嚴格的遵循了CSS2.1 規範,故對於在目前看來不太“標準”的以前的標準模式,被賦予了“近似標準模式」的名字。但在較早的 IE6 IE7 以及 Opera 7.5 之前版本中,瀏覽器無法嚴格遵循 CSS2.1 規範,故對於它們來說沒有這個近似標準模式,也可以理解為它們的近似標準模式就是標準模式。
到目前為止,可以看到各瀏覽器主要包含了三種模式。在 HTML5 草稿中,更明確的規定了模式的定義:
傳統名稱 | HTML5 草案名稱 | document.compatMode 傳回值 |
---|---|---|
standards mode 或strict mode | no-quirks mode | CSS1Compat |
almost standards mode | limited-quirks mode | #CSS1Compat |
quirks mode | quirks mode | BackCompat |
注:HTML5 草案关于 compatMode 的介绍:3.1.3 Resource metadata management
浏览器的工作模式常被称为“渲染模式”。实际上浏览器不同的工作模式不仅对渲染有影响,对代码的解析以及脚本的行为也同样有影响。
从更广泛的角度来看,浏览器的工作模式的差异不仅体现在处理 HTML 页面的时候,处理 XML 及一些非 WEB 内容时也有模式上的差异,但本文仅讨论浏览器在处理 HTML 页面时工作模式。1
注:
关于浏览器的工作模式的更多信息,请参考 Activating Browser Modes with Doctype。
不使用 DOCTYPE 一定会使 HTML 文档处于混杂模式,然而使用了 DOCTYPE,也不一定就能够使文档在所有浏览器中均处于标准模式。DOCTYPE 本身不就是一个“开关”吗?为何在有 DOCTYPE 的 HTML 文档之上仍然还会出现混杂模式?这个和以下条件有关:
使用了本身就会使浏览器进入混杂模式的古老的甚至是错误的 DOCTYPE;
在 DOCTYPE 之前出现了其他内容,如注释,甚至是 HTML 标签。
我们先说第一个条件。HTML 历史悠久,仅正确的 HTML 类型的 DOCTYPE 就有很多种。先看一个标准的 DOCTYPE:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
上面的 DOCTYPE 包含 6 部分:
字符串“
根元素通用标识符“HTML”
字符串“PUBLIC”
被引号括起来的公共标识符(publicId)“-//W3C//DTD HTML 4.01//EN”
被引号括起来的系统标识符(systemId)“http://www.w3.org/TR/html4/strict.dtd”
字符串“>”
其中根元素通用識別碼、公共識別碼、系統識別碼皆可透過腳本呼叫DOM 介面取得,分別對應document.doctype.name、document.doctype.publicId、document.doctype. systemId(IE6 IE7 不支援)。
不同的 DOCTYPE 之間,上面三部分可能不盡相同,有些 DOCTYPE 確實其中某一部分,如何在這些紛繁的 DOCTYPE 中選擇?
其實瀏覽器在嗅探 DOCTYPE 時只考慮了上述 6 部分中的第 1、2、4、6 部分,且不區分大小寫。在各瀏覽器核心實作中,幾乎都存在一個名單用於記錄這些常見的 DOCTYPE 所對應的模式,例如 WebKit 核心中 DocTypeStrings.gperf 檔案。各瀏覽器名單清單中觸發模式的不同導致了某些 DOCTYPE 出現在不同瀏覽器中觸發了不同模式的現象,如 。而對於名單之外的DOCTYPE,瀏覽器之間處理的差異也會導致觸發不同的模式,例如可能有的瀏覽器會將名單之外的DOCTYPE 當作混雜模式,而有的卻會一律當作標準模式。
所以我們在選用 DOCTYPE 的時候首先確定的是我們想讓 HTML 文件使用標準模式。
如果力求最簡,則HTML5 的DOCTYPE 是最佳選擇:,所有的主流瀏覽器均將這種只包含第1、2、6 部分的最短的DOCTYPE 視為標準模式。
如果力求穩妥,則較早的HTML4.01 Strict 的DOCTYPE 也是一個好的選擇:,它在各主流瀏覽器中觸發的模式與上面的HTML5 的完全一致。
有時我們處於特殊情況也希望瀏覽器能夠都處於近似標準模式,則可選擇:。
附註:關於Firefox 中DTD 與瀏覽器工作模式:Mozilla's DOCTYPE sniffing
前面提到,DOCTYPE 作為一個決定瀏覽器對於HTML 文件採取何種模式“開關”,應出現在HTML 文件的最前面。但有時處於某些原因,有的作者會在 DOCTYPE 之前防止一些內容,可能是服務端輸出的某些資訊。這樣會讓瀏覽器感到極為“困惑”,它第一眼看到的不是 DOCTYPE,故可能會認為頁面沒有 DOCTYPE,則可能觸發了混雜模式。然而事實上在這一點各瀏覽器的處理並不相同。我們將DOCTYPE 之前可能出現的這些內容分類,它們包括:
普通文字
XML 宣告
IE 條件註解
#對於一般文字和HTML 標籤,各瀏覽器都進入了混雜模式,這個很好理解,都看到疑似的HTML 文件正文了,瀏覽器不太會往下追查DOCTYPE 在哪裡。
對於 HTML 註解和 XML 聲明,它們和上面的普通文字和 HTML 標籤有些差別,它們不會在頁面中展示出來,即不可視。這時,有的瀏覽器則顯得十分“智能”,非 IE 瀏覽器都會忽略它們的存在,DOCTYPE 被正確解析。但在 IE6 中,DOCTYPE 先前的 XML 聲明會導致頁面進入混雜模式,而所有的 IE 都會使 DOCTYPE 先前出現了 HTML 註解的頁面進入混雜模式。在 IE9 中當出現這種情況時,瀏覽器在控制台中給出了提示:「HTML1113: 文件模式從 IE9 標準 重新啟動到 Quirks ”,看來微軟在這一點上不打算“隨大流”,這樣做也可以敦促作者盡量避免在DOCTYPE 之前加入其他內容。
有的作者很聰明,他既在DOCTYPE 之前加入了他所需要的內容,卻又沒有讓IE 由於這些內容而進入混雜模式。 -- some comments -->
#< ![endif]>
又或是
#
上面這些IE 條件註解在非IE 瀏覽器中,可能完全被忽略,可能被解釋為普通HTML 註解。了,因為這就是IE 條件註釋的作用。 所以這也是目前比較合適的在DOCTYPE 之前寫點什麼又保證所有瀏覽器均為標準模式的做法,但我們仍然不推薦在DOCTYPE 之前加入任何非空白內容。
建議
透過上面的歷史回顧以及分析,我們看到了DOCTYPE 對於目前主流瀏覽器的關鍵作用,同時也發掘了能夠觸發各瀏覽器標準模式的最佳DOCTYPE。則是使DOCTYPE 發揮其正確作用的關鍵。
作業系統版本: | #Windows 7 Ultimate build 7600 |
---|---|
瀏覽器版本: | IE6 IE7 IE8 IE9 Firefox 4.0.1 Chrome 12.0.742.100 Safari 5.0.5 Opera 11.11 |
測試頁面: | |
#本文更新時間: | 2011-06-17 |
瀏覽器相容性渲染模式標準模式混雜模式DOCTYPE DTD
以上是DOCTYPE與瀏覽器渲染介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!