FW:UI Components Based on Web Standards - Menu (2)

本文的第一篇中,我們瞭解了一個“完美”的菜單應該具備的可用性和易用性特徵,並且創建了基本的XHTML和CSS代碼。接下來我們將深入到與菜單相關的一些高級特性的實現技術上,首先是——

指示當前活動菜單項

  當用戶點擊某菜單項進入網站相應的欄目,我們通常會希望這個菜單項表現出與其它菜單項不同的視覺特徵,使用戶明確地瞭解自己所處的“地點”而不至於在站點中迷路。我一直想不好應該是給這個菜單項一個什麼樣的名字,暫且稱爲“當前活動菜單項(Currently Active Menu Item)”吧,如果你有什麼好想法請一定在右邊留言告訴我,謝謝^_^。

  當前活動菜單項對創建良好的用戶體驗具有非常重要的作用,一個負責任的UI設計師是絕對不會忽視它的。實現的方法至少有兩種:“直接指示”與“自上而下的指示”。

  “直接指示”的方法即直接給當前活動菜單項相對應的li元素一個適當的class屬性,再在CSS中爲這個class重載一般菜單項的視覺屬性,使它表現出“獨特”的視覺特徵。說得挺懸忽,做起來很簡單,我們還是用apache.org的菜單爲例,並假設已經點擊“DB”項進入了相應的欄目:

<li class="active">
  <a href="//db.apache.org/" title="Database access">DB</a>
</li>

  XHTML只要做這麼一點小小的改進就可以了,CSS的改動也不大,只要增加這麼一段:

menu li.active a{
	background-color:#E8F3FF;
	border:1px solid #05F;
}

  查看效果(例9)

  “自上而下的指示”並不直接在某個菜單項上指明它特殊的身份,而是先給每個菜單項命名,再在菜單項的“上級(比如body元素)”處指明哪個菜單項被選中了(頗有些類似皇帝翻牌選擇當晚“臨幸”的妃子^_^)。

  我們拿上篇文章中使用”絕對定位”的那個菜單爲例,假設“軟件”項被選中:

<body class="chlSoftware">
<menu>
  <li id="miMovie"><a href="/movie/" title="DVDRip">電影</a></li>
  <li id="miMusic"><a href="/music/" title="mp3">音樂</a></li>
  <li id="miSoftware"><a href="/dl/" title="共享">軟件</a></li>
</menu>
</body>

  body元素的class設置了當前頁面所處的頻道(欄目),也就是此處chl前綴的意思——Channel。根據這個class就可以設置“臨幸”的規矩了……-_-|||

body.chlMovie li#miMovie a,
body.chlMusic li#Music a,
body.chlSoftware li#miSoftware a{
	background-color:#E8F3FF;
	border:1px solid #05F;
}

  查看效果(例10)

  可能的情況下我建議使用第二種方式,理由如下:

  1. 寫後臺程序的時候比較方便,只需判斷當前所處的欄目給body設置class即可(怎麼判斷?那可不是我的事兒....);
  2. 擴展性好,不僅可用於指示當前活動菜單項,也可以給頁面上的其他元素提供當前狀態的信息。比如你想讓每個欄目有不一樣的主色調,知道怎麼辦了吧^_^;
  3. 當皇帝比較爽……

帶圖標的菜單項

  做到現在我們的菜單還都是光禿禿的,某些朋友可能已經對Web標準技術在視覺效果上能走多遠產生懷疑。下面我們就把圖片引入到菜單的製作中,先從最簡單的講起——給菜單項加個圖標“”。我們以例9的菜單爲基礎,對a元素的樣式做些小修改:

menu a{
	/*定義a爲塊級元素,方便用盒模型屬性定義外觀*/
	display:block;
	/*定義尺寸*/
	width:100%;
	height:20px;
	/*盒模型風格*/
	background-color:#F6F6F6;
	border:1px solid #DDD;
	/*文字樣式*/
	font:11px arial;
	text-decoration:none;
	/*垂直居中*/
	line-height:20px;
	/*水平居中*/
	text-align:center;
	/*文字縮進*/
	text-indent:20px;
	/*圖標*/
	background:#F6F6F6 url(i/arrow.gif) 5% 50% no-repeat;
}

  查看效果(例11)

  這裏有三點需要說明一下:

  1. 去除文字水平居中後菜單項的文字都緊貼左側排列,我們需要給圖標留出一定的空間。常用的方法(也是最容易想到的方法),就是使用padding-left。但這樣會面臨IE的盒模型Bug,雖然解決起來也很方便,但總不如用text-indent來得自然,更何況這樣沒有任何的Bug需要處理。
  2. 爲什麼不把圖標直接用img標籤插入到XHTML文檔中?因爲這些圖標僅僅是裝飾作用,它們並不是這個網頁真正的“內容”,所以它們出現在XHTML代碼中是不合適的。另外用背景圖的方式處理也更方便更節約網絡流量。反過來說,如果這個圖標是一個logo,比如Apache HTTP Server那支著名的羽毛,建議你把它加入到XHTML代碼中(別忘了alt屬性),因爲它是這個網頁真正想要表達的“內容”。
  3. 關於如何正確設置背景圖,我這裏就不多說了,請參考小雨的《CSS2.0中文手冊》中background部分。需要注意的是Opera對背景圖定位有一些怪脾氣,請參考我的另一篇文章

背景圖翻轉技術

  這又是一個很實用的技術。當我們對簡單的盒模型風格不滿意的時候,自然會想到使用背景圖來創建更有個性的菜單項,實現的方法也很簡單,我們還是在例9的基礎上做修改。

  先看看兩張背景圖的效果:

  普通狀態(bk01.gif):
   鼠標覆蓋(bk02.gif):

  CSS的改動也不大,我就揀重要的講(開始偷懶了……^_^):

