有多種方式可以將漸進增強融入到層疊樣式表(Cascading Style Sheets, 簡稱CSS)的工作中,本文將討論其中比較成功的一些,並考慮採用其它方式來逐步增強你的站點。
樣式表的組織如何在文件中引入樣式表,很多Web設計者和開發者並沒有想太多,但這其實是一門藝術。使用正確的方法,可以立即獲得漸進增強的許多好處。
使用多個樣式表對樣式進行稍許拆分可以帶來許多好處。顯而易見,超過1500行的樣式表是有點難以維護的,將其拆分成多個樣式表,可以改進工作流程(並節省你的精力)。還有一個好處很少提及:有助於在目標媒介類型(譯註:指電腦、印表機、電視、手機等各種媒介類型)上獲得更一致的呈現效果。
main.css檔案包含了網站的所有樣式規則,考慮將其拆分成包含版式、佈局和顏色的獨立樣式表,相應地命名為:type.css, layout.css, color.css.
(圖示:如何將單一樣式表拆分成多個相關的樣式表)
一旦完成了上面的分離,就可以使用一點神奇的小手段來給過時的瀏覽器(比如IE5/Mac)和很多對CSS佈局缺乏有力支持的瀏覽器自動提供“低保真”的體驗。怎麼做呢?這完全取決你如何引入文件。假設透過link元素來引入main.css:
Example Source Code
[www.downcodes.com] <link rel="stylesheet" type="text/css" href="main.css" />
首先,將上面一行引用拆分成三個相關的樣式表:
Example Source Code
[www.downcodes.com] <link rel="stylesheet" type="text/css" href="type.css" />
<link rel="stylesheet" type="text/css" href="layout.css" />
<link rel="stylesheet" type="text/css" href="color.css" />
在過去,許多開發者將media的值設為”screen”或”projection”, 以使得佈局樣式在Netscape 4.x上徹底失效(譯註:Netscape 4.x不支援浮動和定位等複雜佈局)。然而,有更好的解決方法。在詳細講解這個方法之前,我們先來看看選用媒介類型(Alternate Media Types)。
可選媒介類型漸進增強主要關注內容,我們要將「增強」的體驗帶到所有支援內容顯示的裝置。因此需要考慮瀏覽器以外的設備,例如列印和行動裝置就很重要。
糟糕地是,行動裝置市場依舊四分五裂而且不成熟(不要天真地認為所有手持瀏覽器都會渲染目標為「screen」的媒介類型樣式)。結果,用漸進增強的方式來處理所有媒介的細節討論,如果不寫成一本書的話,也得用上好多篇幅。然而請別沮喪:在行動世界裡,差異正開始統一起來,並且一些非常聰明的人正開始將資源放在一起以幫助我們發展。不過,為了節約時間和節省精力,我們將集中在列印設備上。
通常,我們需要使用另一個link元素來新增列印樣式:
Example Source Code
[www.downcodes.com] <link rel="stylesheet" type="text/css" media="print" href="print.css" />
依照慣例,上面這個樣式表包含所有列印相關的規則,包括版面和顏色規則。特別是版式,樣式表中的規則大部分很可能拷貝自main.css. 也就是說,這造成了許多重複程式碼。
可以看出從佈局樣式中拆分出版式和顏色樣式的好處了:在列印樣式表中,我們不再需要那些重複的規則了。除此之外,可以使用另一個組織上的小技巧來改進網站的適用性,以及針對有問題的瀏覽器隱藏某些佈局樣式。
回顧下我們的樣式表,考慮以下程式碼:
Example Source Code
[www.downcodes.com] <link rel="stylesheet" type="text/css" href="type.css" />
<link rel="stylesheet" type="text/css" href="layout.css" />
<link rel="stylesheet" type="text/css" href="color.css" />
我們沒有聲明媒介類型,因此 Netscape 4.x 會讀取這三個檔案中的所有樣式。但是,Netscape瀏覽器能理解最基本的CSS, 我們可以利用這一點。透過將layout.css包含的所有樣式移到新的樣式表-適當的取名為screen.css, 我們可以進一步組織樣式。最後,將layout.css中的內容更新為引入screen.css, 這樣,NS4.x和它的同族瀏覽器們就再也聰明不起來了(因為它們不理解 @import指令)。 (譯註:作者這裡說的是將所有layout.css中的內容都移動到screen.css中,然後在layout.css中通過@import引入screen.css. 我覺得最好的做法應該是在layout.css中保留最基本的NS4.x也可以理解的佈局樣式,而將其它高級佈局樣式移動到screen.css中。
Example Source Code
[www.downcodes.com] @import 'screen.css';
還有一些改進的空間-應該聲明樣式表所針對的媒介,我們透過為@import聲明添加媒介類型來做到這一點:
Example Source Code
[www.downcodes.com] @import 'screen.css' screen;
問題是IE7及以下瀏覽器不理解這種語法從而忽略上面的樣式表,如果想給這些瀏覽器提供上面的樣式(這是經常期望的),可以很簡單地使用條件註釋來做到,這將在下文闡述。如果你擁有鷹一般利銳的眼睛,可能已經注意到在樣式表名稱的兩邊使用了單引號(')來替代雙引號(”),這個小技巧可以讓IE5/Mac忽略樣式表。IE5/Mac的CSS佈局能力 畢竟非常弱(特別是對浮動和定位的支持),對它們隱藏佈局規則是完全可接受的。
採用相同的技術,可以匯入print.css檔案(和你猜想的一樣,包含列印佈局的特定規則)。
Example Source Code
[www.downcodes.com] @import 'screen.css' screen;
@import 'print.css' print;
現在我們不僅擁有了組織得很漂亮的樣式表,我們還擁有了一套逐步增強網站設計的有效方法。
(圖示:多個樣式表間的相互關係以及將它們套用到文件的方法)
如何處理IE6?對很多人來說,Internet Explorer 6 是一個新的 Netscape 4 ——所有人都想讓它滾蛋。
我們略過對IE6問題的喋喋不休。 IE6的問題已經有了很好的文件總結,而且,老實說,解決起來並不是那麼困難。而且,IE7的採納相當快速(特別是在消費市場),同時IE8也已經在公測了。這意味著某一天,我們可以真正地對老態龍鐘的IE6說拜拜。
不管是有意還是無意,微軟在推出IE5時,為漸進增強提供了一個好工具:條件註解。這些巧妙的邏輯片段(在所有其它瀏覽器中都降級為HTML註釋(譯註:其它瀏覽器把IE的條件註釋理解為純粹的HTML註釋,不起任何作用))不僅允許某些標記代碼片段只作用於IE,也允許這些程式碼片段只作用於IE的特定版本。
作為有Web標準意識的開發者,我們始終應該先在大部分現有的兼容標準的瀏覽器上測試我們的設計,然後再為那些稍作細微修改就能回到正軌的瀏覽器提供補丁。每個人的工作流程都不同,但我發現最好用一套標準的文件來開始每個專案。我的基本套件包括以下文件:
Example Source Code
[www.downcodes.com] type.css
layout.css
screen.css
print.css
color.css
然後,根據專案的需求,新增針對特定瀏覽器的CSS檔案來包含那些「細微修改」。在現在的大部分專案中,這些檔案是ie7.css和ie6.css. 如果專案要求支援IE6之前的版本,我也會為其建立相應的檔案(例如ie5.5.css等等)。將這些文件放在適當的位置後,我開始將樣式規則加入到適當的樣式表中。
我的CSS測試都是從Mozilla Firefox開始,因為我的大部分CSS都是用Firefox的CSS編輯側欄來寫的。一旦在Firefox中完成了頁面設計,我立刻開啟其它瀏覽器來測試檢視。大部分錶現都很完美,因為他們遵守了Web標準。接著打開IE7測試。大部分情況下也沒有多少問題,偶爾需要觸發hasLayout或修正另一些佈局上的小錯誤。我沒有將這些修正補丁寫入到基本套件的樣式表文件中,而是添加到ie7.css中,並且在文檔的HEAD中通過條件註釋來引入:
Example Source Code
[www.downcodes.com] <!-- [if lte IE 7]>
<link rel="stylesheet" type="text/css" href="ie7.css" />
<[endif]-->
上面的條件註釋使得IE7及其以下版本(譯註:lte是less than or equal的縮寫)能辨識引入的樣式。因此,當用IE7瀏覽頁面時,將會取得這些補丁。但是如果用的是新版本的IE——可能已經修復這些問題,例如IE8拋棄了hasLayout從而不再有這些問題——將忽略這些樣式。另一方面,使用IE6可以獲得這些樣式。這是很好的,因為在IE7中的渲染錯誤往往也存在於IE6中。上文中已經提及,IE7及其以下版本無法理解帶有媒介類型的@import,透過這種方式引入screen.css對IE7及其以下版本是無效的。因此,也需要在ie7.css檔案的頂端加入不含媒介類型的@import語句來引入screen.css.
一旦為IE7添加完補丁,我會打開IE6, 看看是否需要隨手打些補丁。如果確實需要,我會為文件添加另一個條件註釋,引入ie6.css:
Example Source Code
[www.downcodes.com] <!-- [if lte IE 7]>
<link rel="stylesheet" type="text/css" href="ie7.css" />
<[endif]-->
<!-- [if lte IE 6]>
<link rel="stylesheet" type="text/css" href="ie6.css" />
<[endif]-->
接著,簡單地將IE6所需的補丁加入對應的樣式表中,這些樣式表將被IE7忽略,但會依舊往下影響到IE5.5等版本。
透過這種方式使用條件註釋,可以輕鬆的管理專案中的目標瀏覽器,並使得CSS修補程式檔案保持獨立自由。
其它考慮CSS漸進增強並不局限於如何將樣式表與文件關聯起來,還可以應用在如何編寫CSS上。
例如,考慮生成的內容(譯註:例如用:after偽類生成的內容)。並非所有瀏覽器都支持,但這是一個很好的方法:可以用來添加一些額外的設計或文字。對於頁面的可用性來說,這不是必須的,但這能提供一些視覺或其它方面上的增強。
拿簡單的聯絡表單來舉個例子:
(圖示:此範例中使用的HTML表單(程式碼將在下面給出))
當編寫上面的HTML程式碼時,很可能會自然地將冒號(:)寫在label元素裡。為什麼要這樣做?真的為label元素添加了內容嗎?並沒有。這樣做的目的是提供使用者額外的視覺線索,對label元素來說,這是多餘的,應當去除:
Example Source Code
[www.downcodes.com] <form id="contact-form" action="#" method="post">
<fieldset>
<legend>Contact Us</legend>
<p>Send us a message. All fields are required.</p>
<ol>
<li>
<label for="contact-name">Name</label>
<input type="text" id="contact-name" name="name" />
</li>
<li>
<label for="contact-email">Email</label>
<input type="text" id="contact-email" name="email" />
</li>
<li>
<label for="contact-message">Message</label>
<textarea id="contact-message" name="message" rows="4" »
cols="30"></textarea>
</li>
</ol>
<button type="submit">Send It</button>
</fieldset>
</form>
透過產生內容來將冒號加回文檔,這是更完美合適的方式:
Example Source Code
[www.downcodes.com] label:after {
content: ":";
}
用這種方式來編寫表單,給了我們靈活性:當需要從整個站點移除裝飾字元時,只要簡單的編輯CSS文件,而不需要去尋找每一個表單(雖然我們曾經知道在哪裡)。這個技巧也能夠很好降級,因為沒有冒號時,表單並不會被渲染得無法使用——這是漸進增強的一個絕佳例子。
也許你已經發現,使用高級CSS選擇符(譯註:selector, 也有譯為選擇器的,但我覺得選擇符更能體現本意,例如operator翻譯成運算符,而不是運算器),可以將特定的樣式附加到更多高級瀏覽器上,這有助於逐步增強網站。一個很好的例子是屬性選擇符,在IE6及其同一時代以及更早的瀏覽器中不能被理解(因此也就被忽略了)。 Egor Kloos很漂亮地運用了這個概念,在CSS禪意花園(CSS Zen Garden)上提交了名為」雙雙」(Gemination)的作品:
(圖示:Egor Kloos的CSS禪意花園作品(「雙雙」)在標準瀏覽器和IE6中的呈現對比)
他是怎麼做到的?下面是略加修改的範例程式碼:
Example Source Code
[www.downcodes.com] /* <= IE 6 */
body {
margin: 0;
text-align: center;
background: #600 none;
}
/* IE 7, Mozilla, Safari, Opera */
body[id=css-zen-garden] {
margin: 100px 0 0;
padding: 0;
text-align: center;
background: transparent url(squidback.gif);
}
差異很明顯,並且非常漂亮地說明了漸進增強如何應用在CSS中。
類似地,Andy Clarke的站點上也有些關於IE6的小玩意。透過使用IE的濾鏡以及加入一些條件註釋,Andy成功地去除了網站上的所有顏色,並提供了一些可替換的圖片,這構成了一個真實的「低保真」體驗。
(圖示:Andy Clark的網站在標準瀏覽器和IE6上的比較)
上面的圖片灰色技術是這樣的:在條件註釋添加的針對IE6(及其以下)的樣式表中,添加以下聲明:
Example Source Code
[www.downcodes.com] /* =img for Internet Explorer < 6 */
img {
filter: gray;
}
儘管上面這兩個例子可能包含了過多日常工作中的運用不到的技巧,但它們非常棒地用事實說明了一個概念:如何在實踐中應用CSS漸進增強。
總結正如我們所討論的,有許多方式可以將CSS漸進增強應用到網站上。最簡單也可能是最好的一種方式是,組織好樣式表並認真考慮如何將樣式錶鍊入文件。一旦了解條件註釋,處理IE的特定問題也將是輕而易舉的事。如果對如何選用選擇符以及使用它們的場景了然於胸,還能在CSS中完成更多小粒度的調整。
用這些知識武裝起來,在通往漸進增強專家的路上你將平坦前進。