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

news2024/12/23 23:58:02

本文首发于微信公众号:大迁世界, 我的微信: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 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/531469.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode_多源 BFS_中等_994.腐烂的橘子

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b;值 1 代表新鲜橘子&#xff1b;值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子周…

给定二叉树的先序遍历有多少种可能的二叉树

title: 给定二叉树的先序遍历有多少种可能的二叉树 date: 2023-05-16 11:42:26 tags: 数据结构与算法 给定二叉树的先序遍历有多少种可能的二叉树 **问题&#xff1a;**给定二叉树的先序遍历有多少种可能的二叉树 git地址&#xff1a;https://github.com/944613709/HIT-Data-St…

使用python进行图片的文字识别

使用python进行图片的文字识别 文章目录 使用python进行图片的文字识别安装 Tesseract OCR安装过程配置系统的环境变量 安装python的第三方库Pytesseract库Pillow库 运行个demo 安装 Tesseract OCR Tesseract OCR 是一款由 Google 团队开发的开源 OCR&#xff08;Optical Chara…

港联证券|新能源大金融双主线发力 沪指探低回升收复3300点

周一&#xff0c;A股三大指数呈现宽幅震荡走势。沉寂许久的新能源板块早盘复苏&#xff0c;保险、券商与部分“中字头”股票午后发力&#xff0c;多主线并进带动市场普涨。截至收盘&#xff0c;上证综指报3310.74点&#xff0c;涨1.17%&#xff1b;深证成指报11178.62点&#x…

【网络】数据通信的桥梁

最近很长一段时间没有更新博客了&#xff0c;不是因为说要放弃了&#xff0c;中间断断续续的在写&#xff0c;但是都是草稿&#xff0c;没发出来&#xff0c;感觉写的不太好&#xff0c;对这些内容也没什么热情&#xff0c;今天重拾键盘&#xff0c;写一篇基础的文章&#xff0…

英雄马系列赛|众翼电气·2023铜鼓半马圆满落幕,每一步都是风景

长寿铜鼓 康养胜地&#xff01;5月14日&#xff0c;众翼电气2023铜鼓半程马拉松暨英雄马系列赛&#xff08;铜鼓站&#xff09;在山清水秀的宜春铜鼓鸣枪起跑&#xff0c;2500多名参赛跑友奔跑在绿意盎然的人间桃花源&#xff0c;感受了长寿铜鼓的卓越风姿。本赛事由中共铜鼓县…

小程序点击导航栏返回顶部小例子

<view class"headerTop" id"headerTop" click"onNavigationBarTap">顶部导航栏 </view> //样式 width: 100%; position: fixed; background: white; left: 0; z-index: 999;//jslastTapTime: null,//用于记录上一次点击的时间戳scr…

swing_树_JTree概述

JTree、TreeModel实现树 树也是图形用户界面中使用非常广泛的GUI组件&#xff0c;在Windows资源管理器中&#xff0c;将我们所看到的目录称为树&#xff1a; 计算机世界里的树是由一系列具有严格父子关系的结点组成的&#xff0c;每个结点既可以是上一级结点的子结点&#xff…

【HMS Core】Health Kit如何获取跑步锻炼记录的轨迹记录?

【问题描述】 使用接口&#xff0c;"/healthkit/v1/activityRecords"&#xff0c;可以正常获取跑步记录&#xff0c;但是里面没有附带轨迹数据&#xff0c;应该怎么获取每条记录的轨迹记录数据呢&#xff1f; 【解决方案】 1、获取锻炼记录的轨迹记录需要关联GPS详…

创业像是驾驶轮船,我们唯一可以做的就是掌好舵

一直拥有领先的认知是很难的&#xff0c;我们唯一可以做的是保持开放的心态&#xff0c;并主动获取新信息&#xff0c;从而不断地促进认知升级。 三年前&#xff0c;神策数据公众号曾发文《桑文锋&#xff1a;创业这五年》&#xff0c;传递了创始人 & CEO 桑文锋对创业的观…

