一步到位:三行CSS代码轻松实现全网站暗黑模式

本文首发于微信公众号:大迁世界, 我的微信:qq449245884,我会第一时间和你分享前端行业趋势,学习途径等等。
更多开源作品请看 GitHub https://github.com/qq449245884/xiaozhi ,包含一线大厂面试完整考点、资料以及我的系列文章。

快来免费体验ChatGpt plus版本的,我们出的钱
体验地址:https://chat.waixingyun.cn
可以加入网站底部技术群,一起找bug.

本文由 Mads Stoumann 撰写的博文,主要介绍了如何通过简单的三行CSS代码实现网站的暗黑模式。该博文提到,<system-color>关键字一般反映用户、浏览器或操作系统做出的默认颜色选择。这些关键字通常用于浏览器的默认样式表。通过这种方式,我们可以轻松地实现网站的暗黑模式。

在另一篇博文中,Mads Stoumann详细介绍了如何使用SVG和CSS重新创建Apple的暗黑模式图标。这证明了他在此领域的深厚技术和创新能力。

总的来说,这个网站提供了许多关于使用CSS和SVG进行网站设计和开发的有用信息,特别是关于暗黑模式的实现。这对那些希望在自己的网站上实现暗黑模式的开发者来说是非常有价值的资源。

下面是正文~~

深色模式是一种设计趋势,网站的配色方案被更改为深色背景,配以浅色文字和元素。它也被称为夜间模式或黑暗主题。深色模式的目的是减少低光环境下的眼睛疲劳,节省移动设备的电池寿命,并创造一个时尚现代的美感。

许多热门网站和应用程序现在都提供了黑暗模式选项 —— 如 TailwindCSS:

image.png

如果您是开发者,您很可能已经知道如何在开发者工具中切换暗黑模式:

image.png

如果你想要为操作系统(以及所有支持暗黑模式的应用程序)切换暗黑模式,请转到系统设置。在Mac上,可以在系统设置>外观下找到它:

image.png

使用系统颜色的深色模式

首先,我们将创建一个带有标题的简单HTML:

<body>
  <h1>Hello Darkness, My Old Friend</h1>
</body>

在样式表中,添加:

body {
  color-scheme: light dark;
}

这会告诉浏览器,document 可以接受亮色和暗色的 color-scheme

当前如果现在指定为 dark 浏览器也不会变成黑色。

image.png

这是因为 user-agent 样式表没有设置任何默认颜色。我们可以通过使用系统颜色快速解决这个问题:

body {
  background-color: Canvas;
  color: CanvasText;
  color-scheme: light dark;
}

image.png

仅用3行CSS代码就能为我们的整个网站实现暗黑模式!

下面,我们更深入地了解系统颜色,来自规范:

一般来说,<system-color>关键字反映了用户、浏览器或操作系统做出的默认颜色选择。由于这个原因,它们通常在浏览器默认样式表中使用。

这是一个浅色模式演示,在Safari中展示了可用的系统颜色:

image.png

如果我们切换到深色模式,某些颜色会完全改变(就像我们已经遇到的 CanvasCanvasText ),而其他颜色只会稍微改变:

image.png

使用系统颜色进行黑暗模式是一种简化的黑暗模式体验。是的,它会起作用 — 但是纯黑白有点无聊

我们可以在CSS中使用 color-mix 来增加趣味性 将 CanvasText (黑色或白色)混入 Canvas (白色或黑色)以获得 background-color ,反之亦然,用于 color

body {
  background-color: color-mix(in srgb, Canvas, CanvasText 2.5%);
  color: color-mix(in srgb, CanvasText, Canvas 15%);
}

这样看起来会更柔和:

image.png

从颜色中减去饱和度,是在深色模式中制作颜色变化的一种广泛使用的方法。

在CSS中使用相对颜色,我们可以做到这一点:

background: hsl(from ActiveText h calc(s - 30%) l);

不幸的是,相对颜色在任何浏览器中都不能与系统颜色一起工作。

注意:系统颜色可以被强制颜色覆盖(尽管很少使用)——所以不要过分依赖这种技术。

我们继续学习另一种技巧,这将使我们能够精细控制我们的暗黑模式颜色。

使用 prefers-color-scheme 媒体查询

要为亮色和暗色模式指定特定颜色,我建议使用 CSS 自定义属性,然后使用 prefers-color-scheme 媒体查询更新这些属性。

