淺談HTML文檔模式


不知道愛多想的你有沒有在編寫HTML代碼時思考過 <!DOCTYPE html> 或是這一長串看都看不懂的 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 的代碼,它是做什么的,為什么要有這句話,這句話起什么作用,它和其他HTML代碼有關嗎?嚶嚶嚶我才不回告訴你在前端的面試題中會經常看到對這個知識點的提問,而我們往往愛追求高大上的頁面效果卻忽略了最為基礎的文檔模式,沒有文檔模式的指揮,怎能得來高大上的頁面效果!!那就來從這篇總結中尋找答案吧!

 

文檔模式:

這個概念是通過使用文檔類型 doctype 切換實現的,最終的兩種渲染模式是混雜模式(quirks mode)和標准模式(standards mode)。這兩種模式的差別就是工作在不同版本渲染引擎環境下,混雜模式會讓IE的行為與(包含非標准特性的)IE5相同,標准模式則讓IE的行為更接近標准行為。這兩種模式主要影響css內容的呈現,在某些情況下也會JavaScript的解釋執行(后面會詳細說到)。之后IE又提出一種准標准模式(almost standards mode),這種模式下的瀏覽器特性有很多都是符合標准,但也不盡然,不標准的地方體現在處理圖片間隙的時候(在表格中使用圖片時問題最明顯)。標准模式和准標准模式非常接近,在檢測文檔模式時也不會發現什么不同,這里在提到標准模式時,指的是除混雜模式之外的其他模式。

 

文檔類型DOCTYPE定義和用法:

可以決定瀏覽器在哪種模式下工作。

  1. <!DOCTYPE>聲明必須是HTML文檔第一行,位於 <html> 標簽之前。
  2. <!DOCTYPE>聲明並不是HTML標簽;它是指示web瀏覽器關於頁面使用哪個HTML版本進行編寫的指令,告知瀏覽器的解析器用什么文檔類型規范來解析這個文檔,針對每種規范瀏覽器同樣也會選擇對應的文檔模式。
  3. HTML4.01中,<!DOCTYPE>聲明引用DTD,因為HTML4.01基於SGML(標准通用標記語言,是現時常用的超文本格式的最高層次標准,是可以定義標記語言的元語言。HTML和XML派生於它。XML可以被認為是它的一個子集,XML的出現就是為了簡化它以便用於更加通用的目的比如語義web,而HTML是它的一個應用)。DTD規定了標記語言的規則,讓瀏覽器的渲染去遵守這個規則才能正確地呈現內容。

    但HTML5不是基於SGML的因此不需要引用DTD。

 

文檔類型DOCTYPE的語法:

頂級元素 可用性 "注冊//組織//類型 標簽 定義//語言" "URL"

  1. <!DOCTYPE 這是XML 指定DTD文件的語法標簽,用來申明DTD,作用就像HTML中鏈接外部css文件用到的 <link> 標簽一樣,但<!DOCTYPE 這個標簽怎么使用是要遵循xml解釋器的內置規則(類似c語言編譯器內置的C語言語法),而<link標簽怎么使用遵循<!DOCTYPE 所引用的DTD文件對其指定的規則,這兩個還是有區別的,但是作用都是標簽要遵守它上級的規則。
  2. html 指定當前文檔最外層標簽,頂級元素,xml里面叫root(根)標簽(比如 <!DOCTYPE note SYSTEM "Note.dtd"> ),html是html(比如html5舉例 <!DOCTYPE html> )。通過document.doctype.name可獲取
  3. PUBLIC  說明指定的DTD文件是公共文件,相對私有文件來說的,也就是后面的url是任何人都可以訪問的,也可以是SYSTEM(從本地系統加載的DTD文件)。
  4. "-//W3C//DTD XHTML 1.0 Transitional//EN"  指定本html文件使用的DTD版本號,這個部只是針對html才有的。-/+指定組織是否由國際標准化組織ISO注冊,+表示名稱已注冊,-表示組織名未注冊。Internet工程任務組(IETF)和萬維網協會(W3C)並非注冊的ISO組織,所以html中的注冊項為-。組織指的是該!DOCTYPE聲明引用的DTD文件的創建和維護的團體是W3C組織。DTD為所引用的對象類型,XHTML 1.0表示公開文本描述,后面可附帶版本號。Transitional表示文檔類型定義是過渡型的,共三種下面介紹。EN表示指定的公開文本語言為英文。document.doctype.publicId可獲取。
  5. URL 指定所引用DTD對象的位置 ,document.doctype.systemId可獲取。一個DTD文檔包含元素定義的規則,元素間關系的定義規則,元素可使用的屬性,可使用的實體和符號規則。

 

