首頁  >  文章  >  web前端  >  純CSS多層選單

純CSS多層選單

高洛峰
高洛峰原創
2017-02-24 11:58:231066瀏覽

這部分最後給的成品效果比較驚人,也就是傳說中的純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;
    }

純CSS多層選單

#最後總結:

  • 保證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。


更多純CSS多層次選單X相關文章請關注PHP中文網!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:CSS版面題整理下一篇:CSS版面題整理