以浅色模式为默认,我们将颜色添加到 :where(body) -部分,将它们与我们的常规 body -样式分开:

/* Properties */
:where(body) {
  --background-color: #FFF;
  --text-color: #222;
}
body {
  background-color: var(--background-color);
  color: var(--text-color);
}

然后,对于暗黑模式,我们将简单地更新这些颜色属性:

@media (prefers-color-scheme: dark) {
  :where(body) {
    --background-color: hsl(228, 5%, 15%);
    --text-color: hsl(228, 5%, 80%);
  }
}

image.png

但是,如果我们希望用户根据自己的需求选择我们网站的版本,而不是根据系统设置呢?

他们可能更喜欢将系统设置为深色模式,但我们的网站是浅色模式。让我们创建一个切换器!如果您访问像 TailwindCSS 这样的网站,您会注意到当您从 color-scheme-toggler 中选择“dark”时,会在 html -节点上添加一个 dark -类。这是通过 JavaScript 完成的:

创建颜色方案切换器

如果你用过 TailwindCSS ,你会注意到当你从 color-scheme-toggler 中选择“dark”时,会在 html -节点上添加一个 dark -类。这是通过 JavaScript 完成的:

window.matchMedia('(prefers-color-scheme: dark)').matches)) {
  document.documentElement.classList.add('dark')
} else {
  document.documentElement.classList.remove('dark')
}

Open Props 正在使用类似的方法,但是更新 data-theme 属性,然后在两个块中定义属性:

[data-theme=light] {
  --nav-icon: var(--gray-7); /* etc */
}
[data-theme=dark] {
  --nav-icon: var(--gray-5); /* etc */
}

使用 Css

使用一些全新的CSS技术,我们可以在不使用JavaScript的情况下创建一个切换器。我们将创建一个具有3种状态的切换器:

  • Light (forced)
  • Auto (system default, could be either light or dark)
  • Dark (forced)

首先,一些基本标记:

<fieldset>
  <label>
    <input type="radio" name="color-scheme" id="color-scheme-light" value="0">
    Light
  </label>
  <label>
    <input type="radio" name="color-scheme" value="auto" checked>
    Auto
  </label>
  <label>
    <input type="radio" name="color-scheme" id="color-scheme-dark" value="1">
    Dark
  </label>
</fieldset>

在添加了一些基本样式后(请参阅下面的Codepen演示),它的呈现效果如下:

image.png

我们将在html元素中添加一个 --darkmode -属性和 container-type

html {
  --darkmode: 0;
  container-name: root;
  container-type: normal;
}

我们使用 @container style() -查询,因此我们需要将节点设置为“container”。

既然我们不想观察到 inline-size 变化,我们只需添加值 normal 。

如果用户选择了一个“强制”值,我们将更新 --darkmode :

html:has(#color-scheme-light:checked) { --darkmode: 0; }
html:has(#color-scheme-dark:checked) { --darkmode: 1; }

最后,我们将使用容器 style() -查询来检查,如果 --darkmode 设置为 1 :

@container root style(--darkmode: 1) {
  body {
    --background-color: hsl(228, 5%, 15%);
    --text-color: hsl(228, 5%, 80%);
  }
}

注意: @container style() -queries 目前仅在 Chrome 中的 behind-a-flag 下工作,这还是初期阶段,所以不要在生产环境中使用。

现在,在选择“Dark”之后,我们的切换器(和页面)看起来是这样的:

image.png

存储状态

如果我们想要存储用户的选择,就需要一点JavaScript!

首先,为 <fieldset> 添加一个标识符:

<fieldset id="colorScheme">

接下来,在JavaScript中:

const colorScheme = document.getElementById('colorScheme')
colorScheme.addEventListener('change', event => {
  localStorage.setItem('color-scheme', event.target.value)
})

现在,我们只需要在文档加载后将属性设置为 localStorage -值:

window.addEventListener("load", event => {
  const scheme = localStorage.getItem('color-scheme') || 'auto'
  if (scheme) {
    document.documentElement.style.setProperty('--darkmode', scheme)
  }
})

要在切换器中选择正确的模式,请将此添加到 if -块:

const selected = [...colorScheme.elements].filter(element => element.value === scheme)
if (selected) selected[0].checked = true;

Toggler

事例:https://codepen.io/stoumann/pen/KKGNbQr

System Colors

https://codepen.io/stoumann/pen/GRYNPzy

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

交流

有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@大迁世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值