【FMC136】AD9467之4通道 250MSPS 采样率16位AD 采集子卡模块得设计原理图中文资料

板卡概述 FMC136 是一款4 通道250MHz 采样率16 位AD 采集FMC子卡&#xff0c;符合VITA57 规范&#xff0c;可以作为一个理想的IO 模块耦合至FPGA前端&#xff0c;4 通道AD 通过高带宽的FMC 连接器&#xff08;HPC&#xff09;连接至FPGA 从 而大大降低了系统信号延迟。该板卡支…

Golang中函数的使用

目录 函数 函数特点 函数的使用 函数定义 函数的参数 函数的返回值 函数的变量作用域 函数的递归调用 函数的可变参数 函数的闭包 函数的 defer 语句 注意 函数 函数调用&#xff1a;函数调用时需要传递函数定义中要求的参数&#xff0c;并根据需要接收返回值。 …

专享策略05 | MACD波段套利交易策略

量化策略开发&#xff0c;高质量社群&#xff0c;交易思路分享等相关内容 大家好&#xff0c;2023俱乐部有4个专享&#xff0c;6个通用。其中专享是2个套利&#xff0c;1个盘口&#xff0c;1个CTA。本期是专享05策略&#xff0c;本年度第二个套利策略。 01、策略介绍 策略以MA…

CH32V3xx RT-Thread Nano调试记录

目录 1、工程创建2、代码修改与调试2.1 RT-Thread 配置2.2 打印串口修改2.3 测试验证1、工程创建 使用MounRiver集成开发环境可以直接创建带有RT-Thread Nano的工程,步骤如下: 打开MounRiver,点击新建MounRiver工程; 在模板类型处选择RT-Thread,然后选择使用的芯片型号,…

UNeXt:基于MLP的快速医学图像分割网络

文章目录 UNeXt: MLP-Based Rapid Medical Image Segmentation Network摘要本文方法Shifted MLPTokenized MLP Stage 实验结果 UNeXt: MLP-Based Rapid Medical Image Segmentation Network 摘要 UNeXt&#xff1a;一种基于卷积多层感知器&#xff08;MLP&#xff09;的图像分…

【 WebSocket 框架 】

文章目录 一、背景介绍二、原理解析三、代码示例四、效果验证 一、背景介绍 WebSocket 是从 HTML5 开始支持的一种网页端和服务端保持长连接的 消息推送机制 理解消息推送: 传统的 web 程序, 都是属于 “一问一答” 的形式. 客户端给服务器发送了一个 HTTP 请求, 服务器给客户…

数据类型、python数字、数据类型转换、字符串

1、python的数据类型 可以使用type&#xff08;&#xff09;函数获取任何对象的数据类型 x 10 print(type(x)) # 打印<class int> 2、python 数字 Int 或整数是完整的数字&#xff0c;正数或负数&#xff0c;没有小数&#xff0c;长度不限。 浮动或“浮点数”是…

JavaScript全解析——express

express 的基本使用 ●express 是什么? ○是一个 node 的第三方开发框架 ■把启动服务器包括操作的一系列内容进行的完整的封装 ■在使用之前, 需要下载第三方 ■指令: npm install express 1.基本搭建 // 0. 下载: npm install express// 0. 导入 const express express()…

DNF命令介绍

DNF命令介绍 DNF是新一代的rpm软件包管理器。他首先出现在 Fedora 18 这个发行版中。而最近&#xff0c;它取代了yum&#xff0c;正式成为 Fedora 22 的包管理器。 1. 安装DNF包管理器 yum -y install dnf2. 命令介绍

MQTT 5协议中的基础更改(二)

上期文章中给大家介绍了MQTT规范版本5中基础更改的信息和CONNACK返回码&#xff0c;本篇文章我们继续介绍MQTT5协议中的基础更改中其他新功能的细节描述。 01 干净启动 MQTT 3.1.1的其中一个主流功能是MQTT客户端使用清除会话&#xff08;cleanSession&#xff09;&#xff0…