樹狀選單加入樹狀線條的設計
- 說明:設計具有樹狀線條的資料夾選單或樹狀選單 (folder menu or tree menu)。本篇的討論僅適用一層子選單,更多層子選單的設計方式,以後再討論。
- 適合:有設計網頁及撰寫 css 語法經驗者。
- 難度:

- 更新:
以下將會討論如何巧妙運用 css 基本特性 (property) 來完成這個實例。
- 先了解
xhtml這部分內容的安排。 -
<div class="TreeMenu"> <div class="section"> <h1>古文今讀</h1> <ul> <li><a href="#">上古神話</a></li> <li><a href="#">詩經</a></li> <li><a href="#">楚辭</a></li> <li><a href="#">諸子散文</a></li> <li><a href="#">漢賦選輯</a></li> <li><a href="#">樂府</a></li> <li><a href="#">駢文</a></li> <li><a href="#">唐詩</a></li> <li><a href="#">宋詞</a></li> <li><a href="#">元曲</a></li> <li><a href="#">章回小說</a></li> </ul> </div> <!--.section--> <div class="section"> <h1>現代文藝</h1> <ul> <li><a href="#">小說</a></li> <li><a href="#">散文</a></li> <li><a href="#">性靈小品</a></li> <li><a href="#">新詩</a></li> <li><a href="#">翻譯小說</a></li> </ul> </div> <!--.section--> </div> <!--.TreeMenu-->
本篇範例的完整 css 設計內容。
散佈、展示請參閱 Creative Commons 授權條文,禁止重混,引述請增加原文連結。
思考 - css 設計的構思與佈局
我們儘量以探討方式介紹,引導如何構思及擴展 css 設計,希望能激發更多設計想法為主,避免陷入步驟式或教條式的悲慘學習模式。
開始:定義一些基本的 css 設計
最外圍的
.TreeMenu指定寬度 (width) 、背景顏色 (background)、邊線 (border) , 而h1指定字體大小 (font) ,a去掉底線,ul,h1去除周圍距離 (padding,margin) 等等。cssline-height(行高) 是設計的主要概念視覺性的瀏覽器通常會預先賦予每行「大於一個字」的行高 (
line-height) ,為了避免不同瀏覽器間產生的差異,以及後面設計 css 時有所依據,先將整個選單內line-height定義為「字高度」的倍數,例中為 1.1 倍,看起來行距應該會較原來更緊一點。由於line-height特性 (property) 有繼承性 (inheritance) ,所以只需要定義一次在.TreeMenu或.section就可以;這裡也順便為分類標題h1加背景色修飾一下。css定義 (紅字)我們只以倍數定義行高,也沒有指定字體的尺寸 (
font-size),如此是為了使全部的設計,單純地以字高 (em) 的倍數來計算,不用去管字體到底幾個像素 (pixel) 大,或者一行有多少像素高。想指定font-size當然可以,不過行高最好還是以倍數的方式指定,設計時才不至於太難計算;這只是建議囉,全部都用像素為單位也沒問題,計算清楚,小腦袋瓜別爆掉就好。產生樹狀的垂直線條
在
ul左側加上線條,當做樹狀結構的垂直線,並且左邊空出一點距離,讓子選項內容li看起來向內縮排。這個距離應該是要對應分類標題h1來設計,我們指定了向內縮半個字 (0.5em),所以線看起來像是由標題第一個字中間向下延伸;標題最前面如果變成小圖示 (icons) ,那就以圖示寬度的一半去定義縮排距離也可以。這裡應該以margin來指定內縮距離,因為我們必須讓垂直線緊貼著li。線條寬度沒有使用em定義,是因為1px寬幾乎沒什麼影響,但是如果需要設計較粗的線,單位最好一致。ul增加css定義 (紅字)我們沒有特別指定線條
border的顏色,將會與該區域字的顏色相同,如果想另外定義顏色,可以像這樣,線條要改成實線也可以,
dotted → solid,當然其它形式的線條也可有更多變化。產生樹狀的水平連接線條
在子選項
li下方加上線條,當做樹狀結構子選項的橫連接線。這裡也讓li的內容a向內縮排,不過,不同於前面,我們必須保持每個li下方的線與左側ul的線緊緊相接,所以在li指定padding,僅讓內容a向內縮,但li本身沒有縮排。li的css定義border也沒有特別指定顏色,這樣可以對應前面ul的border顏色,如果想另外定義顏色,方法同前。css
position:relative;讓a向下位移 (offset)css
position:relative;主要的特點就是,元素可以由本身的 Box 位移,並且保留其它元素原來的排版。利用這個特點,只要讓a向下位移半行,而li會維持原來的位置及下方的橫線,a的中間就會剛好壓在li的線上。前面已經指定line-height:1.1;(1.1倍的字高),所以半行就是0.55em,太棒了,只有a向下移,所有a以外的東西都不會動。a增加css定義 (紅字)由於水平線條只有
1px厚度,對整個位置並無影響,可以不需考量;但是如果指定了較粗的線條,就需要顧慮到線條的厚度會佔掉空間,向下位移的距離應該多加半個線的厚度,這也是為什麼前面有提醒要注意單位一致的原因,如果線的單位是px,而行高是em,那還真有點難算。背景顏色蓋掉重疊的線
明顯地,現在面臨兩個問題:一、字的背面不應該有線。二、因為
a的向下位移,造成與下一個分類重疊。第二個問題稍後再討論。第一個問題比較容易處理,我們為a指定背景色就可以蓋住li的橫線了,由於a本身為行內層級元素 (inline-level elements) ,所以背景色只會在有字的區域呈現。如果a不想有背景顏色,只要指定與.TreeMenu相同的背景色,a看起來就像沒有背景色的樣子。a增加css定義 (紅字)如果想讓字之後的整條線都蓋掉,只要把
a轉換成區塊層級 (block-level) 呈現即可。a增加css定義 (紅字)此時會看到子選項內容
a之間有1px的間隔,這是因為a的實際高度本來就比li少1px高 (li比a多了線條的高度)。增加距離避免重疊,就算完成了。
只要在分類間加一點距離,重疊的問題就解決了,為
.section下方加上padding應是較恰當的方式。為了分類裡面的上下距離看起來一樣 ([上古神話]上方與[章回小說]下方) ,我們指定了padding-bottom:1.1em;,與行高相等的距離。.section增加css定義 (紅字)換成在
ul下方增加距離也可以,不過,只能以margin來定義,因為padding會使左側的線跟著向下延長,就不會與最後一個li的橫線緊接了。目前應該已經算是完成囉,只剩下修飾更好而已。
hasLayout處理 ie bugsie 7 或 ie 6 ,在
ul或a可能會發生高度失準或背景圖片移位的問題,解決這類的 bugs 常用的方式是 hasLayout property 。由於目前在 ie 8 都還正常,為了清楚區隔,我們最好運用 css hacks 技巧。css定義a還是有高度或不正常間隙問題在子選項前加小圖示,並且做最後修飾
以小圖示作為
a的背景,並且指定左邊padding距離,讓a的內容文字向內縮排,才不會與小圖示重疊。例中的小球圖示 (ic008.png) 寬度10px,我們指定它的位置在a的最左側並且上下居中,這樣會讓小球剛好緊接在li的線後,然後左側padding距離為15px,讓字不要與圖看起來太緊鄰。另外,把a的背景顏色指定成與.TreeMenu相同。我們也在
a及標題h1上下加了一點padding距離,讓字看起來不會與邊緣太緊鄰。不過,a上下各增加了0.25em,表示整行的高度也增加了,所以,向下位移的top定義也需要對等增加0.25em的距離 (0.55 + 0.25 = 0.8em) ;而.section下方的padding距離也應該增加為1.6em(1.1em + 0.25em + 0.25em) 。css設計前面提到由於
li的下方線條使a之間會有1px間距,只需要在a或li指定margin-bottom:-1px;(綠字),就會使li之間有1px重疊,a之間就沒有間距了,不過, ie 7, ie 6 最後一個li的線會看不見,修正方式也加在 hacks 裡了 (綠字) ,有興趣可以自行試試。