macOS、Windows 10 等现代操作系统允许用户选择他们希望在所有应用程序中看到的外观。
以下屏幕截图取自 macOS 的常规设置:
可以通过查看媒体查询 @media
的属性 prefers-color-scheme
来检测该选项。
它可以是以下值之一:
light
— 用户希望以浅色模式查看页面dark
— 用户希望在暗黑模式下查看页面no-preference
— 系统不知道用户的偏好
通过检查此媒体查询值,我们可以确定用户是否喜欢暗模式,获取系统是否处于暗模式下有两种方式。
- 使用 CSS 媒体查询检测 CSS 中的首选配色方案:
/* Light mode */
@media (prefers-color-scheme: light) {
body {
filter: invert(0);
}
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
body {
filter: invert(1) hue-rotate(180deg);
}
}
- 使用
matchMedia
方法检测 JS 中的首选配色方案:
const isDarkMode =
window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
或者也许是更通用的方法:
const checkType = (type) =>
window.matchMedia &&
window.matchMedia(`(prefers-color-scheme: ${type})`).matches
const mode = {
is: {
dark: checkType('dark'),
light: checkType('light')
}
}
mode.is.dark // true
mode.is.light // false
另外,如果用户在页面打开时更改首选项配色,我们可以使用 addListener
方法(不要与 addEventListener
混淆)监听系统颜色的切换,来动态更改颜色。
例如:
window.matchMedia('(prefers-color-scheme: dark)').addListener((e) => {
const isDarkMode = e.matches
console.log(`${isDarkMode ? '🌚' : '🌞'}.`)
})
强制设置暗模式:
const forceDarkMode = () =>
[...document.styleSheets[0].rules].forEach((rule) => {
const mediaText = (rule.media && rule.media.mediaText) || []
const hasColorScheme = mediaText.includes('prefers-color-scheme')
const hasLightScheme = hasColorScheme && mediaText.includes('light')
// 如果需要,请删除亮模式。
if (hasLightScheme) {
rule.media.deleteMedium('(prefers-color-scheme: light)')
}
// 添加暗模式
rule.media && rule.media.appendMedium('(prefers-color-scheme: dark)')
})