支持无限级水平和垂直菜单的纯 CSS 菜单





5.00/5 (6投票s)
使用提供的带有类名 div 的 CSS 构建一个外观整洁的基于 Web 的菜单,该菜单不需要 JavaScript,并且支持无限级别的水平和垂直菜单。
引言
是的 - 又一个“纯 CSS 菜单”解决方案。不过,此版本有一些不错的特性
- 支持所有菜单和子菜单的水平和垂直方向
- 支持从菜单到子菜单移动时方向的所有组合(也就是说,无论父菜单是水平还是垂直方向,都可以很好地支持水平和垂直子菜单)
- 支持无限级别的子菜单,无需特殊类(例如,每个级别的“
level-1-menu
”、“level-2-menu
”) - 使用带类名的
DIV
而不是UL
/LI
或表格 - 这使结构保持简单 - 我已经对 CSS 进行了全面记录,使其易于自定义,并且用于构建菜单的 HTML 结构非常简单。
这是使用此 CSS/HTML 构建的菜单的示例,显示了多个级别和方向
在上述示例中未显示的示例代码中,还包含多个连接的水平菜单级别。要访问它,请导航至 [项目 1 -- 子项目 1 -- 子子项目 3],您将在那里找到它们。
Using the Code
使用此代码有两个主要步骤。第一步很简单 - 只需将 CSS 复制到 CSS 文件中并链接它,或者将其包含在 HTML 文件中的 <style type='text/css'>...</style>
标签内。
这是生成上述示例的CSS... CSS 的完全注释版本包含在 项目演示文件中,因此我只会做一些注释。
首先,以下大多数 CSS 都相对重要,但其中一些可以更改。我假设读者具有一般性地知道什么可以安全更改,什么不可以更改的知识。如果您决定自定义,只需进行少量更改,然后测试这些更改以确保没有重大问题。一些比较棘手的内容 - background-color
应在 div.menu
上指定,即使您希望菜单是透明的;否则,将出现一个讨厌的 Internet Explorer 错误,菜单有时会消失,即使鼠标仍在悬停在其上方。您可以使用 rgba(0,0,0,0)
来获得透明菜单,这似乎可以消除 Internet Explorer 错误,但“transparent
”和根本不设置 background-color
似乎都会出现此错误,尽管它是间歇性的。Internet Explorer 的另一个小问题是子菜单定位有点偏差。如果您调整子菜单的边距设置,然后在 Internet Explorer 和其他浏览器中进行测试,您应该会看到我所指的内容,特别是如果您在子菜单周围放置边框。
div.menu {
display: none;
color: white;
background-color: rgba(0,0,0,1);
}
div.top {
display: inline-block;
}
div.top.hmb > div.item {
display: inline-block;
}
div.menu > div.item {
white-space: nowrap;
cursor: pointer;
padding: 5px 10px;
margin: 0;
border-top: 4px solid transparent;
}
div.menu > div.item:hover {
background-color: #262626;
border-top: 4px solid #009ac7;
}
/* Adjust the exact display and positions of sub-menus */
div.hmb > div.item:hover > div.vmb { /* Horizontal menu w/ vertical sub-menu */
position: absolute;
display: block;
margin-top: 5px;
margin-left: -10px;
}
div.hmb > div.item:hover > div.hmb { /* Horizontal menu w/ horizontal sub-menu */
position: absolute;
display: block;
margin-top: 5px;
}
div.vmb > div.item:hover > div.vmb { /* Vertical menu w/ vertical sub-menu */
position: absolute;
display: inline-block;
margin-left: 6px;
}
div.vmb > div.item:hover > div.hmb { /* Vertical menu w/ horizontal sub-menu */
position: absolute;
display: inline-block;
margin-left: 6px;
}
div.item:hover > div.hmb > div.item { /* Horizontal hovered menu items */
display: inline-block;
}
div.menu > div.item > a {
color: inherit;
text-decoration: none;
}
使这些菜单工作原理的关键是上面描述子菜单继承的 CSS 块。 对于水平和垂直菜单之间过渡的四种组合中的每一种,position
和 display
这两个属性控制子菜单的显示方式。 在所有情况下,我们都指定“position: absolute
”,以便子菜单从 HTML 流中移除,从而允许子菜单显示在我们想要的确切位置。该 CSS 属性设置相当普通,但 display
属性更有趣。对于水平菜单,我们总是希望子菜单显示在菜单项下方;对于垂直菜单,我们总是希望子菜单显示在菜单项右侧。由于包含的 DIV
出现在菜单项文本之后(参见下面的 HTML),我们为水平菜单项指定“display: block
”以强制子菜单出现在菜单项文本下方。类似地,对于垂直菜单项,我们指定“display: inline-block
”以允许 div
出现在菜单项文本旁边。在所有情况下,都需要对确切位置进行一些微调。通常,这是通过使用 top
/left
CSS 属性和 position: relative
来实现的。但是,在这种情况下我们不能这样做,因为如前所述,我们需要 position: absolute
来确保子菜单不会影响页面上其余 HTML 的流动,因此设置 top
/left
会将 DIV
移动到屏幕上的确切位置。 相反,我们通过设置子菜单 DIV
的 margin
CSS 属性来完成位置调整。 请注意,负边距(许多人觉得奇怪的概念)可以用于将 DIV
向相反方向移动 - 即,正的 margin-top
会将 DIV
向下移动,但负的 margin-top
会将 DIV
向上移动。
第二步是使用 DIV
和上述 CSS 中的一些类来构建您的 HTML 菜单。类是
menu
- 应将其应用于包含菜单项的任何div
hmb
/vmb
- 任何<DIV class='menu'>
都应包含hmb
(水平菜单栏)或vmb
(垂直菜单栏)。只选择一个。top
- 这个类只是强制菜单在鼠标未悬停时显示。顾名思义,这通常只在菜单的“顶部”级别使用item
- 将此类应用于包含单个菜单项的DIVs
,无论该项是否包含子菜单
有许多方法可以与菜单进行交互。一些可能性是使用 <a>
标签,通过 DIVs
上的 onclick
JavaScript 事件,或通过 JavaScript/jQuery 事件订阅。
这是生成示例图像的示例 HTML
<div class='menu top hmb'>
<div class='item'>
Item 1
<div class='menu vmb'>
<div class='item'>
Sub Item 1
<div class='menu hmb'>
<div class='item'>
Sub Sub Item 1
<div class='menu vmb'>
<div class='item'>
Level 4 - 1
<div class='menu vmb'>
<div class='item'>
Level 5 - 1
<div class='menu vmb'>
<div class='item'>Level 6 - 1</div>
<div class='item'>
Level 6 - 2
<div class='menu hmb'>
<div class='item'>Level 9 - 1</div>
<div class='item'>Level 9 - 2</div>
<div class='item'>Level 9 - 3</div>
</div>
</div>
<div class='item'>Level 6 - 3</div>
</div>
</div>
<div class='item'>Level 5 - 2</div>
<div class='item'>Level 5 - 2</div>
</div>
</div>
<div class='item'>Level 4 - 2</div>
<div class='item'>Level 4 - 3</div>
</div>
</div>
<div class='item'>Sub Sub Item 2</div>
<div class='item'>
Sub Sub Item 3
<div class='menu hmb'>
<div class='item'>Level 7 - 1</div>
<div class='item'>
Level 7 - 2
<div class='menu hmb'>
<div class='item'>Level 8 - 1</div>
<div class='item'>Level 8 - 2</div>
<div class='item'>Level 8 - 3</div>
</div>
</div>
<div class='item'>Level 7 - 3</div>
</div>
</div>
</div>
</div>
<div class='item'>Sub Item 2</div>
</div>
</div>
<div class='item'>
<a href='#'>Item 2</a>
</div>
<div class='item'>
Item 3
</div>
</div>
注意:尽管此 CSS/HTML 菜单确实支持“无限级别”,但我**不**建议过度使用。具有超过 2-3 个级别的菜单结构通常不被认为是良好的设计。
历史
- 2016-01-19 - 初始发布