ISSN: 1534-0295. 20 October 2003 – Issue No. 160
在CSS中,一個(gè)經(jīng)常被人們討論的先進(jìn)之處即背景圖像的可層疊性,并允許他們在彼此之上進(jìn)行滑動(dòng),以創(chuàng )造一些特殊的效果。根據CSS2.0當前的規定,每一個(gè)背景圖像都需要各自的HTML元素。在許多情況下,典型的標記已經(jīng)為一般的接口組件提供了多種元素以供我們使用。
標簽導航欄就是其中的一個(gè)例子。過(guò)去,我們頻繁的使用這些標簽,并已成為了一種非常流行的站點(diǎn)導航方式?,F今,在CSS已被廣泛支持的前景下,我們可以為我們站點(diǎn)制作出更高質(zhì)量和更好外觀(guān)的標簽導航欄來(lái)。你也許知道CSS可以用來(lái)“馴服”無(wú)序的列表,或許你還曾經(jīng)看到過(guò)這種樣式的標簽列表:

如果我們想用和以上類(lèi)似的標記,將導航標簽變成這種樣式,該怎么辦呢?

經(jīng)過(guò)簡(jiǎn)單的設計,我們是可以做到的。
我見(jiàn)過(guò)的許多基于CSS的導航標簽大都具有一類(lèi)的特征:矩形的色塊,也許僅僅是一個(gè)輪廓,對于當前選中的標簽則沒(méi)有邊框,標簽在鼠標指針游至其上時(shí)改變顏色。這難道就是CSS所能給我們的全部嗎?一連串的小盒子和單調的色彩嗎?
在CSS被廣泛采用之前,我們已經(jīng)看到許多標簽導航設計中的創(chuàng )新之處。獨創(chuàng )的外形,熟練的色彩混合,以及對真實(shí)世界中許多物理接口的模仿。但是這些設計往往過(guò)分依賴(lài)于經(jīng)過(guò)復雜制作、帶有文本的圖像,或被包裝成若干嵌套的表格。修改文本或改變標簽的順序則需要一個(gè)復雜的過(guò)程。文本的伸縮更是不可能的,或給頁(yè)面的布局極大的影響。
純文本的導航欄比起文本即圖像的導航欄更具有持續使用性和更快的載入速度。同樣,我們甚至可以為每一個(gè)圖像加上alt屬性,對于弱視者,純文本更可以自由的改變大小。不足為奇的是,基于純文本的導航欄,并加以CSS樣式,又重新回到Web設計中來(lái)。但是,大多數基于CSS的導航欄設計,至今為止仍然是毫無(wú)意義的。一種最近被采用的技術(shù)(例如CSS)可以讓我們做的更好,同樣不失先前提到的那些表格和圖片標簽的效果。
美觀(guān)的工藝,真正靈活的接口組件,并根據文本自適應大小,我們可用兩個(gè)獨立的背景圖像來(lái)創(chuàng )造它。一個(gè)在左邊,一個(gè)在右邊。把這兩幅圖像想象成兩扇可滑動(dòng)的門(mén),它們滑到一起并交迭,占據一個(gè)較窄的空間;或者相互滑開(kāi),占據一個(gè)較寬的空間,就像下圖所顯示的那樣:

在這個(gè)模型中,一個(gè)圖像掩蓋住另一個(gè)圖片的一部分。假設我們放置一些獨特的內容在每個(gè)圖像的周?chē)?,例如標簽的圓角,我們并不希望上面一副圖像完全的遮蔽住下面一副。為了防止這種情況的發(fā)生,我們可以將上面一副圖像(此例中的左邊那幅)控制的盡可能的窄。但仍然要保證一定的寬度來(lái)顯現標簽一側的獨特性。如果外部是圓角,我們就應該控制上面一副圖像和它的弧線(xiàn)部分具有一樣的寬度。

如果目標在大小上增長(cháng),并超過(guò)了以上所顯示的寬度,歸咎于文本大小及字體的改變,圖像會(huì )被拉開(kāi),產(chǎn)生不美觀(guān)的間隙。我們需要判斷的是,預測這種可擴展的量將有多大。如果在瀏覽器中改變字體的大小,目標又會(huì )如果增長(cháng)呢?實(shí)際來(lái)說(shuō),我們至少應該估算到字體大小增長(cháng)至300%的情況。背景圖像也得適應這種增長(cháng)。對于以上的例子,我們將下面(即右邊)的圖像設為400*150像素,上面的設為9*150像素。
在頭腦中,始終要有這樣的認識:背景圖像只是顯示一個(gè)可供內容填充的有效空間(即內容區域和padding,稱(chēng)為doorway)。這兩幅圖像始終和各自外部的邊角相錨定。背景圖像的可見(jiàn)部分和在一起即形成了一個(gè)具有這種標簽形狀的空間(doorway):

