怪異模式(Quirks Mode)對 HTML 頁面的影響

怪異模式(Quirks Mode)對 HTML 頁面的影響

Quirks Mode 概述

定義

什麼是 Quirks Mode? 簡單來說,Quirks Mode 就是瀏覽器爲了兼容很早之前針對舊版本瀏覽器設計、並未嚴格遵循 W3C 標準的網頁而產生的一種頁面渲染模式。

歷史

由渲染引擎產生的兩種文檔模式

談到 Quirks modes 首先就要從瀏覽器渲染引擎說起。我們知道所有的瀏覽器都有自己的頁面渲染引擎,渲染引擎主要包含兩部分,一部分負責 HTML、CSS 代碼的解析,另一部分負責腳本代碼解析,這兩部分合起來就可以繪製出完整的頁面。

表 1 各瀏覽器渲染引擎構成
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 頁面的渲染改變如下。

表 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

圖 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 盒模型

圖 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 標準盒模型

圖 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

圖 4 IE 5 Quirks Mode

圖 5 IE 8 Standards 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 概念

圖 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

圖 7 IE 10 Quirks Mode

圖 8 IE 8 Standards 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

圖 9 IE 5 Quirks Mode

圖 10 IE 8 Standards 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

圖 11 IE 5 Quirks Mode

圖 12 IE 8 Standards 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

圖 13 IE 5 Quirks Mode

圖 14 IE 8 Standards 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

圖 15 IE 5 Quirks Mode

圖 16 IE 8 Standards Mode

圖 16 IE 8 Standards Mode

 

結束語

通過前文的描述我們已經知道 Quirks 和 Standards 這兩種文檔模式渲染頁面的時候會有很大的差別,這些差別主要是由於渲染引擎在歷史的發展過程中與 W3C 標準的差異性而導致的。

知道這些差異的存在和由來將對 Web 工程師的工作有很大的幫助。在新產品的開發中 Web 工程師應該讓頁面滿足 HTML5 規範,避免瀏覽器工作在 Quirks 模式下。另外一點是如果在維護只能工作在 Quirks 模式下的 Web 產品時,可以從 Quirks 模式的根源來出發,考慮如何改進使得產品回到 Standards 模式,這樣就可以添加進更多更好的功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章