menu a:link,menu a:visited{
	background:transparent url(i/bk01.gif) 0 0 no-repeat;
}
menu a:hover,menu a:active{
	background:transparent url(i/bk02.gif) 0 0 no-repeat;
}

  查看效果(例12)

  Yes,就這麼簡單,只要給a元素的四種狀態設置相應的背景圖就可以了。這種辦法足以應付各種古里古怪的菜單,而且不光可以用在菜單上,任何需要模樣古怪的鏈接的地方都可以用上它。不過這還不是最完美的方法,還有更棒的。

  我們先把兩張背景圖合成一張(bk03.gif):

  

  再修改CSS(這裏只列出修改了的部分):

menu a{
	...
	background:transparent url(i/bk03.gif) 0 0 no-repeat;
}
menu a:link,menu a:visited{
	background:transparent url(i/bk01.gif) 0 0 no-repeat;
}
menu a:hover,menu a:active{
	background:transparent url(i/bk02.gif) 0 0 no-repeat;
	background-position:0 -21px;
}

  查看效果(例13)

  看明白了嗎?事實上只用了一張圖,當鼠標覆蓋事件產生後把圖的位置向上移動了一段距離,剛好露出下半張圖的紅色背景部分。這樣做有什麼好處嗎?

  1. 方便管理背景圖。一個大型網站很可能需要使用幾十上百張背景圖,把相關的背景圖合在一起可以極大地方便管理和維護。
  2. 與桌面軟件皮膚的製作方式更接近。制定中的CSS3已經引入桌面軟件皮膚製作中最基本的“九宮格”技術,由此網頁UI設計已經明顯地呈現出向桌面軟件UI設計靠攏的趨勢。
  3. 節約網絡流量。以上面這個例子爲例,小的背景圖0.47K,合併後的背景圖0.94K。兩張小圖的體積之和也是0.94K,這有什麼節約的?我們知道數據是以“IP包”的形式在網絡上傳輸。大部分的IP包都在1K左右,比如我的網站服務器收發的每個IP包大小爲1024字節。每張圖至少需要一個IP包傳輸,這麼一來兩張小圖就佔用了2K的流量,而使用一張大圖只需要1K的流量。對於中小型網站這點流量的出入並不算什麼,但對於日訪問量上千萬的網站來說,“能省則省”並不僅僅是網絡流量的問題,而是實實在在的經濟問題,不可不重視。

文字替換技術

  某些時候我們對菜單項的視覺效果會要求得更多,比如沒有文字純粹是一張圖,或者使用一種極少見的字體。也許你會說:我知道,用背景圖片。沒錯,用上面的“背景圖翻轉技術”你可以實現它。但是a元素中的文字呢?不能讓它繼續出現在視野中了,這時就需要用到“文字替換技術”。

  爲了方便說明,拿我最喜歡的“百事”和“樂事”做一個簡單的菜單:

<menu>
<li id="miLays">
  <a href="http://www.lays.com/" title="樂事薯片">Lay's</a>
</li>
<li id="miPepsi">
  <a href="http://www.pepsi.com/" title="百事可樂">Pepsi</a>
</li>
</menu>

  然後使用“背景圖翻轉技術”把下面這張圖作爲背景。

  查看效果(例14)。具體的實現代碼請自己查看源文件,用到的技術上面都有提到。

  接下來就是重頭戲了:把那兩行帶下劃線的難看文字去掉。讓我們先想想有哪些辦法可以把元素從頁面上隱去:

  1. display:none。好像太厲害了一點,不光把文字隱藏起來,壓根就找不到可以點的鏈接了……-_-|||
  2. visibility:hidden。嗯,文字沒了,鏈接還在……可惜背景圖也沒了,槍斃!

  好像滅什麼辦法了?再次向大家隆重介紹text-indent。看看它是怎麼做的(在例14的基礎上修改):

menu a{
	...
	text-indent:-9999px;
	text-decoration:none;
}

  查看效果(例15)

  OMG,真佩服第一個想出這法子來的人。讓文字負縮進9999px,也就是往左移動9999像素,別告訴我你的顯示器有這麼大的分辨率^_^。後面那個text-decoration:none是爲了防止Firefox出現下劃線(不信你可以拿掉它試試)。

  到目前爲止IE6、Firefox和Opera都表現完美,可是還沒完,你會在IE5下發現根本找不到可點的地方……原來IE5把鏈接的可點區域和文字一起往左挪到了-9999px處,真是麻煩啊-__-|||。解決的方法倒也不難:用絕對定位(這方法是俺自己找出來的,如有雷同純屬英雄所見略同^_^)。

menu li{
	position:relative;
	...
}
menu a{
	position:absolute;
	top:0;
	left:0;
	...
}

  查看效果(例16)

  這下大家都滿意了,這篇文章也到尾聲了……

小結

  這篇文章裏提到的大部分技術和思想不僅僅可以使用在菜單上,比如“背景圖翻轉技術”的使用範圍就相當廣,如果你剛開始學習Web標準,不妨親手製作一個菜單,熟悉一下這些常用技術。如果你已經有一些Web標準實踐經驗,請關注這篇文章中提到的各種思想,相信有助於你理解Web標準的目標與責任。如果你是經驗豐富的高手,請一定指出這篇文章中的錯誤和不足,我也是邊摸索邊總結,估計缺陷不會少。

  最後謝謝關注這篇文章的朋友,空的時候我還會接着寫其他《基於Web標準的UI組件》。

  注:說了這麼多還不能滿意你的菜單要求?那你的菜單還真是有點bt,也許我之前翻譯的一篇文章能幫上忙(這篇文章中還提到另一種文字替換技術,雖然我覺得不怎麼好)。

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