这是一个相当炫的功能,让网页看起来像桌面程序,如 window 的开始菜单。实现原理基本和纯 CSS 相册差不多,但要注意的事项比较多,让我们一步步来吧。
先来一个非常简单的一级菜单与悬停效果。
< ul id="menu">
< li >
< a href="http://www.cnblogs.com/rubylouvre/">
菜单一 < span > </ span >
</ a >
</ li >
< li >
< a href="http://www.cnblogs.com/rubylouvre/">
菜单二 < span > </ span >
</ a >
</ li >
< li >
< a href="http://www.cnblogs.com/rubylouvre/">
菜单三 < span > </ span >
</ a >
</ li >
< li class="last">
< a href="http://www.cnblogs.com/rubylouvre/">
菜单四 < span > </ span >
</ a >
</ li >
</ ul >
|
结构很熟悉吧,就是把原来放图片的地方换成文字而已。我还特意标出来了。接着下来的表现层代码非常简单。
* {
margin : 0 ;
padding : 0 ;
}
.menu {
font-size : 12px ;
}
.menu li {
float : left ;
list-style : none ;
}
.menu a {
display : block ;
position : relative ;
height : 32px ;
width : 100px ;
line-height : 32px ;
background : #a9ea00 ;
color : #ff8040 ;
text-decoration : none ;
text-align : center ;
}
.menu a:hover {
background : #369 ;
color : #fff ;
}
.menu li span {
display : none ;
position : absolute ;
left : 0 ;
top : 32px ;
width : 200px ;
height : 150px ;
background : #B9D6FF ;
}
.menu a:hover span {
display : block ;
}
|
<!doctype html>
<title> 纯 CSS 相册 by 司徒正美 </title>
<meta charset="utf-8"/>
<meta name="keywords" content="纯 CSS 多级菜单 by 司徒正美" />
<meta name="description" content="纯 CSS 多级菜单 by 司徒正美" />
</head>
<body>
<style type="text/css">
* {
margin:0;
padding:0;
}
.menu {font-size:12px;}
.menu li {/* 水平菜单 */
float:left;
list-style:none;
}
.menu a {
display:block;
position:relative;
height:32px;
width:100px;
line-height:32px;
background:#a9ea00;
color:#ff8040;
text-decoration:none;
text-align:center;
}
.menu a:hover {
background:#369;
color:#fff;
}
.menu li span {
display:none;
position:absolute;
left:0;
top:32px;
width:200px;
height:150px;
background:#B9D6FF;
}
.menu a:hover span {display:block;}
<p></style></p>
<p><h1> 纯 CSS 多级菜单 by 司徒正美 </h1><br />
<div class="menu"><br />
<ul><br />
<li><br />
<a href="<a href="http://www.cnblogs.com/rubylouvre/">http://www.cnblogs.com/rubylouvre/</a>"><br />
菜单一 <!-- 小图 --><span><!-- 大图 --></span><br />
</a><br />
</li><br />
<li><br />
<a href="<a href="http://www.cnblogs.com/rubylouvre/">http://www.cnblogs.com/rubylouvre/</a>"><br />
菜单二 <!-- 小图 --><span><!-- 大图 --></span><br />
</a><br />
</li><br />
<li><br />
<a href="<a href="http://www.cnblogs.com/rubylouvre/">http://www.cnblogs.com/rubylouvre/</a>"><br />
菜单三 <!-- 小图 --><span><!-- 大图 --></span><br />
</a><br />
</li><br />
<li class="last"><br />
<a href="<a href="http://www.cnblogs.com/rubylouvre/">http://www.cnblogs.com/rubylouvre/</a>"><br />
菜单四 <!-- 小图 --><span><!-- 大图 --></span><br />
</a><br />
</li><br />
</ul><br />
</div><br />
</body><br />
</html><br />
运行代码
这里有两个值得注意的地方。我们先说第一个。子菜单 (span 元素) 的 top 应该能使其顶部停留在 a 元素的范围内,如果包含块是 li 元素,同理。当 span 的 top 值大于 32px,如 40px,我们就无法把鼠标移到 span 元素上。因为离开了 a:hover 的作用范围,span 元素又重新隐藏。
.menu li span {
display : none ;
position : absolute ;
left : 0 ;
top : 40px ;
width : 200px ;
height : 150px ;
background : #B9D6FF ;
}
|
<!doctype html>
<title> 纯 CSS 相册 by 司徒正美 </title>
<meta charset="utf-8"/>
<meta name="keywords" content="纯 CSS 多级菜单 by 司徒正美" />
<meta name="description" content="纯 CSS 多级菜单 by 司徒正美" />
</head>
<body>
<style type="text/css">
* {
margin:0;
padding:0;
}
.menu {font-size:12px;}
.menu li {/* 水平菜单 */
float:left;
list-style:none;
}
.menu a {
display:block;
position:relative;
height:32px;
width:100px;
line-height:32px;
background:#a9ea00;
color:#ff8040;
text-decoration:none;
text-align:center;
}
.menu a:hover {
background:#369;
color:#fff;
}
.menu ul span {
display:none;
position:absolute;
left:0;
top:40px;/*★★修改这里★★*/
width:200px;
height:150px;
background:#B9D6FF;
}
.menu a:hover span {display:block;}
<p></style><br />
<h1> 纯 CSS 多级菜单 by 司徒正美 </h1><br />
<div class="menu"><br />
<ul><br />
<li><br />
<a href="<a href="http://www.cnblogs.com/rubylouvre/">http://www.cnblogs.com/rubylouvre/</a>"><br />
菜单一 <!-- 小图 --><span><!-- 大图 --></span><br />
</a><br />
</li><br />
<li><br />
<a href="<a href="http://www.cnblogs.com/rubylouvre/">http://www.cnblogs.com/rubylouvre/</a>"><br />
菜单二 <!-- 小图 --><span><!-- 大图 --></span><br />
</a><br />
</li><br />
<li><br />
<a href="<a href="http://www.cnblogs.com/rubylouvre/">http://www.cnblogs.com/rubylouvre/</a>"><br />
菜单三 <!-- 小图 --><span><!-- 大图 --></span><br />
</a><br />
</li><br />
<li class="last"><br />
<a href="<a href="http://www.cnblogs.com/rubylouvre/">http://www.cnblogs.com/rubylouvre/</a>"><br />
菜单四 <!-- 小图 --><span><!-- 大图 --></span><br />
</a><br />
</li><br />
</ul><br />
</div><br />
</body><br />
</html><br />
运行代码
第二个问题是 IE6 特有的,就是子菜单在对应的包含块 mouseout 后仍不消失的问题。hover 伪类相当于 moverover 与 moverout。我们在可以在 mouseover 给它的子孙元素认定一种样式,mouseout 时认定另一种。换言之,display 现在在 IE6 无法切换(img 元素除外)。解决方法用 visibility 代替 display。
<!doctype html>
<title> 纯 CSS 相册 by 司徒正美 </title>
<meta charset="utf-8"/>
<meta name="keywords" content="纯 CSS 多级菜单 by 司徒正美" />
<meta name="description" content="纯 CSS 多级菜单 by 司徒正美" />
</head>
<body>
<style type="text/css">
* {
margin:0;
padding:0;
}
.menu {font-size:12px;}
.menu li {/* 水平菜单 */
float:left;
list-style:none;
}
.menu a {
display:block;
position:relative;
height:32px;
width:100px;
line-height:32px;
background:#a9ea00;
color:#ff8040;
text-decoration:none;
text-align:center;
}
.menu a:hover {
background:#369;
color:#fff;
}
.menu ul span {
visibility:hidden;
position:absolute;
left:0;
top:32px;
width:200px;
height:150px;
background:#B9D6FF;
}
.menu a:hover span {visibility:visible;}
<p></style><br />
<h1> 纯 CSS 多级菜单 by 司徒正美 </h1><br />
<div class="menu"><br />
<ul><br />
<li><br />
<a href="<a href="http://www.cnblogs.com/rubylouvre/">http://www.cnblogs.com/rubylouvre/</a>"><br />
菜单一 <!-- 小图 --><span><!-- 大图 --></span><br />
</a><br />
</li><br />
<li><br />
<a href="<a href="http://www.cnblogs.com/rubylouvre/">http://www.cnblogs.com/rubylouvre/</a>"><br />
菜单二 <!-- 小图 --><span><!-- 大图 --></span><br />
</a><br />
</li><br />
<li><br />
<a href="<a href="http://www.cnblogs.com/rubylouvre/">http://www.cnblogs.com/rubylouvre/</a>"><br />
菜单三 <!-- 小图 --><span><!-- 大图 --></span><br />
</a><br />
</li><br />
<li class="last"><br />
<a href="<a href="http://www.cnblogs.com/rubylouvre/">http://www.cnblogs.com/rubylouvre/</a>"><br />
菜单四 <!-- 小图 --><span><!-- 大图 --></span><br />
</a><br />
</li><br />
</ul><br />
</div><br />
</body><br />
</html><br />
运行代码
好了,现在我们真正做二级菜单,把有关 span 的 CSS 全删掉,并在结构层原 span 的位置改为如下代码:
< ul >
< li >< a href="http://www.cnblogs.com/rubylouvre/">二级菜单_11</ a ></ li >
< li >< a href="http://www.cnblogs.com/rubylouvre/">二级菜单_12</ a ></ li >
</ ul >
|
<!doctype html>
<title> 纯 CSS 相册 by 司徒正美 </title>
<meta charset="utf-8"/>
<meta name="keywords" content="纯 CSS 多级菜单 by 司徒正美" />
<meta name="description" content="纯 CSS 多级菜单 by 司徒正美" />
</head>
<body>
<style type="text/css">
* {
margin:0;
padding:0;
}
.menu {font-size:12px;}
.menu li {/* 水平菜单 */
float:left;
list-style:none;
}
.menu a {
display:block;
position:relative;
height:32px;
width:100px;
line-height:32px;
background:#a9ea00;
color:#ff8040;
text-decoration:none;
text-align:center;
}
.menu a:hover {
background:#369;
color:#fff;
}
</style>
<h1> 纯 CSS 多级菜单 by 司徒正美 </h1>
<div class="menu">
<ul>
<li>
<a href="http://www.cnblogs.com/rubylouvre/">
菜单一
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _11</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _12</a></li>
</ul>
</a>
</li>
<li>
<a href="http://www.cnblogs.com/rubylouvre/">
菜单二
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _21</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _22</a></li>
</ul>
</a>
</li>
<li>
<a href="http://www.cnblogs.com/rubylouvre/">
菜单三
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _31</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _32</a></li>
</ul>
</a>
</li>
<li class="last">
<a href="http://www.cnblogs.com/rubylouvre/">
菜单四
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _41</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _42</a></li>
</ul>
</a>
</li>
</ul>
</div>
</body>
</html>
运行代码
我们在各游览器看一下,感觉非常乏力。IE6 与 Opera10 的二级菜单项是垂直的,但我们并没有清除浮动啊?firefox3.5 与 chrome 与 safari4 的二级菜单项是水平分布了,但上面好像多出一个菜单项……IE8 同学这次反而是表现得最好的。我没有装 IE7,所以一向忽略它。
我们重新设置一下样式,如把包含块改设在 li 元素上,让二级菜单项呈垂直显示。
* {
margin : 0 ;
padding : 0 ;
}
.menu {
font-size : 12px ;
}
.menu li {
float : left ;
list-style : none ;
position : relative ;
}
.menu a {
display : block ;
height : 32px ;
width : 100px ;
line-height : 32px ;
background : #a9ea00 ;
color : #ff8040 ;
text-decoration : none ;
text-align : center ;
}
.menu a:hover {
background : #369 ;
color : #fff ;
}
.menu ul ul {
visibility : hidden ;
position : absolute ;
left : 0px ;
top : 32px ;
}
.menu ul a:hover ul{
visibility : visible ;
}
.menu ul ul li {
clear : both ;
text-align : left ;
}
|
<!doctype html>
<title> 纯 CSS 相册 by 司徒正美 </title>
<meta charset="utf-8"/>
<meta name="keywords" content="纯 CSS 多级菜单 by 司徒正美" />
<meta name="description" content="纯 CSS 多级菜单 by 司徒正美" />
</head>
<body>
<style type="text/css">
* {
margin:0;
padding:0;
}
.menu {font-size:12px;}
.menu li {/* 水平菜单 */
float:left;
list-style:none;
position:relative;/* 把包含块移动 li 元素 */
}
.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;
}
.menu a:hover {
background:#369;
color:#fff;
}
/* 新增的二级菜单部分 */
.menu ul ul {
visibility:hidden;/* 开始时是隐藏的 */
position:absolute;
left:0px;
top:32px;
}
.menu ul a:hover ul{visibility:visible;}
.menu ul ul li {
clear:both;/* 垂直显示 */
text-align:left;
}
</style>
<h1> 纯 CSS 多级菜单 by 司徒正美 </h1>
<div class="menu">
<ul>
<li>
<a href="http://www.cnblogs.com/rubylouvre/">
菜单一
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _11</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _12</a></li>
</ul>
</a>
</li>
<li>
<a href="http://www.cnblogs.com/rubylouvre/">
菜单二
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _21</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _22</a></li>
</ul>
</a>
</li>
<li>
<a href="http://www.cnblogs.com/rubylouvre/">
菜单三
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _31</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _32</a></li>
</ul>
</a>
</li>
<li class="last">
<a href="http://www.cnblogs.com/rubylouvre/">
菜单四
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _41</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _42</a></li>
</ul>
</a>
</li>
</ul>
</div>
</body>
</html>
运行代码
发现二级菜单在 firefox 与 safari 与 chrome 中没有反应,弹不出来(这三个浏览器的 CSS 部分互相抄袭严重啊)。opera10 表现得最好,IE8 其次。不过,标准浏览器的所有元素都支持 hover 伪类,不像 IE6,非带 href 的 a 元素不可。我们改写部分 CSS 代码:
.menu ul li:hover ul,
.menu ul a:hover ul{
visibility : visible ;
}
|
<!doctype html>
<title> 纯 CSS 相册 by 司徒正美 </title>
<meta charset="utf-8"/>
<meta name="keywords" content="纯 CSS 多级菜单 by 司徒正美" />
<meta name="description" content="纯 CSS 多级菜单 by 司徒正美" />
</head>
<body>
<style type="text/css">
* {
margin:0;
padding:0;
}
.menu {font-size:12px;}
.menu li {/* 水平菜单 */
float:left;
list-style:none;
position:relative;/* 把包含块移动 li 元素 */
}
.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;
}
.menu a:hover {
background:#369;
color:#fff;
}
/* 新增的二级菜单部分 */
.menu ul ul {
visibility:hidden;/* 开始时是隐藏的 */
position:absolute;
left:0px;
top:32px;
}
.menu ul li:hover ul,/* 非 IE6*/
.menu ul a:hover ul{/*IE6*/
visibility:visible;
}
.menu ul ul li {
clear:both;/* 垂直显示 */
text-align:left;
}
</style>
<h1> 纯 CSS 多级菜单 by 司徒正美 </h1>
<div class="menu">
<ul>
<li>
<a href="http://www.cnblogs.com/rubylouvre/">
菜单一
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _11</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _12</a></li>
</ul>
</a>
</li>
<li>
<a href="http://www.cnblogs.com/rubylouvre/">
菜单二
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _21</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _22</a></li>
</ul>
</a>
</li>
<li>
<a href="http://www.cnblogs.com/rubylouvre/">
菜单三
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _31</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _32</a></li>
</ul>
</a>
</li>
<li class="last">
<a href="http://www.cnblogs.com/rubylouvre/">
菜单四
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _41</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _42</a></li>
</ul>
</a>
</li>
</ul>
</div>
</body>
</html>
运行代码
二级菜单能弹出来了,但那个神秘的 li 元素也现形了。我用双重浮动的收缩包围 (shrink-wrapping) 现象都无法消除这个神秘的 li 元素。参考外国的代码,方法是,把整个子菜单放到 a 元素的外面,然后用 li:hover 控制样式的切换。于是结构层改写如下:
< div class="menu">
< ul >
< li >
< 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 >
</ li >
< li >
< a href="http://www.cnblogs.com/rubylouvre/">菜单二</ a >
< ul >
< li >< a href="http://www.cnblogs.com/rubylouvre/">二级菜单_21</ a ></ li >
< li >< a href="http://www.cnblogs.com/rubylouvre/">二级菜单_22</ a ></ li >
</ ul >
</ li >
< li >
//***************略************
</ li >
< li >
//***************略************
</ li >
</ ul >
</ div >
|
<!doctype html>
<title> 纯 CSS 相册 by 司徒正美 </title>
<meta charset="utf-8"/>
<meta name="keywords" content="纯 CSS 多级菜单 by 司徒正美" />
<meta name="description" content="纯 CSS 多级菜单 by 司徒正美" />
</head>
<body>
<style type="text/css">
* {
margin:0;
padding:0;
}
.menu {font-size:12px;}
.menu li {/* 水平菜单 */
float:left;
list-style:none;
position:relative;/* 把包含块移动 li 元素 */
}
.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;
}
.menu a:hover {
background:#369;
color:#fff;
}
/* 新增的二级菜单部分 */
.menu ul ul {
visibility:hidden;/* 开始时是隐藏的 */
position:absolute;
left:0px;
top:32px;
}
.menu ul li:hover ul,/* 非 IE6*/
.menu ul a:hover ul{/*IE6*/
visibility:visible;
}
.menu ul ul li {
clear:both;/* 垂直显示 */
text-align:left;
}
</style>
<h1> 纯 CSS 多级菜单 by 司徒正美 </h1>
<div class="menu">
<ul>
<li>
<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>
</li>
<li>
<a href="http://www.cnblogs.com/rubylouvre/"> 菜单二 </a>
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _21</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _22</a></li>
</ul>
</li>
<li>
<a href="http://www.cnblogs.com/rubylouvre/"> 菜单三 </a>
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _31</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _32</a></li>
</ul>
</li>
<li>
<a href="http://www.cnblogs.com/rubylouvre/"> 菜单四 </a>
<ul>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _41</a></li>
<li><a href="http://www.cnblogs.com/rubylouvre/"> 二级菜单 _42</a></li>
</ul>
</li>
</ul>
</div>
</body>
</html>
运行代码
好了,搞定非 IE6 的所有游览器了,下一部分我们来处理 IE6 这个固执的孩子。
如果您觉得此文有帮助,可以打赏点钱给我支付宝 1669866773@qq.com ,或扫描二维码

