随着黑暗模式(Dark Mode)在现代操作系统和浏览器中的普及,为网站添加黑暗模式支持已成为提升用户体验的重要环节。本文将详细介绍如何使用CSS/SCSS媒体查询规范地实现黑暗模式,并提供正反面的代码示例。
1. 基础媒体查询语法
正确示例
scss
// 使用prefers-color-scheme媒体查询
@media (prefers-color-scheme: dark) {
body {
background-color: #121212;
color: #e0e0e0;
}
a {
color: #bb86fc;
}
}
@media (prefers-color-scheme: light) {
body {
background-color: #ffffff;
color: #333333;
}
a {
color: #6200ee;
}
}
错误示例
scss
// 错误:使用不规范的媒体查询条件
@media screen and (dark-mode: enabled) {
/* 这种写法不被标准支持 */
}
// 错误:直接覆盖而不考虑用户偏好
body {
background-color: #121212; /* 强制使用暗色,不考虑用户偏好 */
}
2. SCSS中的最佳实践
正确示例
scss
// 定义颜色变量
$light-bg: #ffffff;
$light-text: #333333;
$light-link: #6200ee;
$dark-bg: #121212;
$dark-text: #e0e0e0;
$dark-link: #bb86fc;
// 基础样式(默认/回退样式)
body {
background-color: $light-bg;
color: $light-text;
a {
color: $light-link;
}
}
// 黑暗模式覆盖
@media (prefers-color-scheme: dark) {
body {
background-color: $dark-bg;
color: $dark-text;
a {
color: $dark-link;
}
}
}
错误示例
scss
// 错误:变量命名不清晰
$color1: #fff;
$color2: #000;
// 错误:嵌套过深导致难以维护
@media (prefers-color-scheme: dark) {
body {
div {
section {
/* 过于复杂的嵌套 */
}
}
}
}
3. 处理图片和SVG
正确示例
scss
.logo {
// 默认浅色模式logo
background-image: url('logo-light.svg');
@media (prefers-color-scheme: dark) {
// 黑暗模式使用反色logo
background-image: url('logo-dark.svg');
}
}
// 或者使用CSS滤镜
.dark-image {
@media (prefers-color-scheme: dark) {
filter: invert(1) hue-rotate(180deg);
}
}
错误示例
scss
// 错误:硬编码图片路径,难以维护
@media (prefers-color-scheme: dark) {
.header {
background-image: url('/images/backgrounds/dark/header-bg.jpg');
/* 路径结构过于具体,难以修改 */
}
}
// 错误:过度使用滤镜影响性能
@media (prefers-color-scheme: dark) {
* {
filter: invert(1); /* 全局应用滤镜会严重影响性能 */
}
}
4. 与自定义主题切换结合
正确示例
scss
// 首先检查是否有本地存储的主题偏好
body {
// 默认主题
--bg-color: #ffffff;
--text-color: #333333;
--accent-color: #6200ee;
background-color: var(--bg-color);
color: var(--text-color);
// 然后检查系统偏好
@media (prefers-color-scheme: dark) {
--bg-color: #121212;
--text-color: #e0e0e0;
--accent-color: #bb86fc;
}
// 用户手动选择黑暗模式
&.dark-theme {
--bg-color: #121212;
--text-color: #e0e0e0;
--accent-color: #bb86fc;
}
// 用户手动选择浅色模式
&.light-theme {
--bg-color: #ffffff;
--text-color: #333333;
--accent-color: #6200ee;
}
}
错误示例
scss
// 错误:媒体查询和类选择器优先级混乱
@media (prefers-color-scheme: dark) {
body.dark-theme {
/* 这种组合可能导致意外行为 */
}
}
// 错误:过度使用!important
body.dark-theme {
background-color: #121212 !important; /* 避免使用!important */
}
5. 过渡动画增强体验
正确示例
scss
// 添加平滑的颜色过渡
body {
transition: background-color 0.3s ease, color 0.3s ease;
a {
transition: color 0.3s ease;
}
}
// 注意:在初始加载时禁用过渡以避免闪烁
body.no-transition,
body.no-transition * {
transition: none !important;
}
错误示例
scss
// 错误:过渡时间过长
body {
transition: all 2s ease; /* 2秒过渡时间太长 */
}
// 错误:过渡属性过于宽泛
* {
transition: all 0.3s ease; /* 影响所有属性,性能不佳 */
}
6. 测试和回退策略
正确示例
scss
// 使用@supports检查媒体查询支持
@supports not (prefers-color-scheme: dark) {
// 为不支持媒体查询的浏览器提供回退
body {
background-color: $light-bg;
color: $light-text;
}
}
// 或者使用JavaScript检测并添加回退类
// <script>
// if (!window.matchMedia('(prefers-color-scheme)').matches) {
// document.body.classList.add('no-prefers-color-scheme');
// }
// </script>
错误示例
scss
// 错误:假设所有浏览器都支持
@media (prefers-color-scheme: dark) {
/* 没有考虑不支持的情况 */
}
// 错误:复杂的浏览器嗅探
@-moz-document url-prefix() {
/* 特定浏览器hack,不推荐 */
}
结论
实现黑暗模式时,应遵循以下规范:
- 使用标准的
prefers-color-scheme
媒体查询 - 在SCSS中合理组织变量和嵌套
- 提供适当的过渡动画增强用户体验
- 考虑与自定义主题切换的兼容性
- 为不支持媒体查询的浏览器提供回退方案
- 避免性能陷阱和过于复杂的嵌套
通过遵循这些规范,可以创建出既美观又易于维护的黑暗模式实现,为用户提供更加舒适和个性化的浏览体验。