寫這篇啰嗦的文章,緣由來自於Jorux Notebook的《什麼是Semantics?》文章。
實際上,從《網站重構》一書開始在國內流行之後,Zeldman提出的語義化標記就已經在一定程度上流傳開來。在拋棄table布局頁面之後大家突然發現,原來這還不夠,隨意地使用<p>或者<div>來進行布局實際上和table布局一樣的糟糕。
Jorux的例子(如下):
我是老大 | 我是不好意思說 | 老三 | 老四在這裡 | 老幺
Jorux指出,在這種極為普遍的導航樣式中(通常是用於網站底部的信息導航,100個網站裡有90個采用這樣的模式),我們應該使用無序列表,而不是下面這種:
1: <p>
2: <a href=”home.Html”>首頁</a> |
3: <a href=”about.Html”>關於</a> |
4: <a href=”blog.Html”>博客</a> |
5: <a href=”message.Html”>留言</a> |
6: <a href=”album.Html”>相冊</a>
7: </p>
甚至是使用了<ul>,但是依然將修飾線條作為內容元素的寫法也是五十步笑百步:
1: <ul>
2: <li><a href=”home.Html”>首頁</a></li>
3: <li>|</li>
4: <li><a href=”about.Html”>關於</a></li>
5: <li>|</li>
6: <li><a href=”blog.Html”>博客</a></li>
7: <li>|</li>
8: <li><a href=”message.Html”>留言</a></li>
9: <li>|</li>
10: <li><a href=”album.Html”>相冊</a></li>
11: </ul>
遺憾的是,內容與樣式分離web標准化建設的推進道路總是充滿了各種各樣的阻礙。即使是新浪和淘寶在它們的頁面底部也存在著上述的情況。
先來看新浪的截圖:
代碼(簡略了內容):
1: <div style="padding-bottom:6px;">
2: <a href="">新浪簡介</a> ┊
3: <a href="">About Sina</a> ┊
4: <a href="">廣告服務</a> ┊
5: <a href="">聯系我們</a> ┊
6: <a href="">誠聘英才</a>
7: </div>
為什麼要這麼做,有過網頁制作經驗的朋友大概會了解。網站底部的導航通常都是以比較簡單的文本形式出現,居中,再附加一些修飾——大部分都是“|”和“·”或者“—”。Html部分采用新浪的做法,節省了編寫CSS的時間,最重要的是讓一切水平居中顯示將是非常簡單的事情。只需要將<div>的text-align設置為center就萬事大吉。
這裡需要討論的是,到底使用什麼標記才算是語義化?
我們沒有教科書,任何一本某某權威指南不會寫著:你應該使用<ul>和<li>,而不是<div>和<p>來制作導航菜單。也就是說,我認為如果考慮到實際項目的操作,使用前者或後者都不是一個嚴重到會出現違背XHtml准則的問題。
我們來看淘寶的底部:
在我看到,如果按照zeldman的思路,應該這樣去寫:
1: <dl>
2: <dt>全球阿裡巴巴 - 阿裡巴巴網絡</dt>
3: <dd>
4: <ul>
5: <li>中國站</li>
6: <li>國際站</li>
7: ......
8: </ul>
9: </dd>
10: </dl>
但實際上,淘寶的代碼是這樣:
1: <div class="ali-group" style="width:680px;margin:5px auto;">
2: 全球阿裡巴巴 - 阿裡巴巴網絡:
3: <a href="">中國站</a>
4: <a href="">國際站</a>
5: <a href="">日文站</a> |
6: <a href="">淘寶站</a> |
7: <a href="">支付寶</a> |
8: ......
9: </div>
為什麼一個如此提倡標准化的UED小組所編寫的淘寶代碼中也有和Jorux說法相違背,不嚴格按照語義化標記來操作呢?
因為,這樣的水平居中和添加“|”不會那麼煩人。
不要小看這個“|”,加入這麼一個小小的修飾線條,看似簡單,實際上還是比較頭痛的。
首先我們知道,這個豎線是分割線,是把一個個鏈接從視覺上分開的一種手段,有多種方式去實現這一個效果:
1、直接插入“|”實體,但這和用空的table來撐開空白一樣,是不符合內容和樣式分離准則。
2、使用border-right來給每一個鏈接加上一個1px寬的邊框。缺點是這個邊框線條的高度定義起來比較討厭,作為行內元素的a,無法應用到上下內邊距來控制高度,勉強使用行高line-height只會讓你在實際應用中漏洞百出。
3、使用background來給每一個鏈接加上一個豎線的圖片背景,這種方式在視覺效果上應用靈活,但缺點是會多制作一張圖片(盡管你可以CSS Sprites或者你認為一條豎線的圖片大小可以忽略不計),同樣高度無法定義。
4、使用:after這樣的偽類元素,如a:after { content: "|"; }。可以再添加font-size來稍稍控制高度。盡管這樣的一種做法被一些css玩家所推崇,畢竟了解的人少,使它看上去比較的高深和復雜。實際上它的缺點也最多。首先,:after在版本8以下的IE中通通免談,這就意味著大部分浏覽者無法看到這樣的效果。其次,看上去這一條“|”是由CSS來控制的樣式,實際上它在Html中實際生成了內容,本質上和直接在<a>之後插入一個“|”沒有區別。
綜上所述,我們理應拋棄第一種做法,采用2、3、4中的一種來顯示這個分割線效果。然而接踵而至的問題是,不管你用了哪種方法,你都要考慮如何去除最後一個“|”分割線。讓導航看上是這樣:
我是老大 | 我是不好意思說 | 老三 | 老四在這裡 | 老幺
而不是這樣:
我是老大 | 我是不好意思說 | 老三 | 老四在這裡 | 老幺 |
常用的做法是給div中的最後一個a,或者ul中的最後一個li(或者都是第一個a和li,這取決與你CSS中的左右位置)添加一個id或者class,例如:
1: <ul id="menu">2: ......3: <li><a href="#">王老五</a></li>4: <li class="last"><a href="#">老幺</a></li>5: </ul>
然後在CSS添加對這個.last的單獨定義,去除它的邊框或者背景或者:after生成的content內容。
如此的繁瑣,是不是已經開始頭大了?
從分割線的問題,我們往下討論導航的水平居中問題。
淘寶的另一個底部導航采用了不讓人頭大的選擇:
在這個例子中,Html如下:
1: <ul class="foot-nav" style="width:690px;_width:695px;">
2: <li><a href="">關於淘寶</a></li>
3: <li><a href="">廣告服務</a></li>
4: <li><a href="">合作伙伴</a></li>
5: <li><a href="">幫助中心</a></li>
6: <li><a href="">誠征英才</a></li>
7: <li><a href="">聯系我們</a></li>
8: <li><a href="">網站地圖</a></li>
9: <li><a href="">熱門品牌</a></li>
10: </ul>
這裡的采用了標准的寫法,沒有分割線,沒有額外的id或class,沒有上面討論的煩人的各種問題。
然而這種寫法意味著,如果將li的display設置block,text-align:center無法輕松的將這個導航水平放置在頁面的正中,除非你給ul定義了一個寬度,在上面的代碼中淘寶也的確是這樣去做的。
如果,導航菜單中的項目數量不能夠確定,整體的寬度勢必也要成為變量——一個未知寬度。不斷地去修改這個width,以確保margin: 0 auto;可以讓這個導航水平居中無疑將讓你的工作變得瑣碎和困難。
最簡單的方法,就是讓每一個li元素不要以block的形式float:left,以inline的方式讓它們一字排開,給ul一個text-align:center就可以搞定這一切。
我做了這樣一個例子,demo1。為了圖省事,我沒有做圖,采用背景圖片的方式顯示分割線,而是使用了:after生成content的方法。
在CSS中的最後,我添加這樣兩行:
1: #menu li:before { content: "|"; padding-right: 10px; }
2: #menu li:first-child:before { content: ""; }
這樣,在不支持:after的浏覽器中,導航以最質樸的方式展現,在IE8和FF這樣的浏覽器中,分割線將顯示出來,最後一個li的分割線將被刪除。
上面的方法,在大部分時間還是比較好用的,但如果需要給導航菜單添加更多的效果控制,例如給每一個li添加一個按鈕似的背景,我們就必須讓li成為塊級元素。這個時候,text-align:center就無效了。
好在Stu Nicholls給出了一個解決方案——Centering Float Left Menus。
我做了另一個例子,demo2。
在這樣的基礎之上,無論你或刪或增導航菜單的項目數量,無論你是想給它添加簡單背景色,還是添加復雜的圓角框,你都可以從容應對了。