怪異模式(Quirks Mode)對 HTML 頁面的影響
Quirks Mode 概述
定義
什么是 Quirks Mode? 簡單來說,Quirks Mode 就是瀏覽器為了兼容很早之前針對舊版本瀏覽器設計、并未嚴格遵循 W3C 標準的網頁而產生的一種頁面渲染模式。
歷史
由渲染引擎產生的兩種文檔模式
談到 Quirks modes 首先就要從瀏覽器渲染引擎說起。我們知道所有的瀏覽器都有自己的頁面渲染引擎,渲染引擎主要包含兩部分,一部分負責 HTML、CSS 代碼的解析,另一部分負責腳本代碼解析,這兩部分合起來就可以繪制出完整的頁面。
表 1 各瀏覽器渲染引擎構成
IE Trident -- ChakraFirefox | Gecko | -- | SpiderMonkey |
Chrome | Webkit | Webcore | V8 |
Safari | Webkit | Webcore | Javascriptcore |
Opera | Presto | -- | Carakan |
從表 1 可以看出,現在市面上的主流瀏覽器中除了 Chrome 和 Safari 都采用了 Webkit 渲染引擎,其余三種瀏覽器采用了各自不同的渲染方式(不同的 HTML 解析,不同的 JS 解析)。我們這里暫且先不討論不同的渲染引擎繪制頁面時的差異,單以每一種渲染引擎而言,隨著版本的發展其渲染頁面的方式也有很大的不同。
IE 是最早提出 Quirks Mode 與 Standards Mode(與 Quirks 相對應的一種模式)的,后來 Firefox、Chrome、Safari、Opera 等瀏覽器也都支持了這兩種渲染方式。但是只有在 IE 中用戶才可以自由地在兩種方式之間切換,其他瀏覽器都是自動匹配其中一種。下文將主要以 IE 為例來說明 Quirks Mode 對頁面繪制的影響,表 2 展示了 IE 隨著其渲染引擎的發展,它對 HTML 頁面的渲染改變如下。
表 2 IE 渲染引擎發展歷史
Trident 版本 MSHTML.dll 版本 IE 版本 更新unversioned | 4.0.x | 4 | 首發 |
unversioned | 5.0.x | 5 | 增加對 CSS1 的支持及改變對 CSS 的渲染 |
unversioned | 5.5.x | 5.5 | 修正部分 CSS 的排版控制 |
unversioned | 6.0.x | 6 | 修正 box model 的錯誤及新增 quirks Mode 的切換功能 |
unversioned | 7.0.x | 7 | 修正部分 CSS 排版錯誤以及增加對 PNGalpha 通道(半透明) |
4.0 | 8.0.x | 8 | 第一個通過 Acid2 測試的版本 |
5.0 | 9.0.x | 9 | 首次支持 HTML5、SVG、CSS3 及采用新的 JavaScript 引擎 |
6.0 | 10.0.x | 10 | 支持 CSS3 多欄式排版、格子對齊、浮動式區塊排版、漸變 |
從表 2 可以清晰的看出,隨著 IE 的發展,其渲染引擎(早期為 MSHTML.dll,后來命名為 Trident)也在不斷加入新的特性以及修正一些早先版本的錯誤。在 2001 年 IE6 正式發布之前,當時的市面主要就是 IE 和 Netscape 的 Navigator 兩款瀏覽器,而 IE 擁有很大的用戶群,所以大多數的頁面都是針對 IE 而設計的,但是 IE 的渲染引擎卻沒有遵循 W3C 的規范,當時微軟已經認識到 W3C 規范的重要性,所以當 IE 發展到 IE6 的時候,渲染引擎(MSHTML.dll)做出了一個重要的改變,將自己原先不符合 W3C 規范中的盒模型 box mode 繪制方式改為與 W3C 標準一致(后面會詳細討論),由于這個重大的改動,原先針對 IE 舊版本所設計的 HTML 頁面都不能正確顯示了,所以在 IE6 發布的時候附帶了一個切換回 IE5 頁面渲染方式的功能,這個功能中就首次提出了 Quirks Mode。
當用戶需要顯示舊版本的頁面時切換到 Quirks Mode,這時瀏覽器的渲染引擎就切換到 IE5.5 所對應的版本(MSHTML.dll 5.5.x),box mode 還是按照之前的方式繪制,這樣頁面就可以正確顯示。當用戶需要顯示一些新的、滿足 W3C 規范的頁面時,渲染引擎切換到一個與 Quirks Mode 對應的 Standards Mode(標準模式),在此模式下渲染引擎就是當前的最新版本,這樣也就滿足了更多的 W3C 規范。這兩種 Mode 之間的差別就是因為工作在不同版本的渲染引擎環境下。
最后,Quirks Mode 和 Standards Mode 合起來就稱為瀏覽器的文檔模式 Document Mode。
Quirks 和 Standards 之外的第三種模式
實際上,在上文提到的具有 Quirks 和 Standards 兩種文檔模式的瀏覽器中還存在第三種模式—Almost Standards Mode。這種模式和 Standards Mode 幾乎一致,唯一的區別就在于某些情況下 Almost Standards Mode 會采用與 Quirks 相同的方式來繪制頁面。比如當我們需要把圖片分割后顯示在一個表格單元中時,Almost Standards Mode 與 Quirks Mode 采用同樣的繪制方式從而讓圖片顯示不像在 Standards Mode 中那么的四分五裂。
但是這只是極少數的情況,在大部分情況下 Almost Standards 和 Standards 兩種模式是一致的,所以我們一般不專門區分二者,后面我們會提到如何查看瀏覽器渲染引擎信息,在這個信息中同樣對 Almost Standards Mode 和 Standards Mode 是不做區分的。
Quirks Mode 有兩種
如果我們將 IE 升級到最新的 IE10 就會發現 IE10 除了擁有 IE7/8/9/10 Standards Mode 四種 Standards Mode,同樣還有擁有了兩種 Quirks Mode:IE5 Quirks 和 IE10 Quirks。隨著 IE10 發布而產生的這個新的怪異模式 IE10 Quirks 被認為是一種更好的支持了 HTML5 規范的 Quirks Mode。我們可以發現針對 HTML5 規范而設計的頁面(如含有<audio>、<video>、<canvas>等標簽)在 IE5Quirks 下是不能正確顯示的,但是在 IE10 Quirks 下完全可以正確顯示。也就是說,IE10 Quirks 是為了在那些針對 HTML5 設計,但是又沒有添加 doctype(可以決定瀏覽器工作在哪種模式下,后面會詳細討論)的頁面而存在的。
如何查看 Document Mode
IE 中,用戶可以在 developer tools 中切換模式,如圖 1 所示,IE10 的六種文檔模式都被顯示在 Document Mode 菜單下,用戶可以直接選擇,下一章的 Demo 我們都采用 IE10(version: 10.0.9200.16576)作為測試瀏覽器。
圖 1 IE Document Mode
除了從 developer tools 中查看,還有可以從 document 對象的屬性 compatMode 中獲知文檔模式,這個屬性只有兩個值 BackCompat 和 CSS1Compat,前者對應的是 Quirks Mode 后者對應 Standards Mode。在 developer tools 中切換文檔模式時,頁面會自動刷新,compatMode 的值也會隨之改變。
瀏覽器如何判斷文檔類型?
上一節中我們知道 IE 用戶可以在 developer tools 中改變文檔模式。那么,如果用戶沒有自己選擇,瀏覽器在準備解析、繪制一個頁面的時候,它是如何決定文檔模式的呢?實際上瀏覽器在渲染頁面之前會檢查兩個內容,一個是頁面是否有 doctype 信息,另外一個是頁面是否有 x-ua-compatible 信息。
Doctype 檢測
對于一個 HTML 頁面,<!DOCTYP >聲明位于其中最前面的位置,處于<html>標簽之前,這個<!DOCTYP >可以告知瀏覽器使用哪種 HTML 規范,針對每種規范瀏覽器同樣也會選擇對應的文檔模式。平時最常見的三種 doctype 信息對應的文檔模式如下。
- 當 doctype 信息如下時,表明該頁面是遵守了 HTML5 規范的,瀏覽器會選擇 Standards Mode,這種 doctype 是最推薦的一種,我們平時設計頁面都應該加上這一個 doctype。
<!DOCTYPE html>
- 當 doctype 如下時,瀏覽器同樣會選擇 Standards Mode,雖然和第一種 doctype 有一些區別,但是幾乎可以認為是一樣的。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
- 當 doctype 如下時,瀏覽器會選擇 Almost Standards Mode,需要注意的是如果今后需要把這個頁面改為 HTML5 規范,那么上文討論的<table>中的分割圖片問題可能會錯亂。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- 當 doctype 缺失的時候,瀏覽器會選擇 Quirks Mode,這是非常不推薦的方式,我們應該盡量避免 Quirks Mode,這對一個 web 應用是非常不利的地方。
x-ua-compatible 信息
除了上一節提到的 doctype 檢測,HTML 頁面的開發者可以在頁面的<head>標簽中加入 x-ua-compatible 信息來影響文檔類型的判定,具體如下表所示。
表 3 x-ua-compatible 影響文檔類型
x-ua-compatible doctype Document Mode<meta http-equiv="X-UA-Compatible" content="IE=5" > | 無影響 | IE5 quirks |
<meta http-equiv="X-UA-Compatible" content="IE=7/8/9/10" > | 無影響 | IE7/8/9/10 Standards |
<meta http-equiv="X-UA-Compatible" content="IE=Edge" > | 無影響 | IE 最新版本的 Standards |
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7/8/9" > | <!DOCTYPE html> | IE7/8/9 Standards |
不存在 | IE5 quirks | |
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE10" > | <!DOCTYPE html> | IE10 Standards |
不存在 | IE10 quirks |
從表 3 可以看出,一般情況下 x-ua-compatible 是優先于 doctype 的設定的,但是當 x-ua-compatible 設定了如“EmulateIExx”的情況時,就會同樣考慮到 doctype 的影響。
另外,在<head>中加入 x-ua-compatible 信息與在請求消息的 header 中加入是等同的,如下代碼效果是等同的。
response.setHeader("X-UA-Compatible","IE=Edge"); <meta http-equiv="X-UA-Compatible" content="IE=Edge" >
到現在為止我們分析了 Quirks Mode 產生的歷史、對瀏覽器的影響以及瀏覽器如何選擇文檔模式。下一章我們主要討論兩種不同的文檔模式下渲染頁面的差別。
標準模式下的頁面與怪異模式下的頁面區別
這一章我們主要選擇一些典型的例子來說明 Quirks Mode 和 Standards Mode 對頁面渲染的影響。
盒模型
前面提到,盒模型(box mode)是瀏覽器 Quirks Mode 和 Standards Mode 的主要區別。
描述
對于“盒模型”一詞并沒有明確的文檔定義,它是開發人員描述 CSS 中塊級元素的一種約定俗稱。
具體而言,針對一個塊級元素,如<p>、<div>、<span>等,CSS 的規范定義了一個寬度和高度,以及 3 個級別的環繞它的框 padding、border 和 margin 。這些屬性我們可以把它轉移到我們日常生活中的盒子上來理解,所以將這種模型稱為盒模式。對于盒模型,針對高度和寬度的定義,不同瀏覽器的解釋不同。
出于歷史原因,早期的 IE 瀏覽器(IE 6 以前)將盒子的 padding 和 border 算到了盒子的尺寸中,這一模型被稱為 IE 盒模型。該模型如圖 2.1 所示,
圖 2 IE 盒模型
在 IE 盒模型中,
box width = content width + padding left + padding right + border left + border right,
box height = content height + padding top + padding bottom + border top + border bottom,
而在 W3C 標準的盒模型中,box 的大小就是 content 的大小,如圖 3 所示,
圖 3 W3C 標準盒模型
box width = content width,
box height = content height,
這一區別將導致頁面繪制時所有的塊級元素都出現很大的差別,所以兩種不同的文檔模式下的頁面也區別很大。
示例展示
如下代碼段所示,我們定義一個簡單的 DIV 元素,設定其寬度和高度分別為 500px,定義 border 為 50px,紅色。
清單 1
div.a{ width:500px; height:500px; border:50px; border-style:solid; border-color:red; }
分別在 IE 5 Quirks Mode 和 IE 8 Standards Mode 下運行,結果如圖 4 和 5 所示。明顯可以看到,在 Standards Mode 下的 DIV 要大于 Quirks Mode,其實際渲染大小為 600px*600px。
圖 4 IE 5 Quirks Mode
圖 5 IE 8 Standards Mode
圖片元素的垂直對齊方式
CSS 中 vertical-align 屬性用于設置或檢索對象內容垂直對齊方式,該屬性定義行內元素的 base line 相對于該元素所在行的 base line 的垂直對齊。在表單元格中,這個屬性會設置單元格框中的單元格內容的對齊方式。其取值可以為 baseline,sub,supper,top,text-top,bottom,text-bottom,middle 等。什么是 baseline 和 bottom,它們有何區別?下面我們通過一副圖來進行解釋。
描述
CSS 為了確定文字行的位置,定義如下概念描述,base line,bottom line,top line, middle line。其中,base line 指的是一行字橫排時下沿的基礎線,baseline 并不是漢字的下端沿,而是英文字母 e 的下端沿,bottom line,指的是漢字,或者英文字母 p,g 的下端沿。如下圖 6 所示。
圖 6 base line 概念
對于 inline 元素和 table-cell 元素,在 IE Standards Mode 下 vertical-align 屬性默認取值為 baseline。而當 inline 元素的內容只有圖片時,如 table 的單元格 table-cell。在 IE Quirks Mode 下,table 單元格中的圖片的 vertical align 屬性默認為 bottom,因此,在圖片底部會有幾像素的空間。
示例展示
如下代碼段所示,我們定義一行兩列的 table,table 單元格設定為寬度和高度均為 200px 的 img 圖片,為了突出顯示區別,分別定義單元格與圖片的邊框顏色為藍色和橘色。
清單 2
td.a { border-style:solid; border-color:blue; } img.c { width:200px; height:200px; border-style:solid; border-color:orange; }
分別在 IE 10 Quirks Mode 和 IE 8 Standards Mode 下運行,結果如圖 7 和 8 所示。在 Quirks Mode 下,table 單元格中的圖片與單元格底部對齊,而在 Standards Mode 下,圖片與單元格之間多了 3 個像素的空間。
圖 7 IE 10 Quirks Mode
圖 8 IE 8 Standards Mode
<table>元素中的字體
CSS 中,描述 font 的屬性有 font-family,font-size,font-style,font-weight,分別表示了 font 的族系、大小、風格以及粗細。
描述
在 CSS 標準中,上述屬性都是可以繼承的。而在 IE Quirks Mode 下,對于 table 元素,字體的某些屬性將不會從 body 或其他封閉元素繼承到 table 中,特別是 font-size 屬性。
示例展示
如下代碼段所示,我們定義 body 的 font 屬性為斜體、紅色、加粗、fantasy 字體,對于 table 元素,未定義其 font 屬性。
清單 3
body { font-style:italic; color:red; font-size:200%; font-weight:bold; font-family: fantasy; }
分別 IE 5 Quirks Mode 和 IE 8 Standards Mode 下運行,結果如圖 9 和 10 所示。在 Quirks Mode 下,table 單元格中字體的 font-size,font-style,font-weight 屬性不會繼承 body,只有 family 屬性會被繼承。而在 Standards Mode 下,所有屬性都被繼承。
圖 9 IE 5 Quirks Mode
圖 10 IE 8 Standards Mode
內聯元素的尺寸
CSS 中常見的元素有兩類,分別是 block(塊級)元素及 inline(內聯)元素。這兩類元素的主要區別在于 block 元素通常作為獨立的一塊繼續顯示,前后都有換行,而 inline 元素則不會產生換行。根據 CSS 標準,對于 inline 元素,又可以分為 replaced 和 non-replaced 兩類。
描述
什么是 non-replaced inline 元素?首先,我們解釋下 non-replaced 元素,對于 HTML 中定義的元素,默認具有 CSS 格式化外表范圍的元素,比如 img 元素,有自己的寬和高,我們稱其為 replaced 元素,其他例 input,textarea,select,object,等都是 replaced 元素。除了這些元素之外的元素就是 non-replaced 元素。因此,具有 non-replaced 屬性的 inline 元素即為 non-replaced inline 元素,如 span 元素。
在 IE Standards Mode 下,non-replaced inline 元素無法自定義大小,而在 IE Quirks Mode 下,定義這些元素的 width 和 height 屬性,能夠影響該元素顯示的大小尺寸。
示例展示
如下代碼段所示,為了突出顯示,我們定義一個背景色為橘色的 div 中嵌套一個 span 元素,該 span 元素的高和寬均為 200px,背景色為藍色。
清單 4
div.a { width:300px; height:300px; background-color:orange; } span.b { height:200px; width:200px; background-color:blue; }
分別在 IE 5 Quirks Mode 和 IE 8 Standards Mode 下運行,結果如圖 11 和 12 所示。在 Quirks Mode 下,span 元素能夠正常顯示,左圖中 200*200 的藍色的區塊。而在 Standards Mode 下,span 尺寸為零。
圖 11 IE 5 Quirks Mode
圖 12 IE 8 Standards Mode
元素的百分比高度
CSS 中對于元素的百分比高度規定如下,百分比為元素包含塊的高度,不可為負值。如果包含塊的高度沒有顯式給出,該值等同于“auto”(即取決于內容的高度)。所以百分比的高度必須在父元素有聲明高度時使用。
描述
當一個元素使用百分比高度時,在 IE Standards Mode 下,高度取決于內容的變化,而在 Quirks Mode 下,百分比高度則被正確應用。
示例展示
如下代碼所示,為了突出顯示,我們定義一個背景為粉色的 table,在 table 的單元格中嵌入一個背景為橘色的 div b,將該 div 的高度設置為 90%。定義 b 的子節點 c 為高度和寬度均為 200px 的 div 元素,背景為藍色。
清單 5
table.a { height:500px; background-color:pink; } div.b { background-color:orange; width:300px; height:90%; display:block; } div.c { width:200px; height:200px; background-color:blue; }
分別在 IE 5 Quirks Mode 和 IE 8 Standards Mode 下運行,結果如圖 13 和 14 所示。在 Quirks Mode 下,div b 的高度為 talle 單元格的 90%,而在 Standards Mode 下,div b 的高度由其子節點 c 決定,為 200px。
圖 13 IE 5 Quirks Mode
圖 14 IE 8 Standards Mode
元素溢出的處理
CSS 中 overflow 屬性定義了一個元素的內容不適合指定的尺寸時,溢出元素內容的處理方式。默認值為 visible,即顯示溢出。
描述
在 IE Standard Mode 下,overflow 取默認值 visible,即溢出可見,這種情況下,溢出內容不會被裁剪,呈現在元素框外。而在 Quirks Mode 下,該溢出被當做擴展 box 來對待,即元素的大小由其內容決定,溢出不會被裁剪,元素框自動調整,包含溢出內容。
示例展示
如下代碼段所示,我們定義一個背景為藍色的 div a,在 a 中嵌入一個背景為橘色的 div b,設置 b 的高度 400px 大于 a 的高度 300px,使 a 發生溢出。
清單 6
div.a { width:300px; height:300px; background-color:blue; } div.b { width:200px; height:400px; background-color:orange; }
分別在 IE 5 Quirks Mode 和 IE 8 Standards Mode 下運行,結果如圖 15 和 16 所示。在 Quirks Mode 下,div a 的高度為又 300px 變為 400px,以適應 b 的大小,而在 Standards Mode 下,div a 的大小保持不變,溢出部分保留。
圖 15 IE 5 Quirks Mode
圖 16 IE 8 Standards Mode
結束語
通過前文的描述我們已經知道 Quirks 和 Standards 這兩種文檔模式渲染頁面的時候會有很大的差別,這些差別主要是由于渲染引擎在歷史的發展過程中與 W3C 標準的差異性而導致的。
知道這些差異的存在和由來將對 Web 工程師的工作有很大的幫助。在新產品的開發中 Web 工程師應該讓頁面滿足 HTML5 規范,避免瀏覽器工作在 Quirks 模式下。另外一點是如果在維護只能工作在 Quirks 模式下的 Web 產品時,可以從 Quirks 模式的根源來出發,考慮如何改進使得產品回到 Standards 模式,這樣就可以添加進更多更好的功能。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
