你重構過自己的頁面嗎?——DOCTYPE的魔咒!(上)

作者: rainnoless  來源: 博客園  發布時間: 2009-03-09 16:17  閱讀: 1785 次  推薦: 1   原文鏈接   [收藏]  

前言如果您知道我有多么辛苦、多么用心的寫著這篇文字,出于同情,您或許會捎上一眼。想要將自己的文字發布在園子的首頁上,就必須用心去寫,上班時白天在公司用著一臺實際上只有480MB可用內存的臺機,在IE7的窗口中敲打著這篇文字,當我插入了“1.1代碼示例”之后,明顯感覺所有瀏覽器窗口就如同當機時一般無法動彈,內存瞬間被吃200MB+,我想是無法繼續在IE7下工作了,想把這篇文字迅速編輯完成的夢想頓時破滅了。存稿,關閉IE7,打開Chrome,嗯,還不錯,至少內存沒被吃太多,編輯器窗口的滾動條還能拖動,我又可以工作了。我的天啊,插入圖片,上傳按鈕失效,老天你不能這樣對我,于是,我又切換到Firefox,OK,終于可以插入圖片了,卻Firefox下,似乎也不是那么順暢,于是我在幾個瀏覽器之間尋求平衡與協作。周末了,終于我熬了兩個通宵,花費了很多本該休息的時間,完成了一個“上篇”,真不知道“下篇”還會耗費我多少不再年輕的“青春”呢?如果您,是一個有點愛心的人,給我點鼓勵吧,呵呵。

      不知道您是否閱讀過 Jeffrey Zeldman 的大作《網站重構——應用Web標準進行設計》(第二版) 這本書,即使您沒有翻閱過此書,那么您也應該或多或少聽說過 W3C 這個詞匯吧,當然《網站重構》這本書并非 W3C官方出品,也非官方代言書籍,但是書中所滲透出的思想卻是對 W3C 標準和規范的闡釋,什么是 Web 標準,如何利用標準進行設計,正是Zeldman在書中用了大量生動的實例所闡述的。

       Zeldman 在他的著作中說過:“……許多設計師和開發者都認為 Web 標準只是一個夢想,許多人甚至放棄了正確實現他們的努力。這并不難理解,理解需要多年才能形成。”

       在當今這個花花的 Web 世界里,沒有一種瀏覽器是完美的,每種瀏覽器在使用標準和可訪問性上都各有所長。我一直很喜歡IE 在字體上的呈現度上,從我的眼睛看去同樣的字體下 IE 總是比其他瀏覽器更為豐滿些,看起來更舒服些,當然這僅僅是我的觀點。至于從實現 W3C 標準和規范的角度來說,非 IE 系列的現代瀏覽器都有著非常良好的表現,當然 IE7+ 也并非一無是處,其對于標準和規范的理解及實現只是稍有欠缺罷了。

       說了這么多,我是被《網站重構》鼓動了的心思,可拿什么頁面來嘗試一下重構樂趣呢?這不,公司首頁改版,外包給美工的靜態頁面交付完工了,某領導最初的設想是讓我按照以前其他同事的方式寫幾個 aspx 頁面,然后通過iframe 將這些“動態”顯示的數據嵌入到靜態的首頁中去,我很反感這樣做,于是以理抗爭說服了領導同志按照我的想法直接將首頁改為了 aspx 頁面。我的工作終于由分別寫幾個 aspx 頁面,變成了專注于寫一個 aspx 頁面,貌似輕松不少。一百來行服務器端代碼,嘩嘩啦啦的一個小時不到就寫完了,可我花在研究 aspx 頁面中 HTML 代碼上的時間卻不少,如何將動態讀取到的數據“安靜、不唐突、悄悄的”復原到靜態的模板頁上,應該采用何種服務器端數據控件動態顯示從數據庫中讀取的數據等。在思考中我浪費了不少時間讀取那糟糕的 HTML 源碼,Table 布局帶給我的視覺沖擊就是大量的

