无需SCSS实现带响应式设计的粘性导航栏方案问询
嘿,太懂你这种看上了酷炫导航效果但不想碰没学过的SCSS的心情了!我给你整理了纯CSS+原生JS的实现方案,完全不用预处理器,还附了更优的优化思路,一步步来:
纯原生实现可折叠+上滑显示/下滑隐藏的顶部导航
一、基础功能实现(固定+小屏幕折叠+滚动交互)
先上完整的代码,都是原生的,你可以直接复制测试:
HTML结构
<header class="navbar"> <div class="navbar-container"> <a href="#" class="logo">MySite</a> <button class="menu-toggle" id="menuToggle" aria-expanded="false" aria-label="切换导航菜单">☰</button> <nav class="nav-links" id="navLinks"> <a href="#home">首页</a> <a href="#about">关于</a> <a href="#services">服务</a> <a href="#contact">联系</a> </nav> </div> </header> <main> <div class="content-block">滚动测试内容1</div> <div class="content-block">滚动测试内容2</div> <div class="content-block">滚动测试内容3</div> <div class="content-block">滚动测试内容4</div> </main>
纯CSS样式(无SCSS)
* { margin: 0; padding: 0; box-sizing: border-box; } /* 导航栏基础样式 */ .navbar { position: fixed; top: 0; width: 100%; background-color: #2c3e50; color: white; padding: 1rem 0; transition: top 0.3s ease; /* 给滚动交互加平滑过渡 */ z-index: 1000; /* 确保导航栏在最上层 */ } .navbar-container { max-width: 1200px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center; padding: 0 1rem; } .logo { color: white; text-decoration: none; font-size: 1.5rem; font-weight: bold; } /* 桌面端导航链接 */ .nav-links { display: flex; gap: 2rem; } .nav-links a { color: white; text-decoration: none; transition: color 0.3s; } .nav-links a:hover { color: #3498db; } /* 小屏幕菜单按钮 */ .menu-toggle { display: none; background: none; border: none; color: white; font-size: 1.5rem; cursor: pointer; } /* 小屏幕适配断点 */ @media (max-width: 768px) { .menu-toggle { display: block; } .nav-links { position: absolute; top: 100%; left: 0; width: 100%; background-color: #2c3e50; flex-direction: column; padding: 1rem; gap: 1rem; max-height: 0; overflow: hidden; transition: max-height 0.3s ease; } /* 激活状态显示菜单 */ .nav-links.active { max-height: 300px; /* 足够容纳所有链接的高度,可按需调整 */ } } /* 页面内容样式,避免被固定导航遮挡 */ main { margin-top: 60px; /* 和导航栏高度匹配,后续可优化为动态计算 */ } .content-block { height: 400px; padding: 2rem; border-bottom: 1px solid #eee; }
原生JS交互逻辑
// 1. 小屏幕折叠菜单功能 const menuToggle = document.getElementById('menuToggle'); const navLinks = document.getElementById('navLinks'); menuToggle.addEventListener('click', () => { const isActive = navLinks.classList.toggle('active'); // 更新无障碍属性,适配屏幕阅读器 menuToggle.setAttribute('aria-expanded', isActive); }); // 点击导航链接后自动关闭折叠菜单(小屏幕下) document.querySelectorAll('.nav-links a').forEach(link => { link.addEventListener('click', () => { navLinks.classList.remove('active'); menuToggle.setAttribute('aria-expanded', false); }); }); // 2. 上滑显示、下滑隐藏导航栏功能 let lastScrollTop = 0; const navbar = document.querySelector('.navbar'); window.addEventListener('scroll', () => { // 用requestAnimationFrame优化性能,减少重排重绘 requestAnimationFrame(() => { const scrollTop = window.pageYOffset || document.documentElement.scrollTop; // 过滤小幅度滚动,避免频繁触发 if (Math.abs(scrollTop - lastScrollTop) > 10) { if (scrollTop > lastScrollTop) { // 下滑时隐藏导航栏 navbar.style.top = '-100%'; } else { // 上滑时显示导航栏 navbar.style.top = '0'; } lastScrollTop = scrollTop; } }); });
二、更优实现思路
- 性能优化:滚动事件是高频触发事件,用
requestAnimationFrame包裹处理逻辑能让浏览器在重绘前执行代码,减少不必要的性能损耗。 - 无障碍支持:给菜单按钮添加
aria-expanded和aria-label属性,让屏幕阅读器用户也能正常使用导航功能,这是专业前端开发的必备细节。 - 动态高度适配:如果导航栏的内容或高度可能变化,不要硬写
main的margin-top,可以用JS动态计算导航栏高度并设置:
const navbarHeight = navbar.offsetHeight; document.querySelector('main').style.paddingTop = `${navbarHeight}px`;
- 响应式断点优化:不要局限于768px的固定断点,改用
em或rem作为单位,能更好地适配不同字体大小的设备;也可以根据实际设计需求调整断点值。 - 状态记忆:如果需要,还可以用
localStorage记录用户最后一次打开菜单的状态,刷新页面后保持一致,提升用户体验。
这样下来,你不用碰SCSS也能实现完全符合需求的导航栏,代码都是原生的,容易理解和修改~
内容的提问来源于stack exchange,提问作者Zap
相关产品推荐
相关产品推荐