如果標簽被撐大,圖像即滑開(kāi),doorway變寬,圖像的也將被顯露的更多:

此例中,我在photoshop中制作兩個(gè)平滑,細的3D標簽圖像,如文章開(kāi)頭所顯示的那樣。對于其一,內部明亮,邊框暗淡些,用來(lái)表現當前選中的標簽。將這種技巧模型應用于左右兩幅圖像中,我們需要擴大標簽圖像覆蓋的區域,將它裁剪成兩部分:

同樣的方式將應用到被稱(chēng)為“當前”的標簽中。一旦我們完成了這四幅圖像(1, 2, 3, 4),我們就可以開(kāi)始用標記和CSS來(lái)制作我們的標簽了。
當你在研究用CSS來(lái)創(chuàng )造水平列表時(shí),會(huì )發(fā)現至少有兩種方法將列表項安排在同一行里。兩種方法各有千秋,但都需要CSS來(lái)解決布局所帶來(lái)的混亂。一種方法使用inline box,另一種則用floats。
方法一,可能是比較普遍的一種,是將列表項都inline顯示。inline方法的魅力在于它的簡(jiǎn)易性。但是,對于我們即將談到的滑動(dòng)門(mén)技術(shù)來(lái)說(shuō),inline方法在特定的瀏覽器上存在一些解釋上問(wèn)題。方法二,是我們將要關(guān)注的,即用floats將列表項安排在同一行里。令人沮喪的是,floats表面上矛盾的行為正巧回避了自然的邏輯。盡管如此,對于解決多重浮動(dòng)元素的基本認識,以及可靠浮動(dòng)的意義,仍是值得討論的。
我們將用另一種浮動(dòng)元素來(lái)解決浮動(dòng)元素的排列問(wèn)題。這樣,父類(lèi)元素將子類(lèi)元素完全包括起來(lái)。于是,我們就可以為標簽加上背景色彩和背景圖像。非常重要的一點(diǎn)必須記住,緊跟在標簽后的文本元素用CSS中的clear功能來(lái)清除浮動(dòng)對象。這樣避免了浮動(dòng)標簽影響頁(yè)面上其它元素的位置。
我們從以下的標記開(kāi)始:
<div id="header"><ul><li><a href="#">Home</a></li><li id="current"><a href="#">News</a></li><li><a href="#">Products</a></li><li><a href="#">About</a></li><li><a href="#">Contact</a></li></ul></div>
現實(shí)中,#header div可能同樣包含logo和搜索框。對于我們的例子,我們要縮短每一個(gè)錨鏈中超鏈接的值。顯然,這些值應該正確的包含文件或者目錄的位置。
我們從定位#header容器開(kāi)始設計列表。這樣確保了這個(gè)容器確確實(shí)實(shí)的充當了容器的作用,以包容它內部浮動(dòng)的列表項。既然元素是浮動(dòng)的,我們同樣需要聲明它的寬度為100%。加入臨時(shí)的黃色背景以確保父類(lèi)容器完全填滿(mǎn)標簽后面的整個(gè)區域。同樣,設定默認的文本屬性,確保樣式的統一:
#header {float:left;width:100%;background:yellow;font-size:93%;line-height:normal;}現在,我們同樣需要為無(wú)序列表設定默認的margin/padding值為0,并去掉列表項前面的標記。每個(gè)列表項左浮動(dòng):
#header ul {margin:0;padding:0;list-style:none;}#header li {float:left;margin:0;padding:0;}設定錨鏈強制作為塊對象呈遞,我們便可無(wú)憂(yōu)的控制所有的樣式:
#header a {display:block;}下一步,我們將右側的背景圖像加入到列表項中去(改變如粗體所示):
#header li {float:left;background:url("norm_right.gif")no-repeat right top;margin:0;padding:0;}在加入左側圖像之前,我們可以在效果1種看看目前為止的效果。(在效果中,忽略body中的規則。僅設定基本margin,padding,colors,text的屬性。)
---
現在我們可以將左側圖像放置在錨鏈的左邊(容器內的元素)。我們同時(shí)加入padding,擴大標簽并將文本從標簽的邊緣推開(kāi):
#header a {display:block;background:url("norm_left.gif")no-repeat left top;padding:5px 15px;}這樣我們就得到了效果2。注意我們的標簽是如何成型的。在這里,IE5/Mac的用戶(hù)會(huì )立刻驚奇道,“天啊,我的標簽垂直堆在一起并且延伸至整個(gè)屏幕!”不要著(zhù)急,我們馬上幫你解決。眼下,盡量按照下面去做,或者方便的話(huà),臨時(shí)改換其他的瀏覽器,并且IE5/Mac版本的問(wèn)題會(huì )馬上得到解決。
---
現在,一般標簽的背景圖像已經(jīng)完成了,我們要為“當前”標簽更換圖像。我們通過(guò)對目標列表項加入id="current"和錨鏈來(lái)實(shí)現。既然不需要改變背景的其他外觀(guān),圖像除外,我們就使用background-image的特性:
#header #current {background-image:url("norm_right_on.gif");}#header #current a {background-image:url("norm_left_on.gif");}我們要在標簽下添加一條邊框。但是,將邊框屬性應用于父類(lèi)的#header容器上,將不能解決“當前”標簽無(wú)需邊框的問(wèn)題。于是我們制作新的帶有邊框的圖像以代替它。同樣,我們可以為它加入漸變效果:

