纯 CSS3 多级下拉菜单

3,487 阅读3分钟
原文链接: justclear.github.io

之前有用 CSS3 新特性 :checked 选择器写了两个简单的标签切换效果后台面板和CSS3 Tab 切换,这两个原理是一样的,不一样的只是它们的样式而已,通过 :checked 这个强大的选择器我们可以不借助 JavaScript 的情况下写出标签切换的功能,不过当然拉,与通过 JavaScript 来写的相比,纯 CSS3 写的标签切换效果在特效上和兼容性上都还有一定的差距,不过我个人觉得能不用 JavaScript 就尽量不用,这次我又用 :hover 伪类写了个非常简单的多级菜单下拉效果,这种菜单在博客中比较常见。

查看图片

Github Demo

先贴 HTML 代码:

然后 LESS 代码:

/* Menu */

.menu {
    background-color: #fff;
    width: 100%;
    height: 60px;

    & ul {
        background-color: #fff;
        text-align: center;

        & li ul {
            display: none;
            position: absolute;
            top: 60px;
            width: 100%;
            background-color: #fff;
            transform: all .5s;

            & li {
                width: 100%;

                & ul {
                    position: absolute;
                    top: 0;
                    left: 100%;
                }
            }
        }
    }

    & li {
        width: 25%;
        float: left;
        position: relative;

        &:hover > a {
                background-color: #f0f0f0;
            }

        & a {
            display: block;
            color: #666;
            line-height: 60px;

            &:hover {
                background-color: #f0f0f0;
            }

            &:hover + ul {
                display: block;
            }
        }

        & ul:hover {
            display: block;
        }
    }
}

通过 LESS 可以很清晰的查看元素在 HTML 中的嵌套关系,在这里我使用:

把所有 li 元素下面的 ul 隐藏掉,因为待会儿我们会通过对 li 中的 a 标签使用 :hover 伪类来判断什么时候该显示它们,代码如下:

.menu li a:hover + ul {
    display: block;
}

这段代码的意思是,当鼠标移到某个 li 元素中的 a 标签时,如果这个 li 标签包含了 ul 标签,这显示这个 ul 标签,其中的 + 号是选择相邻兄弟选择器,在这里的意思是紧跟 a 标签后的第一个兄弟元素 ul ,在这里为什么不用 ~ 选择器是因为如果使用它了的话,当我们鼠标移动到某个包含了多级菜单的菜单上时,其后代元素中的所有 ul 都会显示,换句话说就是它的所有子菜单都会同时显示,这并不是我们想要的结果,所以在这里只能用 + 相邻兄弟选择器。

还有一点要注意的是,如果此时你要把鼠标移动到二级菜单上的话,它会马上消失,这是因为我们只对当鼠标移动到 a 标签上时才显示后面的 ul,所以当我们鼠标移除 a 标签的一瞬间 ul 的 display 属性值又变成了 none 了,所以在这里我们还需要对 ul 本身的 :hover 做出设置,如下代码:

.menu li ul:hover {
    display: block;
}

这样当我们把鼠标从 a 标签移动到它后面的 ul 时 ul 本身不会消失了。