[……]
伴隨著數不清的 HTML 標簽屬性,以及少量使用 style 屬性抒寫的樣式規則。我的天啊,這忽然讓我想起了兩年前第一次嘗試用 Table 布局來組織一個頁面時的痛苦,不知道什么地方會千奇百怪多出來的一個像素,整個 Table 或許會無緣無故的膨脹了起來,那些曾經的痛苦都留在記憶。

  是的,在忍受了 Table 帶給我的痛苦不久后,接觸了 CSS 這個神奇的家伙,我囫圇吞棗的了解基本規則,對著中國同胞整理的 CSS2.1 手冊,開始自己的第一次“DIV之旅”。那時我只是一味的將所有的 Table 全部替換成了“DIV + 絕對定位”,那種對頁面上內容的控制欲讓我成為了一個十足的“多 div 癥”患者。如今回首,那時的我只做了一件事:嘗試用 div 重建自己原來的表格結構。用一套不必要(或不合理)的標簽替換了另一套不必要(或不合理)的標簽。

       您或許會覺得我的旁白有點過于啰嗦,如果您不是早已麻木到遺忘地步,那您肯定沒有經歷過與我類似的痛苦,也沒有動手嘗試過像一位 divitis 患者一樣重構過自己設計過的頁面。那就來吧,和我一起經歷一次又何妨。

       首先,請您來看看根據靜態頁面按照要求修改而成的 aspx 的頁面源碼,請您注意 HTML 結構部分我未作任何修改,在您打開折疊的示例代碼前,我友善的提醒一下您,做好心理準備,看一眼就可以重新折疊上代碼了,因為我怕您“夢回2001”(2001年開始大量使用CSS來表現樣式的頁面出現,其結構和布局類似于下列代碼中所見),但是很感謝您坐在2009年當下的電腦屏幕前認真地閱讀我的文字。

  百克網(這里建議您直接訪問我公司首頁,看看頁面的效果,您或許會發現,嗨,還不錯啊,頁面設計的很簡樸啊,恭喜您使用的是 IE 系列瀏覽器;如果您看見了什么奇怪異樣的頁面,那么恭喜您使用的應該是 Chrome 瀏覽器;如果您發現正在使用的瀏覽器下頁面的表現和 IE 下 看起來只有少許異樣,那么您或許使用的是 Mozilla 系列瀏覽器。如果您正在使用非 IE 系列瀏覽器閱讀該篇文字,那么可以通過瀏覽器點擊源碼閱讀。)首頁 aspx 源碼如下:

1.1代碼示例

 

  您如果看過頁面的 HTML 源碼后,有什么感觸,是否有被電到的感覺呢?呵呵,其實網絡上充斥著這樣的頁面代碼很多,而且運行良好,維護似乎看起來也很方便,在當今寬帶當道的網絡世界,小小的一個首頁浪費的流量算得了什么,ISP 服務商提供的是不限制流量的服務,大家盡情的訪問吧,不會對網站的經營者增加什么額外“超流量”費用。當然在特定環境下,也不大會讓自己的顧客因為無法忍受網頁顯示速度慢(大多數頁面打開緩慢的原因還是根源于網速的問題,不是客戶的就是服務商的網速)而關閉瀏覽器窗口。

 

  好了,有點耐心,跟著我來一次有點“齷齪”的重構,“齷齪”從何而來,看完整篇文字您或許也會有所體味。

  下面要展示兩幅圖片,圖片1是公司某位領導構想的新首頁布局,在這位領導強硬的態度下,經過幾次無謂的修改后,老總終于妥協了,將這張圖交付給外包的美工手中,不久就出圖并制作好了靜態頁面。
                 

 

圖片1

  又過了兩天,按照領導布置給我的要求經過部分加工,并做些簡單的測試,例如每個鏈接是否有效,在 IE 系列瀏覽器上是否正常顯示布局等,終于如您點擊百克網所看到的,也正是下面圖片2這樣截圖所展示的一般:

圖片2

  

 

     不得不說,從圖片2中可以清晰看出美工非常忠實的實現了圖片1中的布局,并且沿襲了公司上一個首頁版本中的很多元素,依然選擇暖色調“橙色”作為主色調,在上海這個甚似冬天的春天里,讓人覺得多了一絲暖意。

  OK,來吧,是該動手的時候了,否則您一定會不耐煩的離開,因為我們似乎離“重構頁面”的設想越走越遠,上面說了那么多無非是想讓您和我一樣有“重構”的沖動罷了,不知道是否能如愿呢?

  請仔細看看圖片1吧,抽出最重要的部分,您勾勒出的是一個什么樣的布局框架呢?是的,下圖就是我從圖片1中所抽象出的布局:

 

   圖片3

  對,上圖是一個典型的三列布局的框架圖(圖中尺寸標注有少許錯誤,1000px應該改為1002px,周一會上傳更正后的新圖片),重構就從這里開始吧,從實現一個簡單的三列布局開始。

 

  其實,早在拿到圖片1時,我就私下開始嘗試自己的“實現”,只可惜自己的平面設計能力停滯在10年前大學生活的那段歷史里,我只能想著如何忠實還原圖片1中的一切,于是在顯示器的實際分辨率為 1024*786 的情況下按照 800*600 的分辨率情況開始了布局設計,其 HTML 結構如下:

 

