DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> CSS入門知識 >> CSS詳解 >> CSS實例:超酷的網站導航按鈕
CSS實例:超酷的網站導航按鈕
編輯:CSS詳解     

導言:本文一步一步手把手教你打造一個極酷的三層分離的標准滑動門導航菜單,從思路、原理、步驟,手段可謂“無所不用其極”,即便你是菜鳥,相信你看了本文後,也能打造出屬於自己的超級漂亮的標准導航菜單。本菜單無冗余結構,利於數據動態輸出,非常適合於用在平常的項目中去。本教程中講到了基本的滑動門原理,相信對那些還在這條路上摸索的朋友會有一些幫助!當然如果有什麼錯誤和問題,也歡迎大家提出來探討。

本導航菜單想達到的理想目標是:

1.漂亮,有個性。

2.結構清晰,語義明確,無冗余標簽。

3.表現、結構、行為三層分離,無侵入式。

4.有利於後台程序的數據輸出。

5.菜單有三態效果的變化。

6.能高亮記錄點擊後的菜單項。

7.自適應文字的寬度。當文字內容長短變化時按鈕能適時變化。

8.兼容各大主流浏覽器。

讓我們一步一步的實現這種理想的菜單吧!

在論壇中經常看到很多朋友在制作菜單,但說實話,不是結構冗余,就是有形無神,或有神無貌。而我們現在要打造的就是極品菜單。無論您是新手或老手,在這個教程中都應該有所收獲。

一個理想的菜單其結構應該是干淨的、無冗余、分離的,然而因為種種的原因,會為它加上許多無意義的東西,到最後,會離“干淨”越來越遠。所以在做菜單前,有些原則是在整個制作過程一直要牢記的,不能以任何外力所阻擾。

結構篇

在我的印象中,理想的標准菜單應該具有下面的結構:

<div id="nav">

        <ul id="menu">

       <li><a href="#none" title="博客園">博客園</a></li>

       <li><a href="#none" title="社區">社區</a></li>

       <li><a href="#none" title="首頁">首頁</a></li>

       <li><a href="#none" title="新隨筆">新隨筆</a></li>

       <li><a href="#none" title="聯系">聯系</a></li>

       <li><a href="#none" title="管理">管理</a></li>

       <li><a href="#none" title="訂閱">訂閱</a></li>

       <li><a href="#none" title="冰極峰">冰極峰</a></li>

 </ul>

</div>

菜單的最原始的結構有了,可以看到這裡面是沒有任何無意義的標簽,每個標簽都有各自的語義。我們在浏覽器中看下,啊哦,確實很簡陋,就是原始的文字,像什麼,嗯,就像我們在菜館裡點菜用的菜單,可能比那個還簡單,並且每個菜單前面還有一個小圓點!哦,天啦,離我們的漂亮菜單還差好大一截呢!

樣式篇

好吧,它現在還只是一個骨架,我們稍微給它美化一下,加點簡單的樣式,至少應該去掉小圓點吧,並且讓它水平排列吧!

好,加點樣式:

*{margin:0;padding:0;}/*將它統一成一個模樣吧,不然在各個浏覽器下,會死得很難看*/

ul{list-style:none}/*去掉小圓點吧*/

li{float:left;margin-left:10px;}/*水平排列並來點間距吧,不要把我擠得太緊了。*/

嗯,現在看看,達到小目標了。

骨架有了,接下來就是給每個菜單項穿上漂亮的衣裳。

要滿足第一項要求,首先要有一個漂亮的按鈕,自已畫一個,哦,我不是美術人員,難!不過,別恢心,網絡之大,無奇不有,說不定人家已經有做好的,google一下,還真發現了一個,感謝啊!

有了設計好的按鈕源碼,省去設計的一環,真好。但要做成三態按鈕,還需要我們改造一下這個按鈕。看到第七條目標了嗎,我們是要做自適應的按鈕,所以要對這個按鈕做一些加工處理。

我們將這三個按鈕分別表現為鼠標移開、點擊後、鼠標移上時的三種狀態,要做滑動門菜單,需要將一個按鈕從中間剖開,左邊圖處放在左側,右邊圖片放在右側。要適應文字加長的情況,還要將這個圖層寬度拉長一點,但這個圖片有很復雜的陰影特效,不能隨便拉伸,否則效果就不像了。我們就從中間給它剖開,將右邊圖片的左側向前平輔拉伸。如圖二所示

圖一

所以我們先將它如圖哪樣切成六片,然後將這六張圖片合並在一起。為什麼要這樣呢?看看CSS sprites原理吧!

圖二

上圖中第一和第二個圖片組成普通菜單樣式(默認樣式),第三、第四個圖片組成翻滾樣式,第五和第六個圖片組成點擊後的菜單項樣式。

我們將陰影圖片專門提取出來,作成一張很小的背景圖片。

圖三

