【QCon】精华内容上线92%,全面覆盖“人工智能+”的典型案例!>>> 了解详情
写点什么

基于 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:281894
用户头像

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

关注

评论

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

Codepoint for mac(图形字符开发工具)v1.14激活版

iMac小白

关于AI智能生成(AIGC),整理一下你该知道这些

Geek_ee6d52

人工智能 AIGC

千分位分隔?一个vue指令搞定

JYeontu

Vue 前端 vue指令 vue组件

企业财务规划的未来:自动化智能化如何推动全面预算管理

智达方通

自动化 智能化 全面预算管理 财务管理 财务自动化

如何做代币分析:以 INJ 币为例

Footprint Analytics

blockchain Token

淘宝京东1688...等电商平台商品详情数据,淘宝京东1688商品详情 API 返回值说明

Anzexi58

API 文档

「外部参数」功能已上线,爷们儿速来体验!!

都广科技

DevOps

MySQL学习笔记

秃头小帅oi

Navicat Charts Viewer for Mac(Navicat图表查看器) v1.2.16激活版

iMac小白

Navicat Charts Creator for Mac(Navicat图表创建器)v1.2.16激活版

iMac小白

如何通过ETL实现快速同步美团订单信息

RestCloud

美团 数据同步 ETL 数据集成 订单同步

开发苹果iOS应用后如何提交到App Store

雪奈椰子

实现一个简单的哈希映射功能

JYeontu

JavaScript 前端 哈希表 算法、

低代码与MES的结合--万界星空科技低代码平台

万界星空科技

低代码 低代码平台 mes 制造业生产管理系统 万界星空科技

NFTScan | 02.26~03.03 NFT 市场热点汇总

NFT Research

NFT NFTScan nft工具

Navicat for SQLite 16 for Mac(强大数据库管理及开发工具)v16.3.6中文版

iMac小白

一键生成个性化二维码:打造你的专属数字名片

JYeontu

JavaScript 前端 npm 插件 Node

使用 Footprint Analytics 提升 Web3 项目的空投活动

Footprint Analytics

blockchain

想做大模型开发前,先来了解一下MoE

华为云开发者联盟

人工智能 华为云 大模型 华为云开发者联盟

函数防抖?一个vue指令搞定

JYeontu

Vue 前端 vue指令 Vue组件库

Bridge 2024 for Mac(BR)v14.0.2激活版

iMac小白

参与DevData调研,共建国内首份研发效能基准线,免费获得“体检报告”!

思码逸研发效能

火山引擎ByteHouse:如何用OLAP为抖音精准推荐提效

Geek_2d6073

INFINI Labs 产品更新 | Easysearch 1.7.1发布

极限实验室

console Gateway easysearch

Adobe Photoshop 2024 v25.5最新中文破解版 附安装教程

iMac小白

装配制造业的MES系统中的物料齐套技术

万界星空科技

制造业 生产管理系统 mes 万界星空科技 装配行业

【技术探讨】如何选择一款距离远的无线通信模块?

Geek_ab1536

GraphicConverter 12 for Mac(图片浏览器)v12.1.1(6440)中文激活版

iMac小白

DRmare Tidal Music Converter Mac(一体式Tidal音乐转换器)v2.14.0直装版

影影绰绰一往直前

软件测试学习笔记丨SQL操作命令(库操作、表操作、表数据操作)

测试人

软件测试

漫画算法——二叉查找树的删除

梦倚栏杆

二叉树 删除 查找算法

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