在网页开发中,夜间模式已经成为提升用户体验的重要功能,搜索框作为页面高频交互组件,其夜间模式样式的适配需要兼顾视觉效果和交互逻辑。实现搜索框夜间模式的核心思路是通过CSS变量定义不同模式的颜色值,再结合JavaScript切换全局模式类名,让搜索框跟随整体模式变化调整样式。
基础HTML结构搭建
首先我们需要搭建搜索框的基础HTML结构,使用语义化的<input>标签和配套的搜索按钮,结构如下:
<div class="search_container"> <input type="text" class="search_input" placeholder="请输入搜索内容" /> <button class="search_btn">搜索</button> </div> <button class="mode_toggle">切换夜间模式</button>
定义CSS颜色变量与基础样式
使用CSS自定义属性(变量)来定义日间和夜间模式的颜色值,这样后续修改颜色只需要调整变量值即可,不需要逐个修改样式。首先在<:root>中定义日间模式的变量,再给夜间模式的根类名定义对应的变量:
/* 日间模式变量 */
:root {
--bg_color: #ffffff;
--text_color: #333333;
--input_bg: #f5f5f5;
--input_border: #dddddd;
--btn_bg: #4a90e2;
--btn_text: #ffffff;
}
/* 夜间模式变量 */
.dark_mode {
--bg_color: #1a1a1a;
--text_color: #e0e0e0;
--input_bg: #2d2d2d;
--input_border: #444444;
--btn_bg: #6a9fd8;
--btn_text: #ffffff;
}
/* 全局基础样式 */
body {
background-color: var(--bg_color);
color: var(--text_color);
transition: background-color 0.3s ease, color 0.3s ease;
font-family: "Microsoft YaHei", sans-serif;
padding: 20px;
}
/* 搜索框容器样式 */
.search_container {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
/* 搜索输入框样式 */
.search_input {
flex: 1;
padding: 10px 15px;
border-radius: 8px;
border: 1px solid var(--input_border);
background-color: var(--input_bg);
color: var(--text_color);
font-size: 14px;
outline: none;
transition: all 0.3s ease;
}
.search_input:focus {
border-color: var(--btn_bg);
box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
}
/* 搜索按钮样式 */
.search_btn {
padding: 10px 20px;
border-radius: 8px;
border: none;
background-color: var(--btn_bg);
color: var(--btn_text);
font-size: 14px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.search_btn:hover {
opacity: 0.9;
}
/* 模式切换按钮样式 */
.mode_toggle {
padding: 8px 16px;
border-radius: 6px;
border: 1px solid var(--input_border);
background-color: var(--input_bg);
color: var(--text_color);
cursor: pointer;
font-size: 14px;
}
实现模式切换逻辑
接下来通过JavaScript实现点击切换按钮时,在body上添加或移除dark_mode类名,同时保存用户的模式选择到本地存储,避免刷新页面后模式重置:
// 获取模式切换按钮
const modeToggleBtn = document.querySelector('.mode_toggle');
// 获取body元素
const bodyElement = document.body;
// 初始化模式:优先读取本地存储的模式,没有则默认日间模式
const savedMode = localStorage.getItem('page_mode');
if (savedMode === 'dark') {
bodyElement.classList.add('dark_mode');
modeToggleBtn.textContent = '切换日间模式';
} else {
bodyElement.classList.remove('dark_mode');
modeToggleBtn.textContent = '切换夜间模式';
}
// 绑定切换按钮点击事件
modeToggleBtn.addEventListener('click', function() {
// 切换dark_mode类名
bodyElement.classList.toggle('dark_mode');
// 判断当前是否为夜间模式
const isDarkMode = bodyElement.classList.contains('dark_mode');
if (isDarkMode) {
// 保存夜间模式到本地存储
localStorage.setItem('page_mode', 'dark');
modeToggleBtn.textContent = '切换日间模式';
} else {
// 保存日间模式到本地存储
localStorage.setItem('page_mode', 'light');
modeToggleBtn.textContent = '切换夜间模式';
}
});
适配系统偏好设置
很多用户会在系统层面设置深色模式偏好,我们可以结合prefers-color-scheme媒体查询,在用户首次访问时自动匹配系统偏好,提升体验:
/* 如果用户没有手动设置过模式,匹配系统偏好 */
@media (prefers-color-scheme: dark) {
body:not(.light_mode_set) {
class: dark_mode;
}
}
对应的JavaScript需要补充逻辑,当用户手动切换过模式后,标记已经设置过偏好,避免被系统偏好覆盖:
// 切换模式时标记用户已经手动设置过
modeToggleBtn.addEventListener('click', function() {
bodyElement.classList.toggle('dark_mode');
const isDarkMode = bodyElement.classList.contains('dark_mode');
localStorage.setItem('page_mode', isDarkMode ? 'dark' : 'light');
// 添加标记类,避免被系统偏好覆盖
bodyElement.classList.add('light_mode_set');
modeToggleBtn.textContent = isDarkMode ? '切换日间模式' : '切换夜间模式';
});
// 初始化时如果用户没有存储过模式,添加标记类
if (!localStorage.getItem('page_mode')) {
bodyElement.classList.add('light_mode_set');
}
注意事项
- 颜色变量的命名要清晰,方便后续维护,所有和颜色相关的样式都尽量使用变量,不要写死颜色值
- 过渡动画的时间建议设置在0.2s到0.3s之间,过长会显得拖沓,过短则没有平滑效果
- 搜索框的placeholder颜色也需要适配夜间模式,可以通过
::placeholder伪类设置,使用对应的变量值 - 如果页面有多个搜索框,只需要统一使用相同的CSS变量,切换模式时所有搜索框都会自动适配