該要的圖形都准備好了,接下來,我們將這個圖片加在菜單項上吧。一個按鈕要用到兩張圖片才能表現出來。地球人都知道,一個標簽只能裝一張圖片(如果你發現一個標簽能裝上兩張圖片,請及時告訴我,我請你吃飯!)。哦!我的菜單結構中每一項剛好有兩個標簽,一個是li,它裡面有一個A標簽,剛好可以用來裝左右兩張圖片。Li用來裝左側的圖片,A用來裝右側的圖片。我真佩服我自己,這麼好的點子都能想得出來,正在沾沾自喜的自我陶醉中…

別忙,哦,天啦,如果這樣來裝圖片,我的三種鼠標翻滾狀態如何實現?我們都應該知道,目前除了該死的IE6,其它的浏覽器都支持li:hover偽類。然而要兼容各主流浏覽器(這是我們的第8項目標喲,別忘了!),這種方法是行不通的。IE6只能在A標簽上應用偽類,其它的標簽它可是一概不理!

既然IE6只能在A標簽上應用hover偽類,那麼我們要制作自適應的滑動門菜單,就需要在結構上動手腳了,看來只能在A標簽中再加入一個標簽,那麼菜單的結構就會變成下面這個樣子了。(注意:這兒就開始改變結構了,雖然我一直想極力避免這種情況的發生,但好像要達到要求,這個標簽是非加不可了。)

<li><a href="#none" title="冰極峰"><span>冰極峰</span></a></li>

我們在A標簽中加入了一個span容器,它將文字內容包括起來了。現在有兩個標簽,可以裝兩張圖片了。我們將右側圖片放在A標簽的背景中並向右靠齊,將左側圖片放在SPAN標簽中並向左靠齊。這樣就能表現出一個完整的按鈕形狀。

還好,雖說多加了一個標簽,但它還不是完全無語義。

好了,我們的准備工作都差不多了,該給菜單穿上新衣服了。

我們要做成自適應寬度的菜單,那麼,我們就不能設置菜單的寬度值,所以我們不能像平時制作一個水平的有固定寬度的菜單的做法那樣,設置寬度,然後向左浮動。如果這樣的話,每個菜單項的寬度不同時,要分別定義每一項的寬度,那就必須給每個菜單項定義一個ID或CLASS,並且這種方式也不利後台程序的動態循環輸出。

我們需要的是像內聯元素一樣從左到右自動在一行內排列每個菜單項,那麼我們就需要菜單以內聯的方式表現出來,OK,我們就用display:inline吧,這是一個非常有用的屬性:它解析後的排列方式能達到我們的基本要求:在一行內從左到右自動排列標簽元素,每一項寬度可以不同。

如果用上面這種屬性真的能滿足我們需要了,就沒有下面這一段文字內容。

雖說這個屬性能滿足我們項目基本需要,可是它有一個非常致命的弱點:它不能設置寬度和高度值,不信你可以試試。它只表現為文字的默認高度和寬度,超出這個寬高值後就自動隱藏了。這樣一來,我在這裡面是有背景圖片的,要表現出這個圖片效果,我們需要給定一個寬度和高度。這就不能做出我們的效果了,郁悶!還好,還有一個屬性:display:inline-block;它的表現就是我們需要的。

但是…這個屬性也有致命弱點,它只能被FF3等高級浏覽器識別。其它的浏覽器只能繞道而行了。啊哦!所以,統一浏覽器是多麼的重要啊!看來,HACK也是我們逼不得已的一種解脫方式了。

原理我們都了解了,我們可以根據上面兩篇文章提供的技巧來做一個自適應的菜單了。

我們先寫右側圖片的樣式,它是應用在li元素的子節點A標簽中的。

