响应式导航栏的下拉框效果可以让导航在桌面端展示完整菜单,在移动端通过点击触发下拉展示子菜单,纯CSS实现的方式不需要引入额外的脚本,兼容性和性能都更有保障。

一、基础HTML结构搭建
首先需要搭建导航栏的基础结构,包含主导航项和带有下拉子菜单的项,整体使用无序列表嵌套的结构,保证语义清晰。
<nav class="navbar">
<div class="nav-brand">站点名称</div>
<input type="checkbox" id="nav-toggle" class="nav-toggle">
<label for="nav-toggle" class="nav-toggle-label">菜单</label>
<ul class="nav-menu">
<li class="nav-item"><a href="#">首页</a></li>
<li class="nav-item has-dropdown">
<a href="#">产品中心</a>
<ul class="dropdown-menu">
<li><a href="#">产品A</a></li>
<li><a href="#">产品B</a></li>
<li><a href="#">产品C</a></li>
</ul>
</li>
<li class="nav-item"><a href="#">关于我们</a></li>
<li class="nav-item"><a href="#">联系我们</a></li>
</ul>
</nav>
二、桌面端基础样式设置
先设置桌面端的导航栏样式,让导航项横向排列,下拉菜单默认隐藏,通过 hover 状态触发显示。
/* 重置默认样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
a {
text-decoration: none;
color: #333;
}
ul {
list-style: none;
}
/* 导航栏容器样式 */
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
height: 60px;
background-color: #f8f9fa;
border-bottom: 1px solid #e7e7e7;
}
/* 品牌区域样式 */
.nav-brand {
font-size: 20px;
font-weight: bold;
}
/* 菜单项样式 */
.nav-menu {
display: flex;
gap: 30px;
}
.nav-item {
position: relative;
line-height: 60px;
}
.nav-item a {
padding: 10px 0;
font-size: 16px;
}
/* 下拉菜单默认隐藏 */
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
width: 160px;
background-color: #fff;
border: 1px solid #e7e7e7;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
display: none;
z-index: 100;
}
.dropdown-menu li {
line-height: 40px;
padding: 0 15px;
}
.dropdown-menu li a {
font-size: 14px;
}
/* 桌面端 hover 触发下拉显示 */
.has-dropdown:hover .dropdown-menu {
display: block;
}
/* 隐藏移动端切换按钮 */
.nav-toggle, .nav-toggle-label {
display: none;
}
三、移动端响应式适配
当屏幕宽度小于768px时,切换到移动端布局,隐藏默认菜单,通过点击切换按钮控制菜单和下拉框的显示。
/* 移动端适配断点 */
@media screen and (max-width: 768px) {
/* 显示切换按钮 */
.nav-toggle-label {
display: block;
font-size: 16px;
cursor: pointer;
padding: 5px 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
/* 隐藏复选框 */
.nav-toggle {
display: none;
}
/* 菜单默认隐藏 */
.nav-menu {
display: none;
position: absolute;
top: 60px;
left: 0;
width: 100%;
flex-direction: column;
background-color: #f8f9fa;
padding: 10px 20px;
border-top: 1px solid #e7e7e7;
gap: 0;
}
/* 选中切换按钮时显示菜单 */
.nav-toggle:checked ~ .nav-menu {
display: flex;
}
/* 导航项垂直排列 */
.nav-item {
line-height: 45px;
border-bottom: 1px solid #eee;
}
.nav-item:last-child {
border-bottom: none;
}
/* 下拉菜单样式调整 */
.dropdown-menu {
position: static;
width: 100%;
border: none;
box-shadow: none;
background-color: transparent;
padding-left: 20px;
display: none;
}
.dropdown-menu li {
padding: 0;
line-height: 40px;
}
/* 下拉切换逻辑:通过相邻选择器控制显示 */
.has-dropdown > a {
display: block;
position: relative;
}
/* 添加下拉箭头指示 */
.has-dropdown > a::after {
content: "▼";
font-size: 12px;
margin-left: 5px;
transition: transform 0.3s;
}
/* 点击导航项切换下拉显示 */
.has-dropdown:focus-within .dropdown-menu {
display: block;
}
.has-dropdown:focus-within > a::after {
transform: rotate(180deg);
}
}
四、实现要点说明
整个实现过程的核心逻辑分为几个部分:
- 使用
checkbox伪类或者focus-within伪类来替代JavaScript的点击事件,实现状态切换 - 桌面端通过
:hover伪类触发下拉显示,移动端通过:focus-within或者复选框选中状态控制显示 - 响应式断点使用
@media查询,在不同屏幕宽度下切换布局模式 - 下拉菜单使用绝对定位脱离文档流,避免影响其他元素的布局
五、兼容性说明
上述实现方式兼容所有现代浏览器,如果需要兼容更低版本的IE浏览器,可以将focus-within相关的逻辑替换为复选框控制下拉显示的方式,避免伪类兼容性问题。整体实现没有使用任何JavaScript代码,加载速度更快,也减少了脚本冲突的可能性。