Home >Web Front-end >CSS Tutorial >Pure CSS multi-level menu
The final product effect given in this part is quite amazing, which is the legendary pure CSS six-level menu. The most powerful thing about this thing is that it is compatible with all mainstream browsers (IE6, IE8, Maxthon2.5, firefox3.5, opera10, safari4 and chrome2), and a little CSS hack is useless. After all, CSS hack is just a temporary measure, treating the symptoms but not the root cause. Who knows what side effects it will have on new versions of browsers in the future, so don’t use it if you can. Because the structure is very regular, readers can expand it to a ten-level menu after careful study.
Since IE6 supports very few pseudo-classes, it only supports hover, visited and active of the a element. In order to display the hidden secondary menu, we must put the unordered list of the secondary menu under the a element, but this brings firefox into trouble again. At this time, we need to ask for IE's conditional comments so that the page will present one set of structural layers under IE6 and another set under other browsers.
<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>
But doing this cannot make the secondary menu of IE6 pop up. I have encountered this situation many times in pure CSS photo albums. Checking foreign information, it is said that there is a problem when IE uses hover to switch absolutely positioned sub-elements, but there are many specific situations and different solutions. But for multi-level sub-elements of multi-level menus, the most common method is to put them in a table, which is equivalent to table layout. Because table has the strongest fault tolerance, so many people have been using it for layout, so browsers have been enhancing its advantages in this regard. Thanks to table, we finally got rid of the IE6 weirdo.
<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>
But this adds a lot of redundant structural layer code to browsers such as Firefox, which basically do not need tables to function well. Therefore, we integrated the table into IE conditional comments. Such as:
<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>
However, this structural layer can be further streamlined. At the same time, we should pay attention to the abnormal height of the horizontal menu of IE6. This is because the li element of IE6 will have an extra 5px gap when it contains block-level display elements. Since the structure contained in the li element is relatively complex, several methods used to deal with the img element in the past will not work. We can explicitly set the height of the a element and hide the excess part. This is the only way to do it without using CSS hacks.
More streamlined structural layer:
<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;/*★★★★*/ }
Based on the above structure, we can develop multi-level submenus.
At this time we discovered that under IE6, when our mouse moves over the secondary menu, a border will appear on the first-level menu item, and the color will be the background color when hovering . In IE6, there is a gap between the table and the cell (cellspacing), and between the cell and the cell content (cellspadding). The background color is transparent, which means that the background color of the next layer is always displayed. Since we set the display:block of a, it will occupy all the space of td, so the mysterious border should be cellspacing. We can confirm my conjecture in the following way.
.menu table { border:1px solid aqua; } .menu table td{ border:1px solid aqua; }
If we know what the problem is, we can prescribe the right remedy. There are two solutions. One is to set cellspacing equal to zero. Since cellspacing is a DOM attribute, not a CSS attribute, in other words, we have to write it as many times as there are tables. The second is to set border-collapse to collapse, because this will merge the table and the border of the td inside it into one, so that the gap between them will no longer exist. Of course we choose the second option.
.menu table { border-collapse: collapse; }
Finally summarize:
Ensure that when hovering, the top and left of the corresponding submenu Within the scope of the containing block.
Usually we use hover to call display to make sub-elements appear, but in IE6, it will not disappear after mouseout, so visibility must be changed.
Some browsers have bugs in using a:hover to switch absolutely positioned sub-elements, so use li:hover to achieve this.
In IE6, after activating the a:hover of the parent element and then calling the a:hover of its descendant element, there will be no response. In other words, the downward rendering will not continue. At this time, we need table, the most fault-tolerant label, to take action.
For cross-platform needs, we need to use IE conditional comments to switch the corresponding structural layer code.
In IE6, when the li element contains elements with a display of block (such as a), there will be 5px more. We can use overflow:hidden to clean it up.
In IE6, there is a gap between table and td. When we move a submenu item, its parent menu item will be stained with two sides because of these transparent spaces. Solution: Set the table's border-collapse to collapse.
For more pure CSS multi-level menu X related articles, please pay attention to the PHP Chinese website!