800*600分辨率下三列布局HTML代碼示例


     HTML 代碼中外部導入的樣式表 indexStyle.css 的源碼如下:

三列布局的樣式表示例


  
     好的,非常好,我從 Andy Budd 那里學到的三列布局技巧終于派上了用場,我迫不及待的在 IE7+、Chrome1.0、Firefox3.0+、Opera9.5+、Navigator9.0+等現代瀏覽器上測試了一番,結果如預期一般,在非 IE 瀏覽器中我獲得了幾乎一直的三列布局效果,結果就是非 IE 瀏覽器們很好的解析了我編寫的 CSS,頁面上看起來絲毫不差可謂相當滿意。這不,唯獨在 IE7 下,頁面看起來稍微有點別扭,不,是殘缺,您來和我一起看看 IE7 如何表現的吧!截圖如下:

                        圖片4

  如果您只是一名 HTML 和 CSS 方面的新手,不怕麻煩,建議您花上少許的時間,把示例中的 HTML 代碼和CSS 代碼分別拷貝到記事本中,然后分別將拷貝了 HTML 代碼的記事本文件改名為 index.html,將拷貝了 CSS 代碼的記事本文件更名為 indexStyle.css,并將更名后的兩個文件放置于同一個文件夾內,其后您可以通過點擊 index.html 文件,就可以看到如圖片4中一般的畫面了(如果是以 IE7 為默認瀏覽器的話)。如果您是一名熟練的老手了,是否已看出問題所在了呢?

 

  來吧,看看我當時遇見問題時的簡單分析,還原我最初的思考,希望您不曾遇見過如此討厭的情景。

 

  當您無法改變自己身處的環境時候,您就得去適應它,而我,就是那個必須去適應自己所處環境的人之一。公司網站的開發基于.NET 1.1,使用的 IDE 理所當然的就是 VS2003 了,而這卻埋下了圖片4中奇怪現象的種子。我曾經習慣在不去關注 aspx 頁面中的 DOCTYPE,在沒有進入目前的這家公司之前我使用的 IDE 是 VS2005,其 aspx 頁面的 DOCTYPE 都是 XHTML,那是一種無論如何都能和 Web 標準攀上親戚的 DOCTYPE,是具有良好的標準特性的文檔類型,當然能以一種符合標準的模式來解析頁面上 HTML 的結構和 CSS 所表現的樣式。如果不幸的是由于VS2003自動生成的 aspx 頁面中的 DOCTYPE 為:。按照 Web 標準的 CSS2.1 對頁面進行三列布局,無論如何都無法做到在 IE7+ 下與 Chrome、Firefox3.0+ 和 Opera9.5+等現代瀏覽器下獲得幾乎一致的表現結果,這其中究竟又是如何呢?

 

  Chrome 與 Firefox3.0+ 等瀏覽器所獲得布局結果表現幾乎一致,能夠完美的按照設想的表現來布局,可在 IE7 下,總是表現很怪異,從圖片4中,細心的您是可以找出 IE7 下布局表現的結果與其它非 IE 瀏覽器不一樣的地方,您是否發現 sideContent 這塊區域的左邊框線消失在了屏幕上,而且 secondaryContent 整塊塊區域通過目測應該向左偏移了3px以上的距離。這一切都根源于當前的 IE7 在解析盒模型時,對設置了“空白邊 ”(margin)的“塊級元素”(div)并沒有將div的邊框寬度計算在其 width 和 height 之中,而在 Chrome 與 Firefox3.0 等瀏覽器下,按照標準的盒模型解析時候,設置了 margin 的 div 元素的邊框寬度均計算在內了。

  想了很多辦法,甚至想過是否能夠找到某些 HACK 方法,在創建一個 id 選擇器所對應的樣式時,讓 IE7 解析到專門為其設置好的margin值,然后緊跟其后是一條讓 IE7 無法解讀的屬性規則(該規則是符合CSS標準的),這樣IE7就不再繼續閱讀之后定義屬性規則,從而做到能夠按照我設想的那樣在 IE7 上進行布局。同時,在那一條 IE7 無法解讀的屬性規則下,我再設置一個 margin 值,當在Chrome 和 firefox3.0 等對 Web 標準實現更完美的瀏覽器下,能夠順利閱讀那條“無法解讀的屬性規則”的話,就會將后一個 margin 值覆蓋前一個專為 IE7 設置的 margin 值。