DTD(document type definition):

DTD標准可以理解成一種語法,這種語法規定了標簽嵌套的規則,從而使HTML或XML的展示效果不會亂來。不同的DTD文件說明不同的標准DTD。DTD實際上是一個約束規則,規定文檔中合法的都哪些元素,以及元素之間使用規則。

 

詳解:

如果在文檔開始處沒有發現文檔類型聲明,則所有瀏覽器都會默認開啟混雜模式,不同瀏覽器在這種模式下行為差異很大,如果不使用某些hack技術,跨瀏覽器的行為根本沒有一致性可言。

(1).混雜模式:不引用任何文檔類型定義,對文檔的渲染影響很大。
(2).標准模式:可以使用下面任何一種文檔類型來開啟,使用嚴格型(strict)文檔來觸發。

//html
該DTD包含所有HTML元素和屬性,但不包含展示性的和棄用的元素(比如font),不允許框架集(Framesets)
<!-- HTML 4.01 嚴格型 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <!-- HTML5 --> <!DOCTYPE html> //xhtml
該DTD包含所有HTML元素和屬性,但不包含展示性的和棄用的元素(比如font),不允許框架集(Framesets)。必須以格式正確的XML來編寫標記
<!-- XHTML 1.0嚴格型 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

(3).准標准模式:使用過渡型(transitional)或框架集型(frameset)文檔來觸發。

//html
該DTD包含所有HTML元素和屬性,包括展示性的和棄用的元素(比如font),不允許框架集(Framesets)。
<!-- HTML 4.01 過渡型 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
該DTD包含所有HTML元素和屬性,包括展示性的和棄用的元素(比如font),但允許框架集內容。 <!-- HTML 4.01 框架集型--> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"> //xhtml
該DTD包含所有HTML元素和屬性,包括展示性的和棄用的元素(比如font),不允許框架集(Framesets),必須以格式正確的XML來編寫標記。
<!-- XHTML 1.0 過渡型 --> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
該DTD包含所有所有HTML元素和屬性,包括展示性的和棄用的元素(比如font),允許框架集內容。 <!-- XHTML 1.0 框架集型 --> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

關於所有的 HTML5/HTML 4.01/XHTML 元素,以及它們會出現在什么文檔類型 (DTD) 中可參考HTML元素和有效的DTD
使用過渡型的DTD允許我們使用表現層的標識,元素,屬性(指那些純粹用來控制表現的tag,例如用於排版的表格,背景顏色標識等),也比較容易通過W3C代碼校驗。但HTML5強調HTML標識是用來表示結構,用css實現表現形式,也就是數據和表現相分離,所以盡量還是不要使用過渡型和框架型。

 

當瀏覽器開啟了混雜模式的時候

影響css的情況

主要是IE瀏覽器,其他Chrome,FF以及IE高版本瀏覽器無論在什么模式下都能正常顯示

  1. 盒模型是混雜模式和標准模式的主要區別
    <=IE6將盒子的padding和border算到盒子尺寸中,這被稱為IE盒模型。
    W3C標准的盒模型中,box大小就是content大小。
    這一區別將導致頁面繪制時所有塊級元素都出現很大差別,所以兩種不同的文檔模式下的頁面也區別很大。
  2. 影響圖片元素的垂直對齊方式,就是在行框對基線的選擇,IE的怪異模式會以Bottom-line為基線,標准模式下以base-line為基線。
  3. 影響table元素繼承字體的某些屬性,在IE5的怪異模式下不會繼元素的一部分屬性,尤其是font-size屬性。
  4. IE5怪異模式中內聯元素可以定義尺寸
  5. IE標准模式下,overflow取值為visible即溢出可見,在怪異模式下該溢出會被當作擴展box來對待,元素的大小由其內容決定,溢出不會被裁剪,而是父元素會自動調整自己的寬高以完全適應包含內容。

