zoukankan      html  css  js  c++  java
  • css div ul li 导航栏(横向):(纯CSS 多级菜单IE6能支持的)

    这部分最后给出的成品效果比较惊人,也就是传说中的纯CSS六级菜单。这个东西最厉害的地方是兼容所有主流浏览器(IE6,IE8,Maxthon2.5,firefox3.5,opera10,safari4与chrome2),而一点CSS hack也没有用。毕竟CSS hack只是权宜之计,治标不治本,谁知它会对未来新版本的浏览器有什么副作用,因此能不用就不要用了。由于结构非常有规律,读者认真学习后,可以自行扩展为十级菜单。

    纯CSS多级菜单

    由于IE6能支持的伪类少得可怜,仅支持a元素的hover与visited与active。为了显示隐藏的二级菜单,我们必须把二级菜单的那个无序列表放到a元素下,但这样一来firefox那边又发难了。这时我们就要请出IE的条件注释,让页面在IE6下呈现一套结构层,在其他浏览器下呈现另一套。

    01.<div class="menu">
    02.  <ul>
    03.    <li>
    04.      <a href="http://www.cnblogs.com/rubylouvre/">菜单三<!--[if !IE 6]><!--></a><![endif]-->
    05.      <ul>
    06.        <li><a href="http://www.cnblogs.com/rubylouvre/">二级菜单_11</a></li>
    07.        <li><a href="http://www.cnblogs.com/rubylouvre/">二级菜单_12</a></li>
    08.      </ul>
    09.      <!--[if lte IE 6]></a><![endif]-->
    10.    </li>
    11.    <li>
    12.      <a href="http://www.cnblogs.com/rubylouvre/">菜单二<!--[if !IE 6]><!-->二</a><![endif]-->
    13.      <ul>
    14.        <li><a href="http://www.cnblogs.com/rubylouvre/">二级菜单_11</a></li>
    15.        <li><a href="http://www.cnblogs.com/rubylouvre/">二级菜单_12</a></li>
    16.      </ul>
    17.      <!--[if lte IE 6]></a><![endif]-->
    18.    </li>
    19.    <li>
    20.      //************略***********
    21.    </li>
    22.    <li>
    23.      //************略***********
    24.    </li>
    25.  </ul>
    26.</div>

    但是这样做不能使IE6的二级菜单弹出来,这情形我在纯CSS相册遇到许多次。查一下国外的资料,说是IE用hover切换绝对定位子元素时存在问题,但具体情形又分许多种,解法也不一。但针对多级菜单的这种多层子元素,最常用的方法是把它们套在table中,这相当于table布局。因为table的容错能力是最强的,这多得人们一直用它来布局,于是浏览器一直在增强它在这方面的优势。感谢table,我们终于收拾IE6这个怪胎了。

    01.<div class="menu">
    02.    <ul>
    03.      <li>
    04.        <a href="http://www.cnblogs.com/rubylouvre/">菜单<!--[if !IE 6]><!--><strong>一</strong></a><![endif]-->
    05.        <table><tr><td>
    06.              <ul>
    07.                <li><a href="http://www.cnblogs.com/rubylouvre/">二级菜单_11</a></li>
    08.                <li><a href="http://www.cnblogs.com/rubylouvre/">二级菜单_12</a></li>
    09.              </ul>
    10.        </td></tr></table>
    11.        <!--[if lte IE 6]></a><![endif]-->
    12.      </li>
    13.      <li>
    14.        <a href="http://www.cnblogs.com/rubylouvre/">菜单<!--[if !IE 6]><!--><strong>二</strong></a><![endif]-->
    15.        <table><tr><td>
    16.              <ul>
    17.                <li><a href="http://www.cnblogs.com/rubylouvre/">二级菜单_11</a></li>
    18.                <li><a href="http://www.cnblogs.com/rubylouvre/">二级菜单_12</a></li>
    19.              </ul>
    20.        </td></tr></table>
    21.        <!--[if lte IE 6]></a><![endif]-->
    22.      </li>
    23.      <li>
    24.        //*************略**************
    25.      </li>
    26.      <li>
    27.        //*************略**************
    28.      </li>
    29.    </ul>
    30.  </div>

    但这样一来对firefox等浏览器添加了许多多余的结构层代码,它们基本不需要table这东西就能运作良好。因此,我们把table整到IE条件注释中。如:

    01.<div class="menu">
    02.    <ul>
    03.      <li>
    04.        <a href="http://www.cnblogs.com/rubylouvre/">菜单
    05.        <!--[if !IE 6]><!--><strong>一</strong></a><![endif]-->
    06.        <!--[if lte IE 6]><table><tr><td><![endif]-->
    07.        <ul>
    08.          <li><a href="http://www.cnblogs.com/rubylouvre/">二级菜单_11</a></li>
    09.          <li><a href="http://www.cnblogs.com/rubylouvre/">二级菜单_12</a></li>
    10.        </ul>
    11.        <!--[if lte IE 6]></td></tr></table></a><![endif]-->
    12.      </li>
    13.      <li>
    14.        //*************略************
    15.      </li>
    16.      <li>
    17.        //*************略************
    18.      </li>
    19.      <li>
    20.       //*************略************
    21.      </li>
    22.    </ul>
    23.  </div>

    然而,这结构层还能进一步精简。同时我们应该留意到IE6水平菜单的异常高度,这是IE6的li元素在包含块级显示元素时会多出5px空隙。由于li元素包含的结构比较复杂,以前用对付img元素的几种方法行不通了。我们可以显式设置a元素的高度,让多余的部分隐藏掉就是。这就唯一不用CSS hack的方法。

    更精简的结构层:

    01.<div class="menu">
    02.   <ul>
    03.     <li>
    04.       <!--[if lte IE 6]><a href=""><table><tr><td><![endif]-->
    05.       <a href="http://www.cnblogs.com/rubylouvre/">菜单一</a>
    06.       <ul>
    07.         <li><a href="http://www.cnblogs.com/rubylouvre/">二级菜单_11</a></li>
    08.         <li><a href="http://www.cnblogs.com/rubylouvre/">二级菜单_12</a></li>
    09.       </ul>
    10.       <!--[if lte IE 6]></td></tr></table></a><![endif]-->
    11.     </li>
    12.     <li>
    13.        //***********略*********
    14.     </li>
    15.     <li>
    16.        //***********略*********
    17.     </li>
    18.     <li>
    19.        //***********略*********
    20.     </li>
    21.   </ul>
    22. </div>
    01..menu a {
    02.  display:block;
    03.  /*position:relative;发现放在a元素中,
    04.  在标准游览器中惨不忍睹,
    05.  和纯CSS相册3的第一个运行框在chrome中遇到的bug一样*/
    06.  height:32px;
    07.  width:100px;
    08.  line-height:32px;
    09.  background:#a9ea00;
    10.  color:#ff8040;
    11.  text-decoration:none;
    12.  text-align:center;
    13.  overflow:hidden;/*★★★★*/
    14.}

    基于上面的结构我们就可以开发多级子菜单了。

    这时我们又发现在IE6下,当我们的鼠标移到二级菜单的上面时,一级菜单项会出现一个边框,颜色为hover时的背景色。在IE6,table与单元格之间(cellspacing),单元格与单元格的内容之间(cellspadding)是存在空隙,背景色为transparent,也就是说永远显示下一层的背景色。由于我们设置a的display:block,它会占满td的所有空间,因此那个神秘的边框应该是cellspacing。我们可以用以下的方式证实我的猜想。

    1..menu table {
    2.  border:1px solid aqua;
    3.}
    4..menu table td{
    5.  border:1px solid aqua;
    6.}

    知道问题的所在,我们就可以对症下药了。解决方法有二。一是设置cellspacing等于零。由于cellspacing为DOM属性,非CSS属性,换言之,有多少个table我们就要写多少次。二是设置border-collapse 为collapse,因为这样会把table与它里面的td的border合而为一,这样它们之间的空隙也不复存在。我们当然选择第二种啦。

    1..menu table {
    2.  border-collapse: collapse;
    3.}

    司徒正美 纯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。
  • 相关阅读:
    为什么mvc里面的ModelState.IsValid一只都是true
    ASP.NET MVC Filters 4种默认过滤器的使用【附示例】
    ASP.NET MVC学习之过滤器篇(1)
    百分比定位加position定位的常用布局
    angular_$inject
    angular的$scope,这东西满重要的
    angular-scope.assign
    angular_$attrs
    angular-input
    angular_form
  • 原文地址:https://www.cnblogs.com/dudu837/p/1878558.html
Copyright © 2011-2022 走看看