很可惜,上面這一切,我并沒有實現,我的嘗試失敗了,因為 IE7 不是 IE6/IE5.x,她能夠識別很多她的前輩們無法閱讀的規則屬性。我甚至想過,利用 IE瀏覽器專有的“有條件注釋”,為 IE7+ 瀏覽器寫一個專有的樣式表,然后通過下列規則導入樣式表: -->。可這是解決問題的最終之道嗎?招數、專有,這些打上標簽的名詞是在我們“走投無路”時才會想起的救命稻草,可此時我還沒有走到山窮水盡的地步,不是嗎?為什么只會在 IE7+ 下表現如此怪異,而在 IE6/IE5.x 下布局完全變得的支離破碎呢,卻又在非 IE 瀏覽器下完美之至呢?

 

 

    既然 IE7 下表現是那么怪異,加上上面那些分析,其解析盒模型的方式如此接近 IE6/IE5.x又不完全是,我忽然想到了一詞,一個非常貼切用于形容此刻瀏覽器所表現出來的狀態的詞匯——怪異模式(quirks mode)。OK,就是它在作弄我們,忽然想起曾經在 Andy Budd 的大作中學習過 DOCTYPE 聲明的另一個重要作用,就是切換瀏覽器的表現模式,一般來說瀏覽器都存在兩種表現模式:標準模式和怪異模式(quirks mode)。顧名思義,在標準模式中,瀏覽器根據 Web 標準的規范表現頁面;在怪異模式中,頁面以一種比較寬松的向后兼容的方式顯示。怪異模式通常模擬老式瀏覽器的行為,最顯著的例子當然就是 Windows 上 IE 專有的盒模型。在 IE6 中,在標準模式中使用正確的盒模型,在怪異模式中使用老式的專有盒模型。

    為驗證上面的概述是否也適合 IE7 瀏覽器呢,三列布局中所呈現的怪異結果,是否因為 IE7 瀏覽器的怪異模式下工作所致呢?于是乎,我迫不及待的將 aspx 頁面中的DOCTYPE聲明簡單的修改HTML 4.01 Transitional + URI的形式,即:,您猜怎么著,果不其然,IE7 下怪異的布局消失了,其展現出的結果與Firefox、Chrome等現代瀏覽器一致完美,看來問題的根結就起源于瀏覽器的怪異模式。

 

 

 

 

那么,如何判斷瀏覽器會采用那種模式工作,一個大致的原則如下:如果 XHTML 文檔包含形式完整的DOCTYPE,那么一般以標準模式表現。對于 HTML4.01 文檔,包含嚴格 DTD 的 DOCTYPE 常常也會導致頁面以標準模式表現。包含過度 DTD 和URI 的 DOCTYPE 也導致頁面以標準模式表現,但是有過度 DTD 而沒有 URI 會導致頁面以怪異模式表現(正是我所展示的aspx 頁面最初的狀態,缺少URI)。DOCTYPE 不存在或形式不正確也會導致 HTML 和 XHTML 文檔以怪異模式表現。

在這方面的深入研究,CSS 大師 Eric Meyer 制作的一張圖表,這張圖表中說明不同的瀏覽器如何根據 DOCTYPE 聲明選擇表示方式的。如果您覺得去研究這種圖片很麻煩,也不大原因去記憶我上面給出的那些通用準則的話,在這我可以教您一個最簡單的辦法,來觀察您的瀏覽器當前處于何種模式下工作。實施這個方法的前提是,您必須安裝一款 Firefox 系列的瀏覽器(最好為簡體中文),然后將鼠標放在您瀏覽的當前頁面上,點擊鼠標右鍵——查看頁面信息——渲染模式。對了,我們要找的就是這個渲染模式,如果您看見其后寫著“混雜模式”,那就是表示當前瀏覽器處在“quirks mode”了。

在了解我設計中遇見的“怪異”問題后,請大家切記:無論是否編寫了有效且符合標準的CSS,如果您選擇了錯誤的DOCTYPE,那么頁面就有可能以怪異模式表現,其表現就可能會有錯誤或不可預測存在。當然,這些不可預測會像折磨我一樣折磨這你,不是嗎?

寫到這里,我的上篇就此告一段落了,編輯、排版、插圖實在很辛苦,一個非常簡單的問題,往往會折騰了大半天。當然,如果您看到這里,真誠的感謝您,陪著我一起受累了,如果您對我所描述的這些文字有那么一點點感興趣,同時我所描述的內容能給您帶來一點點受益,我就很滿足了。

當然,真正的重構才剛剛開始,如果您有興趣,那么就盡請期待我的下篇吧,謝謝您的光臨!

 

                           rainnoless 2009.03.09 5:28 

 

 

 

 

 

 

 

1
0
 
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()