影響javascript的情況

跨瀏覽器確定一個窗口大小不是一件簡單事,注意以下介紹的屬性獲取后的值都是整數而且沒單位,即使是小數瀏覽器計算時也會四舍五入。
IE9+,FF,Safari,Opera,Chrome均為此提供四個屬性:innerWidth,innerHeight,outerWidth,outerHeight。

  1. IE9+,Safari,FF:outerWidth,outerHeight返回瀏覽器窗口本身尺寸(無論是從最外層的window對象還是從某個框架訪問)。innerWidth和innerHeight返回各自視圖區高度(減去邊框寬度)。
  2. Opera:outerWidth,outerHeight表示頁面視圖容器的大小。innerWidth和innerHeight表示頁面表示該容器中頁面視圖區大小(減去邊框寬度)。
  3. Chrome:JavaScript高程上說outerWidth和outerHeight與innerWidth和innerHeight返回相同的值,即視口大小而非瀏覽器窗口大小。(??經測試並沒有,表現的和其他瀏覽器一致都是瀏覽器窗口尺寸和視口區尺寸)                
     

雖然<=IE8沒有取得瀏覽器窗口尺寸的屬性,但是可通過DOM提供頁面可見區域的相關信息:雖然最終無法確定瀏覽器窗口本身大小但卻可以取得頁面視口大小。
IE,FF,Safari,Opera,Chrome中,document.documentElement.clientWidth和document.documentElement.clientHeight保存頁面視口信息。高版本的IE和Chrome,FF瀏覽器在標准模式下是優先選擇document.documentElement的,而document.body根據body元素內容寬高來計算的。在混雜模式下高版本IE和Chrome的document.documentElement和document.body計算的值一樣,但FF不正常。

(1)FF44.0.2 版本瀏覽器測驗:標准模式表現下正常,混雜模式下document.body計算值正確,但document.documentElement計算有誤。

(2)但在IE6中這些屬性必須在標准模式下才有效,如果在混雜模式就必須通過document.body.clientWidth和document.body.clientHeight取得相同信息。這里模擬了一下IE5文檔模式,可見在混雜模式下只有document.body可用,而且獲取的值還不一定正確。模擬IE7在標准模式下是優先選擇document.documentELement的,但是獲取的值也不一定正確。高版本的IE表現正常。


(3)標准模式下的Chrome46.0.2490.80 ,要優先選擇document.documentElement計算視口,而document.body.clientWidth和clientHeight默認是body元素所包含內容的總寬高,這里我設置body的width為200px了。

混雜模式下的Chrome,無論通過document.documentElement還是document.body中的clientWidth和clientHeight屬性都可取得視口大小。

//獲取頁面可見視口寬高,向后兼容
function visualViewport(){
  var visualobj={};
  visualobj.pageWidth=window.innerWidth,
  visualobj.pageHeight=window.innerHeight;
  //<=IE8不支持上面兩種屬性
  if(typeof visualobj.pageWidth!="number"){
        if(document.compatMode=="CSS1Compat"){
            visualobj.pageWidth=window.documentElement.clientWidth;
            visualobj.pageHeight=window.documentElement.clientHeight;
        }else{
            //兼容三大主流瀏覽器的混雜模式(因為FF在混雜模式下document.documentElement的兩個屬性表現不正常,所以集中用document.body)
            visualobj.pageWidth=window.body.clientWidth;
            visualobj.pageHeight=window.body.clinetHeight;
        }
    }
     return visualobj;
    }

 

參考

《JavaScript高級程序設計》

HTML<!DOCTYPE>標簽

怎么看網頁是使用哪個HTML版本編寫的?

DOCTYPE作用及用法詳解

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

DTD詳解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM