HTML Dog
跳至导航

CSS 下拉菜单

一种相当常见的导航形式是下拉菜单,其中子导航列表仅在鼠标光标移到链接上方时显示。

HTML Dog 在下拉菜单方面有着悠久的历史——早在 2003 年,我们就曾重点介绍过流行的 Suckerfish 下拉菜单方法。此后,标准和浏览器都取得了长足的进步,现在我们可以安全地使用一种更简单的技术,使用 CSS 而无需任何 JavaScript。

多级下拉菜单。

HTML:精美的嵌套列表

与所有好的导航一样,链接的列表是构建下拉菜单的最佳选择。由于我们希望一个项目显示一组子项目,因此我们肯定需要嵌套列表——也就是列表的列表。


<ul>
    <li>
        <a href="">Birds</a>
        <ul>
            <li><a href="">Ratites</a></li>
            <li><a href="">Fowl</a></li>
            <li><a href="">Neoaves</a></li>
        </ul>
    </li>
    <li>
        <a href="">Mammals</a>
        <ul>
            <li><a href="">Monotremes</a></li>
            <li><a href="">Marsupials</a></li>
            <li><a href="">Placentals</a></li>
        </ul>
    </li>
    <!-- etc. -->
</ul>

因此,“鸟类”和“哺乳动物”是我们顶层项目,“平胸鸟类”、“单孔类”等是我们第二层子类别项目。

CSS:最基本的要求

为了在视觉上设置好一切,让我们为列表清除默认的内边距(对于旧版浏览器,还包括外边距)。


ul {
    padding: 0;
    margin: 0;
}

接下来,对于每个列表项,我们希望将它们水平排列。提前考虑,我们还希望指定所有子列表的定位原点是其父列表项。


li {
    display: inline;
    position: relative;
}

现在,让我们来处理列表中的列表。我们希望将它们绝对定位,将它们置于所有元素之上,并隐藏它们。


ul ul {
    position: absolute;
    display: none;
}

最后,当鼠标悬停在主要列表项上时,显示这些子列表。


li:hover ul {
    display: block;
}

第一个配套示例展示了这一点,并附带了说明性的内联注释(查看源代码)。

多级下拉菜单

支持多个下拉菜单级别将涉及更多的列表嵌套。


<li>
    <a href="">Mammals</a>
    <ul>
        <li>
            <a href="">Monotremes</a>
            <ul>
                <li><a href="">Echidnas</a></li>
                <li><a href="">Platypus</a></li>
            </ul>
        </li>
        <li>
            <a href="">Marsupials</a>
            <ul>
                <li><a href="">Opossums</a></li>
                <li><a href="">Numbats, etc.</a></li>
                <li><a href="">Bandicoots, etc.</a></li>
                <li><a href="">Kangaroos, koalas, wombats, etc.</a></li>
            </ul>
        </li>
        <li>
            <a href="">Placentals</a>
            <ul>
                <li><a href="">Primates, ungulates, etc.</a></li>
                <li><a href="">Anteaters, sloths, etc.</a></li>
                <li><a href="">Elephants, etc.</a></li>
            </ul>
        </li>
    </ul>
</li>

现在,为了以略微不同的方式处理这些新的子子列表,我们希望它们出现在父列表项的旁边,而不是下方。


ul ul ul {
    left: 100%;
    top: 0;
}

还需要进行一些小修改。目前,悬停列表项的所有后代列表都会显示出来。因此,当悬停“哺乳动物”时,不仅会显示“单孔类”、“有袋动物”和“有胎盘类”,还会显示所有种类的哺乳动物——“负鼠”等等。我们只希望显示第一个后代——子项(而非孙项)。因此,我们通过插入一个子选择器来修改 li:hover ul


li:hover > ul {
    display: block;
}

美化

第三个配套示例稍微美化了一下。当然,演示选择权在您,但这提供了一些需要考虑的方面。突出显示父列表始终是提供额外提示您所处位置的好方法。过渡提供了额外的优势,可以使下拉菜单保持更长的时间,从而减少当鼠标光标短暂移出下拉菜单边界时列表消失的恼人问题。