如何使用Web组件构建明暗主题

在明暗主题之间切换从未如此简单

在明暗主题之间切换

我们已经完成了黑暗模式。从暗模式到亮模式再到暗模式。在个人计算的曙光中,黑暗模式是唯一的选择。单色CRT计算机监视器通过将电子束发射到磷光屏幕上来工作。早期CRT中使用的荧光粉是绿色的,导致文本显示为绿色,而屏幕的其余部分为黑色。这些模型通常被称为绿屏

随后引入彩色CRT,通过使用红色,绿色和蓝色荧光粉可以显示多种颜色。通过同时激活所有三种磷光体来产生白色。现在我们已经回归到黑暗的主题,因为它更容易在眼睛上,并且在主观上,更美观。

我是Web组件的忠实粉丝,并喜欢他们如何使Web开发面向组件。让我们仅使用Web组件构建一个黑暗和明亮的主题切换。

“面向组件的编程将成为未来。” - Indrek Lasn

Web组件是一套不同的技术,允许您创建可重用的自定义元素 - 将其功能与其他代码封装在一起 - 并在Web应用程序中使用它们。如果你不确定Web组件,检查出“ w ^ 一言以蔽之EB组件 ”。


入门

我们所需要的只是一个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>

每个Web应用程序构建块, **index.html**

<dark-mode-toggle> 元件

感谢开源代码,我们已经为我们的需求提供了一个便利的组件。它被称为[dark-mode-toggle](https://github.com/GoogleChromeLabs/dark-mode-toggle)- 我们可以通过CDN包含组件或将其安装为NPM包。


暗模式切换 - https://github.com/GoogleChromeLabs/dark-mode-toggle

以下组件是一个自定义元素,允许您轻松地在您的网站上放置暗模式🌒切换,因此您最初可以根据用户的喜好[prefers-color-scheme](https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme),但也允许他们(可选地永久地)覆盖他们的系统设置你的网站。

[prefers-color-scheme](https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme)媒体功能用于检测用户是否已经请求的页面使用浅色或深色的主题。它具有以下三个值。

  • no-preference:表示用户未使浏览器知道任何首选项。此关键字值的计算方式false布尔上下文相同
  • light:表示用户已通知浏览器他们更喜欢具有浅色主题的页面(浅色背景上的深色文本)。
  • dark:表示用户已通知浏览器他们更喜欢具有深色主题的页面(深色背景上的浅色文本)。

将以下代码放在以下<head>部分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组织在不同的文件中,这些文件是根据media样式表的相应link元素中的属性有条件加载的。以下样式表被命名common.csslight.css并且dark.css- 注意每个主题如何具有自己的封装样式。继续创建三个样式表。

touch common.css light.css dark.css

这是一个很棒的性能模式,因为你不强迫人们根据他们当前的主题偏好下载他们不需要的CSS,但是不匹配的样式表仍然会被加载但是不会在关键渲染路径中争夺带宽。

接下来,将<dark-mode-toggle>元素添加到我们的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>

添加暗模式切换元素

虽然我们在那里,但我们也要添加一些内容。毕竟,我们希望看到并测试我们的结果。以下是我们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>

index.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%);
}

common.css

注意该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%);
}

/* If no dark mode user agent stylesheet exists, emulate it */
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);
}

light.css

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

$ python -m SimpleHTTPServer

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

继续,然后单击右上角的主题切换器按钮。

切换主题

真棒!它就像一个魅力。您可以在此处找到GitHub存储库中的所有图像资源。

感谢阅读,我希望你学到了一两件事。保持好状况!

翻译自:https://medium.com/better-programming/how-to-build-dark-and-light-theme-with-web-components-a63ca1570bfe

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容