li a{display:inline-block; padding-right:30px; padding-top:10px; *padding-top:0; padding-bottom:13px; *padding-bottom:0; height:36px; background:url(images/button.gif) no-repeat right -36px;  text-decoration:none; font-size:12px; color:#fff;}

我們先設置display:inline-block,然後我們再用padding來撐開它的邊距,讓它有一定的空間來裝填圖片。注意,這裡的圖片路徑換成你自己的路徑。然後設置其它的樣式,如去掉下劃線,字體顏色,字體大小等等。設置圖片靠右對齊。

li a span{display:inline-block; padding-left:30px; padding-top:10px; *padding-top:0; padding-bottom:13px; padding-bottom:0; height:36px; line-height:36px; background:url(images/button.gif) no-repeat left top; font-weight:bold;}

按鈕左側的圖片是放在SPAN元素中的,將它的圖片向左對齊,也設置padding來撐開它的寬度和高度。

li a,li a span{display:inline;cursor:pointer;}

然後將它們的又設置回inline內聯模式,觸發IE的haslayout特性。

在上面的代碼,我們還看到有一個HACK的應用,*padding-bottom:0;和*padding-top:0;這用來解決IE與FF等浏覽器不同效果的。不信你刪除後看看會有什麼效果,在IE下高度伸展有問題。

好了下面該寫鼠標移上時的效果了。

li a:hover{padding-right:30px;background:url(images/button.gif) no-repeat right -108px;}

li a:hover span{padding-left:30px;background:url(images/button.gif) no-repeat left -72px;font-weight:bold;}

再接下來是鼠標點擊後的效果。

li a:active{padding-right:30px;background:url(images/button.gif) no-repeat right -180px;}

li a:active span{padding-left:30px;background:url(images/button.gif) no-repeat left -144px;font-weight:bold;}

ok,似乎大功告成,在不同浏覽器下看看,似乎都能達到滿意的效果。下面是截圖:

圖四

現在純CSS版的滑動門菜單基本上就做好了。

 

行為篇

 

上面的效果似乎離我的理想狀態的菜單又更進了一步。不過也有暇癡。

1.如我點擊一個菜單後其焦點虛線框讓人感到非常討厭。

2.還有點擊後不能高亮記錄當前選中項。

一步一步來解決吧!

為了除去此虛線框,我們可以在A標簽屬性中加入onfocus="this.blur();"這句代碼,這是非常立竿見影的方法。那麼就需要在結構上添加一些內容,可能就會變成下面這種結構了:

<li><a href="#none" title="冰極峰" onfocus="this.blur();"><span>冰極峰博客</span></a></li>

可是,我們別忘了,要盡量避免“行為”給“結構”造成干擾,這是我們在開始就提出的要求。因此,這種方法基本上可以否決了。

另外我們想記錄當前選中項菜單,這種制作方法有很多種,純CSS的做法可能會為每一個菜單項創建一個ID,然後用樣式表來設置不同頁面下調用高亮菜單的樣式。但這種方法又會對結構添加一些字符。

上面兩個解決方案都需要在結構中嵌入一些本來該用“動作”來表現的東西,這會造成結構冗余,可讀性較差,並且給人感覺頁面很亂。

我想該是JS粉墨登場的時候了...

我想在頁面一載入時就遍歷UL下的所有A標簽,自動給它加上一個樣式,這個樣式就是li a的樣式,我們可以將它改成一個class類,我們取名為normal吧,方便JS動態調用,並將li a:hover也換成一個class類,取名為over,作為JS動態調用鼠標移上時的效果,而li a:active就是當前選中狀態了,取名為cur,將它們三個都在樣式表中作出修改。

在頁面載入後,用for循環給每個菜單A標簽注入onclick,onmouseover,onmouSEOut事件,我們就可以摒棄用a:link,a:hover,a:active來摸擬三態效果了,因為這樣更便於控制當前選中菜單的高亮效果。順便在這個循環中去掉討厭的虛線框(雖說在FF下只用一句樣式就可以搞定,但在IE中顯然是不行的!)。然後我們用cookie來記錄選中的菜單項ID,並設置其為5分鐘後過期。這樣無論你如何惡意刷屏,高亮菜單還是能記住。(是否采用cookIE方式來保持高亮,這可以根據不同的項目需求來定。這種方式也有不好的地方,有同好者可以交流一下!)

JS中創建了幾個基本的函數,看起來就像下面這樣(詳細代碼請參看源碼):

var temp;/*菜單ID*/

function getObj(objName){return(document.getElementById(objName));}

window.onload =function() {

var obj=getObj("menu");/*ul的id*/

var obj_a=obj.getElementsByTagName("a");

number=obj_a.length;

for (var i=0,j=obj_a.length;i<j;i++){

obj_a[i].index=i;

obj_a[i].className="normal";

obj_a[i].onclick=function(){click(this)};

obj_a[i].onmouSEOver=function(){overme(this)};

obj_a[i].onmouSEOut=function(){outme(this)};

obj_a[i].onfocus=function(){this.blur()};/*去掉IE下的虛線框,ff用樣式解決*/

}

if (getCookIE("show_a") != null) {

obj_a[getCookIE("show_a")].className="cur";

temp=getCookIE("show_a")

}

else{

var obj=getObj("menu");

var obj_a=obj.getElementsByTagName("a");

obj_a[0].className="cur";

//鼠標滑過效果

function overme(o){/*代碼略,請看DEMO*/}

//鼠標移開後效果

function outme(o){/*代碼略,請看DEMO*/}

//鼠標點擊後效果

function click(o){/*代碼略,請看DEMO*/}

//設置cookIE

function setCookIE(sName,sValue,expireMinute) {/*代碼略,請看DEMO*/}

//獲取cookIE

function getCookIE(sName) {/*代碼略,請看DEMO*/}

加上以上的JS後,我們控制了菜單的交互動作,並精簡了菜單的結構,三層分離得比較徹底。這樣結構未做作何過多的變動,就達到我們理想的狀態。這樣的結構在添加後台代碼時,直接循環,只需要在菜單文字項的地方動態輸出數據就行了,干淨利落。

現在在各種主流浏覽器中看看你的成果,是否顯示得完全一樣呢!

圖五

至此,一個極酷的標准的滑動門導航菜單就在你手中誕生了! 

總結:我們在制作這些案例時,要隨時留意自己的結構,讓它能保持良好的前後伸展性。盡量杜決冗余的無語義的標簽,這在一個流水線似的工作環境中尤其顯得重要。給後端程序帶來巨大的方便的同時,也使自己的代碼看來比較舒服! 

本實例測試的兼容性環境是:

IE6/IE7/FF3/TT/Opera9.63/谷歌浏覽器測試通過,其它的浏覽器請朋友幫忙測試一下。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved