写点什么

基于 Web 组件,手把手教你搭建黑暗主题

  • 2019-10-15
  • 本文字数:9288 字

    阅读完需:约 30 分钟

基于Web组件,手把手教你搭建黑暗主题


我们绕了一圈后,又回到了黑暗模式。从黑暗模式到浅色模式,绕了一大圈然后又回到了黑暗模式。在个人电脑时代的早期,黑暗模式是唯一的选择。单色 CRT 计算机显示器的工作原理是将电子束发射到荧光屏上。早期 CRT 中使用的荧光粉是绿色的,导致文本显示为绿色,而屏幕的其余部分显示为黑色。这些模式通常被称为绿色屏幕



图片来自 wikimedia


随着后来彩色 CRT 的引入,显示器通过使用红、绿、蓝三色荧光粉可以显示多种颜色。白色是通过同时激活所有三种荧光粉而产生的。现在我们又回到了黑暗主题,因为它让人的眼睛更舒服,并且从主观审美上让人更愉悦。


我非常喜欢 web 组件,它们让 web 开发变成了面向组件开发的方式,我很喜欢这种方式。下面就让我们仅使用 web 组件构建一个切换黑暗和浅色主题的小程序。


“面向组件的编程将是未来的趋势。"——Indrek Lasn


Web 组件是许多不同技术的组合,它允许您创建可重用的自定义元素(其封装的功能可与您的其他代码隔离开来),并在 web 应用程序中使用这些元素。如果您不太了解 web 组件是什么,请查看“Web组件的概要”。

开始

我们只需要一个 web 浏览器和一个文本编辑器就够了。然后创建 index.html 文件。如果您正在使用emmet,您可以直接输入!,然后点击 tab 键。这将为您显示出 index.html 的样例代码。


<!DOCTYPE html>  <html lang="en">  <head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <meta http-equiv="X-UA-Compatible" content="ie=edge">    <title>Toggle</title>  </head>  <body>      </body>  </html>
复制代码

元素

多亏了开源代码,我们已经有了一个方便的组件来满足我们的需求。它被称为dark-mode-toggle——我们可以通过 CDN 包含该组件,或者将之视为 NPM 软件包安装。



以下组件是一个自定义元素,使您可以轻松地将一个黑暗模式切换开关放在您的网站上,您一开始可以使用prefers-color-scheme读取用户设置的偏好,但也允许用户选择性地只在这个网页上覆盖系统设置,并且这种单独设置可以是永久生效的。


被称为prefers-color-scheme的媒体特性用于检测用户的页面请求所要求的是浅色主题还是黑暗主题。它有以下三个值。


  • no-preference:表示用户没有向浏览器显示任何首选项。此关键字值在布尔上下文中计算为 false。

  • light:表示用户已经告知浏览器,他们更喜欢浅色主题的页面(浅色背景上的深色文本)。

  • dark:表示用户已经告知浏览器,他们更喜欢黑暗主题的页面(深色背景上的浅色文本)。


将以下代码放到 index.html 的部分:


<!DOCTYPE html>  <html lang="en">      <head>        <link rel="stylesheet" href="common.css" />        <link          rel="stylesheet"          href="light.css"          media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"        />        <link          rel="stylesheet"          href="dark.css"          media="(prefers-color-scheme: dark)"        />        <script          type="module"          src="https://googlechromelabs.github.io/dark-mode-toggle/src/dark-mode-toggle.mjs"        ></script>  

<meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Toggle</title> </head> <body> </body> </html>
复制代码


自定义元素假设您已经将 CSS 组织到不同的文件中,浏览器会根据样式表相应的 link 元素中的 media 属性有条件地加载这些文件。以下样式表被命名为 common.css、light.css 和 dark.css——注意每个主题是怎样具有自己的封装样式的。继续创建这三个样式表。


touch common.css light.css dark.css
复制代码



这是一个很好的高性能模式,因为浏览器会遵循人们当前的主题偏好,而不会强制人们下载他们不需要的 CSS,虽然不匹配的样式表仍然会被加载,但是不会在关键的渲染通道上争夺带宽资源。


接下来,将元素添加到 index.html 中。


<aside>    <dark-mode-toggle      id="dark-mode-toggle"      legend="Theme Switcher"      light="Light"      dark="Dark"      appearance="switch"      permanent="false"    ></dark-mode-toggle>  </aside>
复制代码


添加 dark-mode-toggle 元素


到了这一步,我们还应该添加一些内容。毕竟,我们想要看到并测试我们的结果。下面是我们现在的 index.html 文件的样子:


<!DOCTYPE html>  <html lang="en">    <head>      <link rel="stylesheet" href="common.css" />      <link        rel="stylesheet"        href="light.css"        media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"      />      <link        rel="stylesheet"        href="dark.css"        media="(prefers-color-scheme: dark)"      />      <script        type="module"        src="https://googlechromelabs.github.io/dark-mode-toggle/src/dark-mode-toggle.mjs"      ></script>  

<meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Toggle</title> </head> <body> <aside> <dark-mode-toggle id="dark-mode-toggle" legend="Theme Switcher" light="Light" dark="Dark" appearance="switch" permanent="false" ></dark-mode-toggle> </aside>

<main> <h1>Hi there!</h1> <p> Lorem ipsum dolor sit amet, legere ancillae ne vis. Ne vim laudem accusam consectetuer, eu utinam integre abhorreant sea. Quo eius veri ei. </p> <form id="content"> <fieldset> <legend>Lorem ipsum</legend> <div> <select> <option>Lorem</option> <option>Ipsum</option> </select> </div> <div> <button type="button">Lorem</button> </div> <div> <input type="text" value="Lorem ipsum" /> </div> <div> <input type="search" value="Lorem ipsum" /> </div> <div> <label><input checked type="checkbox" /> Lorem</label> <label><input type="checkbox" /> Ipsum</label> </div> <div> <label><input checked name="foo" type="radio" /> Lorem</label> <label><input name="foo" type="radio" /> Ipsum</label> </div> </fieldset> </form> </main> </body> </html>
复制代码


最后,我们需要声明黑暗和浅色主题的样式。请从下面的代码片段中获取样式。

common.css

这些样式在黑暗和浅色主题之间可以复用。


:root {    color-scheme: dark light; /* stylelint-disable-line property-no-unknown */    --heading-color: red;    --duration: 0.5s;    --timing: ease;  }  

*, ::before, ::after { box-sizing: border-box; }

body { margin: 0; transition: color var(--duration) var(--timing), background-color var(--duration) var(--timing); font-family: sans-serif; font-size: 12pt; background-color: var(--background-color); color: var(--text-color); display: flex; justify-content: center; }

main { margin: 1rem; max-width: 30rem; position: relative; }

h1 { color: var(--heading-color); text-shadow: 0.1rem 0.1rem 0.1rem var(--shadow-color); transition: text-shadow var(--duration) var(--timing); }

img { max-width: 100%; height: auto; transition: filter var(--duration) var(--timing); }

p { line-height: 1.5; word-wrap: break-word; overflow-wrap: break-word; hyphens: auto; }

fieldset { border: solid 0.1rem; box-shadow: 0.1rem 0.1rem 0.1rem var(--shadow-color); transition: box-shadow var(--duration) var(--timing); }

div { padding: 0.5rem; }

aside { position: absolute; right: 0; padding: 0.5rem; }

aside:nth-of-type(1) { top: 0; }

aside:nth-of-type(2) { top: 3rem; }

aside:nth-of-type(3) { top: 7rem; }

aside:nth-of-type(4) { top: 12rem; }

#content select, #content button, #content input[type="text"], #content input[type="search"] { width: 15rem; }

dark-mode-toggle { --dark-mode-toggle-remember-font: 0.75rem "Helvetica"; --dark-mode-toggle-legend-font: bold 0.85rem "Helvetica"; --dark-mode-toggle-label-font: 0.85rem "Helvetica"; --dark-mode-toggle-color: var(--text-color); --dark-mode-toggle-background-color: none;

margin-bottom: 1.5rem; }

#dark-mode-toggle { --dark-mode-toggle-dark-icon: url("moon.png"); --dark-mode-toggle-light-icon: url("sun.png"); --dark-mode-toggle-icon-size: 1rem; --dark-mode-toggle-icon-filter: invert(100%); }
复制代码


注意 color-scheme 属性。color-scheme 属性仍在开发中,可能还没有得到完全支持。Chrome 将在 2019 年底对其提供全面支持。

dark.css

这些是我们黑暗主题的样式。


:root {    --background-color: rgb(40, 44, 53);    --text-color: rgb(240, 240, 240);  }  

.icon { filter: invert(100%); }

/* 如果不存在黑暗模式用户agent,那就模拟它 */ select, input, button, option { color: var(--text-color); background-color: var(--background-color); border-width: 1px; border-radius: 1px; }

/* Else, use the user agent stylesheet */ @media (prefers-color-scheme: dark) { select, input, button, option { color: unset; background-color: unset; } }
复制代码


dark.css

light.css

最后是浅色主题的样式。


:root {    --background-color: rgb(240, 240, 240);    --text-color: rgb(15, 15, 15);  }
复制代码


在浏览器中打开 index.html 文件。您可以在本地打开它,也可以启动一个现成的 HTTP 服务器。在我的例子中,我将使用内置的 Python 服务器来打开它。


$ python -m SimpleHTTPServer
复制代码



启动我们的 Python 服务器


现在,如果我们打开浏览器并输入 localhost:8000——我们应该会看到以下内容:



继续点击右上角的主题切换按钮。



太酷了!这招很管用。您可以在GitHub代码库中找到所有的图片资源。


如果您是 JavaScript 新手,而且想要学习这门语言,我建议您从阅读书籍开始,边学边构建代码。从“学习JavaScript的更聪明方法”这本书开始,这里有一个有趣的应用程序列表


谢谢您的阅读,我希望您学到了一些东西。继续加油!


原文链接:


How to Build Light and Dark Themes With Web Components


2019-10-15 15:282186
用户头像

发布了 61 篇内容, 共 26.5 次阅读, 收获喜欢 135 次。

关注

评论

发布
暂无评论
发现更多内容

制造业工厂使用生产管理MES系统前后区别

万界星空科技

数字化转型 制造业 mes 万界星空科技

PostgreSQL技术内幕(十四)探索PG的进程与内存管理

酷克数据HashData

《重构:改善既有代码的设计(第2版)》PDF

程序员李木子

XML 简介及用法详解

小万哥

xml 程序人生 编程语言 软件工程 前端开发

华为云开年采购季Web及移动App上云体验,助力软件行业创新发展

轶天下事

2023 亚马逊云科技 re:lnvent 大会探秘: Amazon Connect 全渠道云联络中心

亚马逊云科技 (Amazon Web Services)

掌握Python库的Bokeh,就能让你的交互炫目可视化

华为云开发者联盟

Python 开发 数据可视化 华为云 华为云开发者联盟

MediaBox音视频终端SDK已适配鸿蒙星河版(HarmonyOS NEXT)

阿里云CloudImagine

云计算 低代码 sdk

NOT IN子查询中出现NULL值对结果的影响你注意到了吗

GreatSQL

怎么用ai创作ppt?办公必备的自动生成PPT软件!

彭宏豪95

人工智能 PPT 在线白板 AIGC AI生成PPT

电源常用电路—驱动电路详解

芯动大师

芯片 驱动 电源

阿里通义灵码全面公测,来看看它的水平怎么样?

阿里云云效

阿里云 云原生 云效

越影视觉,让AI看见这世界的繁花

脑极体

AI

从testcafe迁到playwright你需要注意什么?

QE_LAB

自动化 TestCafe 测试框架 playwright

技术分享 | Selenium多浏览器处理

霍格沃兹测试开发学社

20年后的人工智能会发展到什么程度,如何融入到普通人的生活中?

算法的秘密

C++语言现在还有人学吗?

小齐写代码

掌握 Kubernetes 故障排除技巧:kubectl命令的基本指南

SEAL安全

Kubernetes 云原生 kubectl

从0带你设计与实现基于STM32的智慧农业管理系统

华为云开发者联盟

开发 华为云 stm32 华为云开发者联盟 智慧农业管理系统

什么是数字化工厂?数字化工厂的整体架构是什么?

万界星空科技

数字化 mes 数字化工厂 万界星空科技

为什么说 Scroll 上的 PenPad,有望在本轮牛市行情中胜出?

石头财经

市场广泛看好的LaunchPad 平台 PenPad,有望在牛市胜出

BlockChain先知

AI会取代低代码吗?——探讨两者在软件开发中的角色和关系

天津汇柏科技有限公司

低代码开发 人工智能、

京东五星门店小程序性能优化实践

京东零售技术

taro 性能优化 前端

如何高效接入 Flink: Connecter / Catalog API 核心设计与社区进展

Apache Flink

机器学习 大数据 flink

技术分享 | 网页 frame 与多窗口处理

霍格沃兹测试开发学社

基于Web组件,手把手教你搭建黑暗主题_语言 & 开发_Indrek Lasn_InfoQ精选文章