什麼是 Quirks Mode? 簡單來講,Quirks Mode 就是瀏覽器爲了兼容很早以前針對舊版本瀏覽器設計、並未嚴格遵循 W3C 標準的網頁而產生的一種頁面渲染模式。 html
由渲染引擎產生的兩種文檔模式 web
談到 Quirks modes 首先就要從瀏覽器渲染引擎提及。咱們知道全部的瀏覽器都有本身的頁面渲染引擎,渲染引擎主要包含兩部分,一部分負責 HTML、CSS 代碼的解析,另外一部分負責腳本代碼解析,這兩部分合起來就能夠繪製出完整的頁面。 canvas
IE | Trident | -- | Chakra |
---|---|---|---|
Firefox | 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 頁面的渲染改變以下。 ide
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 | 首次支持 HTML五、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。 ui
Quirks 和 Standards 以外的第三種模式 spa
實際上,在上文提到的具備 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)做爲測試瀏覽器。
除了從 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 html>
<!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">
x-ua-compatible 信息
除了上一節提到的 doctype 檢測,HTML 頁面的開發者能夠在頁面的<head>標籤中加入 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 所示,
在 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 所示,
box width = content width,
box height = content height,
這一區別將致使頁面繪製時全部的塊級元素都出現很大的差異,因此兩種不一樣的文檔模式下的頁面也區別很大。
示例展現
以下代碼段所示,咱們定義一個簡單的 DIV 元素,設定其寬度和高度分別爲 500px,定義 border 爲 50px,紅色。
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。
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 所示。
對於 inline 元素和 table-cell 元素,在 IE Standards Mode 下 vertical-align 屬性默認取值爲 baseline。而當 inline 元素的內容只有圖片時,如 table 的單元格 table-cell。在 IE Quirks Mode 下,table 單元格中的圖片的 vertical align 屬性默認爲 bottom,所以,在圖片底部會有幾像素的空間。
示例展現
以下代碼段所示,咱們定義一行兩列的 table,table 單元格設定爲寬度和高度均爲 200px 的 img 圖片,爲了突出顯示區別,分別定義單元格與圖片的邊框顏色爲藍色和橘色。
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 個像素的空間。
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 屬性。
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 下,全部屬性都被繼承。
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,背景色爲藍色。
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 尺寸爲零。
CSS 中對於元素的百分比高度規定以下,百分比爲元素包含塊的高度,不可爲負值。若是包含塊的高度沒有顯式給出,該值等同於「auto」(即取決於內容的高度)。因此百分比的高度必須在父元素有聲明高度時使用。
描述
當一個元素使用百分比高度時,在 IE Standards Mode 下,高度取決於內容的變化,而在 Quirks Mode 下,百分比高度則被正確應用。
示例展現
以下代碼所示,爲了突出顯示,咱們定義一個背景爲粉色的 table,在 table 的單元格中嵌入一個背景爲橘色的 div b,將該 div 的高度設置爲 90%。定義 b 的子節點 c 爲高度和寬度均爲 200px 的 div 元素,背景爲藍色。
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。
CSS 中 overflow 屬性定義了一個元素的內容不適合指定的尺寸時,溢出元素內容的處理方式。默認值爲 visible,即顯示溢出。
描述
在 IE Standard Mode 下,overflow 取默認值 visible,即溢出可見,這種狀況下,溢出內容不會被裁剪,呈如今元素框外。而在 Quirks Mode 下,該溢出被當作擴展 box 來對待,即元素的大小由其內容決定,溢出不會被裁剪,元素框自動調整,包含溢出內容。
示例展現
以下代碼段所示,咱們定義一個背景爲藍色的 div a,在 a 中嵌入一個背景爲橘色的 div b,設置 b 的高度 400px 大於 a 的高度 300px,使 a 發生溢出。
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 的大小保持不變,溢出部分保留。
經過前文的描述咱們已經知道 Quirks 和 Standards 這兩種文檔模式渲染頁面的時候會有很大的差異,這些差異主要是因爲渲染引擎在歷史的發展過程當中與 W3C 標準的差別性而致使的。
知道這些差別的存在和由來將對 Web 工程師的工做有很大的幫助。在新產品的開發中 Web 工程師應該讓頁面知足 HTML5 規範,避免瀏覽器工做在 Quirks 模式下。另一點是若是在維護只能工做在 Quirks 模式下的 Web 產品時,能夠從 Quirks 模式的根源來出發,考慮如何改進使得產品回到 Standards 模式,這樣就能夠添加進更多更好的功能。