純CSS多級菜單

來源:互聯網
上載者:User
這部分最後給出的成品效果比較驚人,也就是傳說中的純CSS六級菜單。這個東西最厲害的地方是相容所有主流瀏覽器(IE6,IE8,Maxthon2.5,firefox3.5,opera10,safari4與chrome2),而一點CSS hack也沒有用。畢竟CSS hack只是權宜之計,治標不治本,誰知它會對未來新版本的瀏覽器有什麼副作用,因此能不用就不要用了。由於結構非常有規律,讀者認真學習後,可以自行擴充為十級菜單。

司徒正美 純CSS多級菜單

由於IE6能支援的偽類少得可憐,僅支援a元素的hover與visited與active。為了顯示隱藏的二級菜單,我們必須把二級菜單的那個無序列表放到a元素下,但這樣一來firefox那邊又發難了。這時我們就要請出IE的條件注釋,讓頁面在IE6下呈現一套結構層,在其他瀏覽器下呈現另一套。

  <p class="menu">    <ul>      <li>        <a href="http://www.cnblogs.com/rubylouvre/">菜單三<!--[if !IE 6]><!--></a><![endif]-->        <ul>          <li><a href="http://www.cnblogs.com/rubylouvre/">二級菜單_11</a></li>          <li><a href="http://www.cnblogs.com/rubylouvre/">二級菜單_12</a></li>        </ul>        <!--[if lte IE 6]></a><![endif]-->      </li>      <li>        <a href="http://www.cnblogs.com/rubylouvre/">菜單二<!--[if !IE 6]><!-->二</a><![endif]-->        <ul>          <li><a href="http://www.cnblogs.com/rubylouvre/">二級菜單_11</a></li>          <li><a href="http://www.cnblogs.com/rubylouvre/">二級菜單_12</a></li>        </ul>        <!--[if lte IE 6]></a><![endif]-->      </li>      <li>        //************略***********      </li>      <li>        //************略***********      </li>    </ul>  </p>

但是這樣做不能使IE6的二級菜單彈出來,這情形我在純CSS相簿遇到許多次。查一下國外的資料,說是IE用hover切換絕對位置子項目時存在問題,但具體情形又分許多種,解法也不一。但針對多級菜單的這種多層子項目,最常用的方法是把它們套在table中,這相當於table布局。因為table的容錯能力是最強的,這多得人們一直用它來布局,於是瀏覽器一直在增強它在這方面的優勢。感謝table,我們終於收拾IE6這個怪胎了。

<p class="menu">    <ul>      <li>        <a href="http://www.cnblogs.com/rubylouvre/">菜單<!--[if !IE 6]><!--><strong>一</strong></a><![endif]-->        <table><tr><td>              <ul>                <li><a href="http://www.cnblogs.com/rubylouvre/">二級菜單_11</a></li>                <li><a href="http://www.cnblogs.com/rubylouvre/">二級菜單_12</a></li>              </ul>        </td></tr></table>        <!--[if lte IE 6]></a><![endif]-->      </li>      <li>        <a href="http://www.cnblogs.com/rubylouvre/">菜單<!--[if !IE 6]><!--><strong>二</strong></a><![endif]-->        <table><tr><td>              <ul>                <li><a href="http://www.cnblogs.com/rubylouvre/">二級菜單_11</a></li>                <li><a href="http://www.cnblogs.com/rubylouvre/">二級菜單_12</a></li>              </ul>        </td></tr></table>        <!--[if lte IE 6]></a><![endif]-->      </li>      <li>        //*************略**************      </li>      <li>        //*************略**************      </li>    </ul>  </p>

但這樣一來對firefox等瀏覽器添加了許多多餘的結構層代碼,它們基本不需要table這東西就能運作良好。因此,我們把table整到IE條件注釋中。如:

<p class="menu">    <ul>      <li>        <a href="http://www.cnblogs.com/rubylouvre/">菜單        <!--[if !IE 6]><!--><strong>一</strong></a><![endif]-->        <!--[if lte IE 6]><table><tr><td><![endif]-->        <ul>          <li><a href="http://www.cnblogs.com/rubylouvre/">二級菜單_11</a></li>          <li><a href="http://www.cnblogs.com/rubylouvre/">二級菜單_12</a></li>        </ul>        <!--[if lte IE 6]></td></tr></table></a><![endif]-->      </li>      <li>        //*************略************      </li>      <li>        //*************略************      </li>      <li>       //*************略************      </li>    </ul>  </p>

然而,這結構層還能進一步精簡。同時我們應該留意到IE6水平菜單的異常高度,這是IE6的li元素在包含塊級顯示元素時會多出5px空隙。由於li元素包含的結構比較複雜,以前用對付img元素的幾種方法行不通了。我們可以顯式設定a元素的高度,讓多餘的部分隱藏掉就是。這就唯一不用CSS hack的方法。

更精簡的結構層:

 <p class="menu">    <ul>      <li>        <!--[if lte IE 6]><a href=""><table><tr><td><![endif]-->        <a href="http://www.cnblogs.com/rubylouvre/">菜單一</a>        <ul>          <li><a href="http://www.cnblogs.com/rubylouvre/">二級菜單_11</a></li>          <li><a href="http://www.cnblogs.com/rubylouvre/">二級菜單_12</a></li>        </ul>        <!--[if lte IE 6]></td></tr></table></a><![endif]-->      </li>      <li>         //***********略*********      </li>      <li>         //***********略*********      </li>      <li>         //***********略*********      </li>    </ul>  </p>
    .menu a {      display:block;      /*position:relative;發現放在a元素中,      在標準遊覽器中慘不忍睹,      和純CSS相簿3的第一個運行框在chrome中遇到的bug一樣*/      height:32px;      width:100px;      line-height:32px;      background:#a9ea00;      color:#ff8040;      text-decoration:none;      text-align:center;      overflow:hidden;/*★★★★*/    }

基於上面的結構我們就可以開發多級子功能表了。

這時我們又發現在IE6下,當我們的滑鼠移到二級菜單的上面時,一級功能表項目會出現一個邊框,顏色為hover時的背景色。在IE6,table與儲存格之間(cellspacing),儲存格與儲存格的內容之間(cellspadding)是存在空隙,背景色為transparent,也就是說永遠顯示下一層的背景色。由於我們設定a的display:block,它會佔滿td的所有空間,因此那個神秘的邊框應該是cellspacing。我們可以用以下的方式證實我的猜想。

    .menu table {      border:1px solid aqua;    }    .menu table td{      border:1px solid aqua;    }

知道問題的所在,我們就可以對症下藥了。解決方案有二。一是設定cellspacing等於零。由於cellspacing為DOM屬性,非CSS屬性,換言之,有多少個table我們就要寫多少次。二是設定border-collapse 為collapse,因為這樣會把table與它裡面的td的border合而為一,這樣它們之間的空隙也不複存在。我們當然選擇第二種啦。

    .menu table {      border-collapse: collapse;    }

最後總結一下:

  • 保證hover時,對應的子功能表的top與left在包含塊的範圍內。

  • 通常我們是用hover來調用display實現子項目的隱現,但在IE6中,mouseout後它不會乖乖消失,得換visibility上陣。

  • 某些瀏覽器在用a:hover來切換絕對位置子項目存在bug,統一用li:hover實現。

  • 在IE6中,啟用父級元素的a:hover後再調用其子孫元素的a:hover時,會沒有反應,換言之,不繼續向下渲染。這時我們需要table這個容錯能力最強的標籤出馬。

  • 為了跨平台的需要,我們需要用到IE條件注釋來切換相應的結構層代碼。

  • 在IE6中,當li元素包含display為block的元素時(如a)會多出5px,我們可以用overflow:hidden收拾之。

  • 在IE6中,table與td是存在空隙,當我們移動某個子功能表項時,其父功能表項目就會因為這些透明的空間而染上兩條邊。解決方案:設定table的border-collapse為collapse。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.