我們將圖像放置到#header容器的背景中去(代替原有的黃色背景),將背景圖像移至到最下方,并為圖像上方留出的空白添加相應的背景顏色。同時(shí),去掉由body繼承下來(lái)的padding,為ul的上、左、右邊加進(jìn)10像素的padding:
#header {float:left;width:100%;background:#DAE0D2 url("bg.gif")repeat-x bottom;font-size:93%;line-height:normal;}#header ul {margin:0;padding:10px 10px 0;list-style:none;}我們必須讓“當前”標簽覆蓋邊框,如下面提示的那樣。你也許會(huì )認為我們將要把底部邊框加入到與其顏色相對應的、#header背景圖像中去,然后將“當前”標簽的底部邊框顏色改為白色。但是,對于挑剔的觀(guān)察者,還是會(huì )發(fā)現一些細小的差別。于是,我們改變錨鏈的padding,為“當前”標簽創(chuàng )造出直角來(lái),如下面放大的例子:

我們通過(guò)減少1像素普通錨鏈的底部padding值(5px-1px=4px)來(lái)實(shí)現,然后為“當前”錨鏈補上減去的padding。
#header a {display:block;background:url("norm_left.gif")no-repeat left top;padding:5px 15px 4px;}#header #current a {background-image:url("norm_left_on.gif");padding-bottom:5px;}經(jīng)過(guò)改變,底部邊框將在普通標簽中出現,而在“當前”標簽中則隱藏了起來(lái)。于是,我們得到了效果3。
敏銳的觀(guān)察者也許會(huì )在上一例注意到白色的標簽角落。這些不透明的角用來(lái)防止下面的圖像透過(guò)上面的一副。理論上,我們可以嘗試使用部分背景圖像來(lái)適應標簽的背景。但是我們的標簽會(huì )在高度上增長(cháng),嘗試通過(guò)移動(dòng)背景顏色,背景圖像就會(huì )相對變矮。代替的辦法是,改變圖像,將標簽的角落設為透明。如果弧線(xiàn)是反鋸齒的,我們在其邊緣使用較平均的背景色彩。
現在,角落已經(jīng)變成透明色,左邊的圖像將透過(guò)右邊圖像的角落。為了補償,我們?yōu)楸韱雾椉尤牒妥筮厛D像寬度相吻合的padding(9px)。既然已經(jīng)為表單項加入了padding,我們還需去掉同樣的寬度以達到文本的居中(15px-9px=6px):
#header li {float:left;background:url("right.gif")no-repeat right top;margin:0;padding:0 0 0 9px;}#header a {display:block;background:url("left.gif")no-repeat left top;padding:5px 15px 4px 6px;}仍未結束,因為加入了9個(gè)像素的padding使左邊圖像與標簽的左邊之間產(chǎn)生了一段空白?,F在,左側與右側,可見(jiàn)“doorway”的邊緣接在一起,我們再不需要將左邊圖像保持在上方。于是,交換兩幅背景圖像的順序,相反過(guò)來(lái)。同樣交換“當前”標簽中使用的兩幅圖像:
#header li {float:left;background:url("left.gif")no-repeat left top;margin:0;padding:0 0 0 9px;}#header a, #header strong, #header span {display:block;background:url("right.gif")no-repeat right top;padding:5px 15px 4px 6px;}#header #current {background-image:url("left_on.gif");}#header #current a {background-image:url("right_on.gif");padding-bottom:5px;}完成這些后,我們到達了效果4。要注意的是,透明的角落在標簽的左側產(chǎn)生了一段不能點(diǎn)擊的無(wú)效區域。這個(gè)區域在文本以外,但仍然是可以察覺(jué)到的。在標簽的兩邊都使用透明的圖像是沒(méi)有必要的。如果我們不希望產(chǎn)生這種無(wú)效的區域,那么我們必須使用在標簽后面使用顏色,然后用這種顏色來(lái)代替標簽角落的透明圖像?,F在我們僅保持這種透明角落。
---
對于剩下的問(wèn)題,我們將一次性完成全部的修改:加重標簽文本,將普通標簽中的文本改為棕色,“當前”標簽文本改為深灰色,去掉鏈接的下劃線(xiàn),最后將懸停文本色彩改為同樣的深灰色。經(jīng)過(guò)一系列的改變,我們將看到目前為止的效果5。
在效果2之后,我們公認的一個(gè)問(wèn)題就是在IE5/Mac瀏覽方式下,每個(gè)標簽延伸并占據了整個(gè)瀏覽器的寬度,以致標簽垂直的堆在了一起。這不是我們所希望的。
在大多數的瀏覽器中,浮動(dòng)一個(gè)元素會(huì )有收縮,收縮最小至它所包含內容的大小。如果一個(gè)浮動(dòng)元素包含一幅圖像或其本身即圖像,便會(huì )收縮至圖像的寬度。如果僅僅包含文本,那么將會(huì )收縮至最長(cháng)的,不可被頂開(kāi)的那文本的寬度。
一個(gè)問(wèn)題出現在IE5/Mac中的圖片中,當一個(gè)auto-width的塊對象元素被插入到一個(gè)浮動(dòng)的元素中時(shí)。其他的瀏覽器仍舊將浮動(dòng)縮小至最小,而無(wú)視容器內的塊對象元素。但IE5/Mac并不按照這種情況,相反它將浮動(dòng)和塊對象元素擴展至盡可能的寬度。為解決這個(gè)問(wèn)題,我們將錨鏈同時(shí)浮動(dòng)起來(lái),但僅僅對于IE5/Mac,以免放棄其他的瀏覽器。首先,我們?yōu)殄^鏈設定浮動(dòng)規則。然后,我們使用反斜杠注釋法來(lái)隱藏這種規則,讓它僅僅對IE5/Mac生效,而無(wú)視其他的瀏覽器:
#header a {float:left;display:block;background:url("right.gif")no-repeat right top;padding:5px 15px 4px 6px;text-decoration:none;font-weight:bold;color:#765;}/* Commented Backslash Hackhides rule from IE5-Mac \*/#header a {float:none;}/* End IE5-Mac hack */現在IE5/Mac瀏覽器將按我們所期望的那樣來(lái)顯示標簽,看效果6。對于非IE5/Mac的瀏覽器什么都不需要改變。注意到IE5.0/Mac的一系列解釋上的bug在IE5.1中解決。因此,滑動(dòng)門(mén)技術(shù)在5.0版本中所遭遇的問(wèn)題超出了hack的限度。既然升級到IE5.1/Mac已不成難題,OS 9 Macs/IE5.0的占有率應逐漸縮減至很低。
我們剛剛演練了滑動(dòng)門(mén)技術(shù),用純文本和無(wú)序列表來(lái)創(chuàng )造導航標簽,加以少量的樣式。它的裝載速度快,具有可維持性,并且文本的大小可以在不破壞外觀(guān)的情況下進(jìn)行較大的伸縮。不必我們再重申在創(chuàng )造復雜樣式的導航欄中,滑動(dòng)門(mén)技術(shù)所表現出來(lái)的彈性了。
只有想不到,沒(méi)有做不到。最終效果向我們展示了一例,但我們設計不可能因此而被限定死。
在某些場(chǎng)合,標簽不一定是對稱(chēng)的。我很快就制作了這種標簽的第二個(gè)版本,也有陰影3D的樣式,有角的邊緣,和具有特色的左邊部分。依據第二個(gè)版本,我們甚至可以交換左右兩幅圖像的位置。以這種細致的布局和靈巧的圖像控制,我們可以去掉按鈕的下邊框以便標簽圖像更好的去適應背景,如第三個(gè)版本所顯示的那樣。如果你的瀏覽器支持多個(gè)樣式表的切換,你甚至可以靠它在多個(gè)版本的導航欄之間自由切換。
仍有許多我們沒(méi)有提到的其他的效果??焖俚奶嵋幌?,我改變鼠標懸停的文本色彩,但是真個(gè)圖像可以替換掉以創(chuàng )造出更有趣的變換效果。即使標記中兩個(gè)嵌套的HTML元素,也可以用CSS來(lái)達到一些我們還未想到的效果。我們在此例中創(chuàng )造的僅僅是水平的標簽欄,但滑動(dòng)門(mén)亦可應用于許多其他的情形。閣下覺(jué)得如何呢?
聯(lián)系客服