如何用:checked伪类实现纯CSS带动画的侧边导航面板切换?
问题分析与解决方案
你的核心问题是CSS选择器层级关系错误:#toggle复选框位于#menu容器内部,而.site-navigation是header的直接子元素,和#menu是同级关系,并非#toggle的兄弟元素。你使用的~兄弟选择器只能选中同一父级下的后续兄弟,因此#toggle:checked~.site-navigation无法匹配到导航面板,导致切换功能失效。
修正方案(两种可选)
方案1:调整HTML结构,让复选框与导航面板同级
将#toggle从#menu容器中移出,放到和.site-navigation同一父级(即header下),使兄弟选择器能够正常工作。
修正后的HTML
<header id="masthead" class="site-header" role="banner"> <!-- 把复选框移至此处,与nav同级 --> <input type="checkbox" id="toggle"> <div class="container"> <div id="brand"> <h1 class="site-title"><a href="#">Nice site</a></h1> </div> <div id="menu"> <label class="toggle-btn toggle-btn__cross" for="toggle"> <div class="bar"></div> <div class="bar"></div> <div class="bar"></div> </label> </div> <div class="clear"></div> </div> <!--/container --> <!-- .site-navigation .main-navigation --> <nav role="navigation" id="navigation" class="site-navigation main-navigation"> <span class="menuLabel">menu</span> <ul> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">News</a></li> <li><a href="#">Contact</a></li> </ul> </nav> </header>
修正后的CSS(仅调整选择器部分)
/* 现在兄弟选择器可正常匹配导航面板 */ #toggle:checked~.site-navigation { opacity: 1; visibility: visible; } #toggle { display: none; } /* 调整汉堡按钮的选择器路径,适配新结构 */ #toggle:checked ~ .container #menu .toggle-btn .bar { background-color: #efefef; } #toggle:checked ~ .container #menu .toggle-btn .bar:nth-child(2) { opacity: 0; } #toggle:checked ~ .container #menu .toggle-btn .bar:nth-child(1) { transform: translateY(10px) rotate(45deg); } #toggle:checked ~ .container #menu .toggle-btn .bar:nth-child(3) { transform: translateY(-8px) rotate(-45deg); } /* 补充导航菜单的基础过渡状态,让动画更流畅 */ .site-navigation ul { position: relative; top: 0; transition: top 0.3s ease; } .site-navigation ul li { transform: translateY(20px); opacity: 0; transition: all 0.3s ease; } #toggle:checked~.site-navigation ul { top: 70px; } #toggle:checked~.site-navigation ul li { transform: translateY(0px); opacity: 1; } /* 保留原有基础样式 */ .site-navigation { z-index: 99; background-color: rgba(0, 0, 0, 0.8); position: fixed; top: 0; left: 0; width: 40%; height: 100%; opacity: 0; visibility: hidden; transition: all 0.3s ease-in-out; } .toggle-btn { display: block; position: fixed; z-index: 10; right: 10px; top: 10px; cursor: pointer; } .toggle-btn .bar { width: 30px; height: 2px; margin: 7px auto; background-color: #fff; transition: all 0.3s ease-in-out; box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.3); } .toggle-btn .bar:nth-child(2) { width: 28px; }
方案2:使用CSS :has()选择器(无需调整HTML)
如果不想修改HTML结构,可以使用:has()选择器,让#menu容器在复选框被选中时,选中其兄弟元素.site-navigation。注意:has()目前在现代浏览器中支持良好(Chrome 101+、Firefox 121+)。
修正后的CSS关键部分
/* 替换原有的#toggle:checked~.site-navigation */ #menu:has(#toggle:checked) ~ .site-navigation { opacity: 1; visibility: visible; } #menu:has(#toggle:checked) ~ .site-navigation ul { top: 70px; } #menu:has(#toggle:checked) ~ .site-navigation ul li { transform: translateY(0px); opacity: 1; } /* 汉堡按钮的样式保留原有逻辑,因为#toggle与label是直接兄弟 */ #toggle:checked+label.toggle-btn .bar { background-color: #efefef; } #toggle:checked+label.toggle-btn .bar:nth-child(2) { opacity: 0; } #toggle:checked+label.toggle-btn .bar:nth-child(1) { transform: translateY(10px) rotate(45deg); } #toggle:checked+label.toggle-btn .bar:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }
额外优化建议
- 可以将
.site-navigation的opacity和visibility替换为transform: translateX(-100%),实现侧边滑入的动画效果,视觉体验更好:
.site-navigation { /* 替换原有opacity和visibility */ transform: translateX(-100%); transition: transform 0.3s ease-in-out; } #toggle:checked~.site-navigation { transform: translateX(0); }
内容的提问来源于stack exchange,提问作者WITI
相关产品推荐
相关产品推荐

