纯HTML + CSS 基础下拉菜单(最常用)
这是最经典、最常用的实现方式,不依赖任何JavaScript,纯靠CSS的 hover 伪类来触发下拉菜单的显示。

(图片来源网络,侵删)
特点:
- 优点:代码简单,性能好,对SEO友好。
- 缺点:在触屏设备(如手机、平板)上无法通过
hover触发,需要额外配合JavaScript或使用其他交互方式。
代码实现:
HTML 结构
<nav class="navbar">
<ul class="nav-menu">
<li><a href="#">首页</a></li>
<li class="dropdown">
<a href="#">产品服务 <i class="fas fa-chevron-down"></i></a>
<ul class="dropdown-menu">
<li><a href="#">Web开发</a></li>
<li><a href="#">移动应用</a></li>
<li><a href="#">UI/UX设计</a></li>
<li><a href="#">咨询服务</a></li>
</ul>
</li>
<li><a href="#">关于我们</a></li>
<li><a href="#">联系方式</a></li>
</ul>
</nav>
<nav>: 导航栏的容器。<ul>: 无序列表,作为菜单的容器。<li class="dropdown">: 这是一个特殊的列表项,它包含了下拉菜单,给它添加dropdown类是为了方便CSS选择器定位。<a href="#">: 菜单项的链接。<ul class="dropdown-menu">: 这是下拉菜单本身,默认是隐藏的。<i class="fas fa-chevron-down">: 这是一个图标(需要引入 Font Awesome 库),用于提示用户这里有下拉内容。
CSS 样式
/* 基础样式,美化整个导航栏 */
.navbar {
background-color: #333;
padding: 0;
}
.nav-menu {
list-style: none; /* 移除列表前的点 */
margin: 0;
padding: 0;
display: flex; /* 使用Flexbox布局,让菜单项水平排列 */
}
.nav-menu li {
position: relative; /* 关键:为下拉菜单定位提供参考 */
}
.nav-menu li a {
display: block; /* 让链接可以填充整个li */
color: white;
text-decoration: none;
padding: 15px 20px;
transition: background-color 0.3s ease;
}
.nav-menu li a:hover {
background-color: #555;
}
/* --- 下拉菜单的核心样式 --- */
/* 1. 默认状态下隐藏下拉菜单 */
.dropdown-menu {
position: absolute; /* 关键:将下拉菜单从文档流中脱离,相对于.dropdown定位 */
top: 100%; /* 定位在父级li的下方 */
left: 0;
background-color: #444;
min-width: 160px;
box-shadow: 0 8px 16px rgba(0,0,0,0.2);
z-index: 1000; /* 确保下拉菜单显示在其他内容之上 */
/* 默认隐藏 */
display: none;
}
/* 2. 当鼠标悬停在.dropdown上时,显示下拉菜单 */
.dropdown:hover .dropdown-menu {
display: block;
}
/* 下拉菜单中的链接样式 */
.dropdown-menu li a {
color: white;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-menu li a:hover {
background-color: #666;
}
如何使用图标
为了让下拉箭头图标显示,您需要在 <head> 中引入 Font Awesome:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
带有多级下拉菜单
这个方案在方案一的基础上,增加了二级甚至三级下拉菜单,非常适合复杂的网站导航。

(图片来源网络,侵删)
代码实现:
HTML 结构
在方案一的基础上,只需在 dropdown-menu 中再嵌套一个 dropdown 即可。
<nav class="navbar">
<ul class="nav-menu">
<li><a href="#">首页</a></li>
<li class="dropdown">
<a href="#">产品服务 <i class="fas fa-chevron-down"></i></a>
<ul class="dropdown-menu">
<li><a href="#">Web开发</a></li>
<li><a href="#">移动应用</a></li>
<li class="dropdown"> <!-- 二级下拉菜单 -->
<a href="#">设计服务 <i class="fas fa-chevron-right"></i></a> <!-- 使用右箭头表示有子菜单 -->
<ul class="dropdown-menu">
<li><a href="#">UI设计</a></li>
<li><a href="#">UX研究</a></li>
<li><a href="#">品牌设计</a></li>
</ul>
</li>
<li><a href="#">咨询服务</a></li>
</ul>
</li>
<li><a href="#">关于我们</a></li>
<li><a href="#">联系方式</a></li>
</ul>
</nav>
CSS 样式
在方案一的CSS基础上,增加针对二级下拉菜单的样式,核心思想是调整 top 和 left 的值。
/* ... (方案一的所有CSS保持不变) ... */
/* --- 多级下拉菜单的新增样式 --- */
/* 调整二级下拉菜单的位置,让它出现在一级菜单的右侧 */
.dropdown-menu .dropdown-menu {
top: 0; /* 从顶部开始 */
left: 100%; /* 定位在父级菜单的右侧 */
}
/* 当鼠标悬停在二级菜单的父级上时,显示二级菜单 */
.dropdown-menu .dropdown:hover .dropdown-menu {
display: block;
}
/* 二级菜单的箭头图标向右 */
.dropdown-menu .dropdown > a > i {
float: right; /* 将图标向对齐 */
}
使用 JavaScript 实现的下拉菜单(适合触屏设备)
为了在触屏设备上也能正常工作,我们需要使用JavaScript来监听点击事件,而不是 hover。
特点:
- 优点:兼容性好,能在桌面和移动设备上工作。
- 缺点:需要额外的JavaScript代码。
代码实现:
HTML 结构 HTML结构可以和方案一一样,但为了更好的可访问性,我们通常会添加一个按钮来触发下拉菜单(尤其是在移动端)。
<nav class="navbar">
<ul class="nav-menu">
<li><a href="#">首页</a></li>
<li class="dropdown">
<!-- 给触发链接添加一个类名,方便JS选择 -->
<a href="#" class="dropdown-toggle">产品服务 <i class="fas fa-chevron-down"></i></a>
<ul class="dropdown-menu">
<li><a href="#">Web开发</a></li>
<li><a href="#">移动应用</a></li>
<li><a href="#">UI/UX设计</a></li>
<li><a href="#">咨询服务</a></li>
</ul>
</li>
<li><a href="#">关于我们</a></li>
<li><a href="#">联系方式</a></li>
</ul>
</nav>
CSS 样式
CSS和方案一基本一样,但要去掉 hover 的样式,并给 .dropdown-menu 设置一个默认的 display: none;。
/* ... (方案一的所有CSS) ... */
/* 删除 .dropdown:hover .dropdown-menu { display: block; } 这一行 */
/* 确保.dropdown-menu默认是隐藏的 */
.dropdown-menu {
/* ... 其他样式 ... */
display: none;
}
JavaScript 代码
document.addEventListener('DOMContentLoaded', function() {
// 获取所有带有 'dropdown-toggle' 类的链接
const dropdownToggles = document.querySelectorAll('.dropdown-toggle');
dropdownToggles.forEach(toggle => {
toggle.addEventListener('click', function(e) {
e.preventDefault(); // 阻止链接的默认跳转行为
// 找到当前点击的链接的兄弟元素,也就是下拉菜单
const dropdownMenu = this.nextElementSibling;
// 切换下拉菜单的显示和隐藏
// 使用 classList.toggle 是最简单的方式
dropdownMenu.classList.toggle('show');
});
});
// 可选:点击页面其他地方时关闭下拉菜单
document.addEventListener('click', function(event) {
// 如果点击的不是下拉菜单的触发器或菜单本身
if (!event.target.matches('.dropdown-toggle') && !event.target.closest('.dropdown-menu')) {
// 关闭所有显示的下拉菜单
const dropdowns = document.querySelectorAll('.dropdown-menu.show');
dropdowns.forEach(dropdown => {
dropdown.classList.remove('show');
});
}
});
});
新增的CSS类
为了让JavaScript的 classList.toggle('show') 生效,需要在CSS中定义 .show 类:
.dropdown-menu.show {
display: block;
}
总结与选择建议
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 方案一 (纯CSS) | 代码少、性能好、SEO友好 | 触屏设备不兼容 | 纯展示型网站、博客、后台管理系统(主要在桌面端使用) |
| 方案二 (多级CSS) | 结构清晰,层级丰富 | 同样有触屏设备不兼容问题 | 复杂的企业官网、大型电商平台导航 |
| 方案三 (JavaScript) | 兼容所有设备,交互灵活 | 代码稍复杂,需要引入JS | 现代响应式网站,需要同时支持桌面和移动端 |
对于大多数现代网站,推荐使用 方案一 作为基础,然后通过 媒体查询 在小屏幕设备上隐藏 hover 触发的下拉菜单,并切换为类似 方案三 的点击触发模式,这样可以兼顾性能和兼容性。
