
效果如下:
一、为什么要做 “双态导航”
二、HTML 结构:BEM 命名法
<header class="header">
<div class="header__container">
<!-- Logo -->
<div class="header__logo">
<a href="/" class="header__logo-link">
<img src="/skin/img/logo-white.png"
alt="理想艺术"
class="header__logo-img"
data-black="/skin/img/logo-black.png">
</a>
</div>
<!-- 导航菜单 -->
<nav class="header__nav">
<a href="/" class="header__nav-link header__nav-link--active">首页</a>
<a href="/about/" class="header__nav-link">关于我们</a>
<a href="/school/" class="header__nav-link">理想校园</a>
<a href="/teacher/" class="header__nav-link">师资介绍</a>
<a href="/course/" class="header__nav-link">专业课程</a>
<a href="/news/" class="header__nav-link">新闻动态</a>
<a href="/enroll/" class="header__nav-link">在线报名</a>
<a href="/contact/" class="header__nav-link">联系我们</a>
</nav>
<!-- 搜索框 -->
<div class="header__search">
<form method="get" action="/search.html">
<input type="text" name="keywords" placeholder="搜索" class="header__search-input">
<button type="submit">
<i class="fas fa-search header__search-icon"></i>
</button>
<input type="hidden" name="method" value="1" />
<input type="hidden" name="type" value="all" />
</form>
</div>
</div>
</header>
结构清晰,三级:
Block:header — 整个导航块
Element:header__container、header__logo、header__nav、header__search
Modifier:header__nav-link–active — 当前页高亮
三、CSS 实现:双态切换的核心
/* ===== 基础样式:顶部透明红底背景图 + 渐变遮罩 */
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
height: 80px;
display: flex;
align-items: center;
background-color: #c00000;
background-image:
linear-gradient(135deg,
rgba(26,26,46,0.35) 0%,
rgba(177,11,24,0.25) 50%,
rgba(192,0,0,0.35) 100%),
url('/skin/img/header-bg.jpg');
background-size: cover;
background-position: center;
transition: background-color 0.3s ease,
box-shadow 0.3s ease,
background-image 0.3s ease;
}
/* ===== 滚动后白底 */
.header.scrolled {
background-image: none;
background-color: #fff;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}
/* 给 body 顶部留空,防止 fixed 定位不遮挡内容 */
body { padding-top: 80px; }
导航链接的双态文字颜色:
.header__nav-link {
color: #fff;
font-size: 16px;
font-weight: 500;
position: relative;
transition: color 0.3s ease;
}
/* 滚动后文字变深灰 */
.header.scrolled .header__nav-link { color: #333; }
/* active / hover 下划线效果 */
.header__nav-link::after {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: 0;
height: 2px;
background-color: #fff;
transition: width 0.3s ease;
}
.header__nav-link--active::after {
width: 100%;
background-color: #fff;
}
.header.scrolled .header__nav-link--active::after {
background-color: #a30000;
}
关键技巧:通过 .header.scrolled 作为「开关状态切换所有子元素颜色的状态。切换只需加一行 JS 加一个类,所有子元素的颜色、背景、边框全部联动。
搜索框的双态
.header__search-input {
width: 140px;
height: 36px;
border: 1px solid rgba(255,255,255,0.3);
border-radius: 18px;
background: rgba(255,255,255,0.1);
color: #fff;
outline: none;
transition: all 0.3s ease;
}
.header__search-input::placeholder {
color: rgba(255,255,255,0.6);
}
/* 滚动后白底 */
.header.scrolled .header__search-input {
border-color: #e0e0e0;
background: #f5f5f5;
color: #333;
}
.header.scrolled .header__search-input::placeholder {
color: #999;
}
/* 聚焦时展开 */
.header__search-input:focus {
width: 180px;
border-color: #a30000;
}
四、JavaScript:滚动切换逻辑
(function() {
'use strict';
const headerEl = document.querySelector('.header');
if (!headerEl) return;
/* 1. Logo 黑白切换(data-black 属性存黑色 Logo 地址
const logoImg = headerEl.querySelector('.header__logo-img');
if (logoImg && logoImg.dataset && logoImg.dataset.black) {
const whiteSrc = logoImg.src;
const blackSrc = logoImg.dataset.black;
function updateLogo() {
logoImg.src = window.scrollY > 80 ? blackSrc : whiteSrc;
}
window.addEventListener('scroll', updateLogo, { passive: true });
updateLogo();
}
/* 2. Header 滚动样式切换 */
function updateHeaderScroll() {
if (window.scrollY > 80) {
headerEl.classList.add('scrolled');
headerEl.classList.remove('transparent');
} else {
headerEl.classList.remove('scrolled');
headerEl.classList.add('transparent');
}
}
window.addEventListener('scroll', updateHeaderScroll, { passive: true });
updateHeaderScroll();
/* 3. 搜索框交互 */
const searchIcon = headerEl.querySelector('.header__search-icon');
const searchInput = headerEl.querySelector('.header__search-input');
if (searchIcon && searchInput) {
searchIcon.addEventListener('click', function(e) {
e.stopPropagation();
searchInput.focus();
});
searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Enter' && this.value.trim()) {
window.location.href = '/search.html?keyword=' + encodeURIComponent(this.value.trim());
}
});
document.addEventListener('click', function(e) {
if (searchInput.value && !e.target.closest('.header__search')) {
searchInput.value = '';
}
});
}
})();
五、核心亮点
1. 数据驱动的 Logo 切换
用 data-black 属性存黑色 Logo 地址,HTML 写一行代码就能实现黑白 Logo 切换,JS 代码不用改 JS,换个图片地址就行。
2. 单一状态类控制所有子元素
只用一个 .scrolled 类,配合 CSS 后代选择器联动所有子元素的颜色、背景、边框。维护成本极低,新增元素只需在 CSS 里加一行即可。
3. passive: hover
滚动监听使用 passive: true,提升滚动性能,避免页面卡顿。
4. 搜索框的微交互
聚焦时输入框宽度从 140px → 180px 展开,给用户明确的输入反馈。点击外部自动清空,保持页面干净。
5. 全站一致的过渡动画
所有颜色、背景、阴影都加了 transition: 0.3s ease,切换平滑过渡,不会有生硬的 “跳变” 感。
如果你的网站首屏视觉冲击力较强,不妨试试这种「透明→白底」的双态导航,既能提升品牌调性又不影响可用性。
