为我的副项目 www.fediverse.to 添加光明模式和黑暗模式是一次有趣的旅程。我特别喜欢整个过程的直观性。 prefers-color-scheme CSS 属性包含用户的配色方案——光明或黑暗。然后我为两种模式定义 SASS 或 CSS 样式,浏览器会应用用户想要的样式。就是这样!从操作系统到浏览器再到网站的无缝流程对用户和开发者来说都是巨大的胜利。
在摆弄了 www.fediverse.to 后,我也决定为这个网站添加光明模式和黑暗模式。我首先在互联网上研究了如何最好地处理这个问题。这个 GitHub 线程 显示了该功能的当前进展。而 这个深入的 POC 演示了该过程可能有多么具有挑战性。
挑战
最大的挑战是有时 SASS 和 CSS 不能很好地协同工作。
让我解释一下。
从我之前关于光明和黑暗主题的文章来看,要创建这两种样式,我需要像这样定义 CSS
/* Light mode */
:root {
--body-bg: #FFFFFF;
--body-color: #000000;
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
:root {
--body-bg: #000000;
--body-color: #FFFFFF;
}
}
这很简单。定义样式后,我们在 CSS 中使用 var(--body-bg) 和 var(--body-color)。颜色会根据 prefers-color-scheme 的值进行切换。
Bootstrap 5 使用 Sass 定义颜色值。我网站的 _variables.scss 中的配色方案 看起来像这样
// User-defined colors
$my-link-color: #FFCCBB !default;
$my-text-color: #E2E8E4 !default;
$my-bg-color: #303C6C;
现在解决方案似乎很明显了,对吧?我可以将 prefers-color-scheme 与上面的变量结合起来,然后 boom!
// User-defined colors
:root {
--my-link-color: #FFCCBB;
--my-text-color: #E2E8E4;
--my-bg-color: #303C6C;
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
:root {
--my-link-color: #FF0000;
--my-text-color: #FFFFFF;
--my-bg-color: #000000;
}
}
此外,我需要在 _variables.scss 中将 $ 值替换为它们的 -- 变体。进行更改并运行 jekyll build 后,我得到以下结果
Conversion error: Jekyll::Converters::Scss encountered an error while converting 'css/main.scss':
Error: argument `$color2` of `mix($color1, $color2, $weight: 50%)` must be a color on line 161:11 of _sass/_functions.scss, in function `mix` from line 161:11 of _sass/_functions.scss, in function `shade-color` from line 166:27 of _sass/_functions.scss, in function `if` from line 166:11 of _sass/_functions.scss, in function `shift-color` from line 309:43 of _sass/_variables.scss from line 11:9 of _sass/bootstrap.scss from line 1:9 of stdin >> @return mix(black, $color, $weight); ----------^
Error: Error: argument `$color2` of `mix($color1, $color2, $weight: 50%)` must be a color on line 161:11 of _sass/_functions.scss, in function `mix` from line 161:11 of _sass/_functions.scss, in function `shade-color` from line 166:27 of _sass/_functions.scss, in function `if` from line 166:11 of _sass/_functions.scss, in function `shift-color` from line 309:43 of _sass/_variables.scss from line 11:9 of _sass/bootstrap.scss from line 1:9 of stdin >> @return mix(black, $color, $weight); ----------^
Error: Run jekyll build --trace for more information.
这个错误意味着 Bootstrap mixin 期望颜色值是颜色值,而不是 CSS 变量。从这里开始,深入研究 Bootstrap 代码以重写 mixin。但我必须重写大部分 Bootstrap 才能使其工作。 此页面 描述了此时可用的大多数选项。但我能够用更简单的方法来解决。
由于我不使用 Bootstrap 功能的整个套件,因此我能够通过结合 prefers-color-scheme、一些 CSS 覆盖和少量代码重复来添加光明模式和黑暗模式。
步骤 1:将演示与结构分离
在应用新样式来处理光明模式和黑暗模式之前,我对 HTML 和 CSS 进行了一些清理。
第一步是确保所有演示层的东西都在 CSS 中,而不是在 HTML 中。演示标记 (CSS) 应始终与页面结构 (HTML) 分开。但是网站的源代码会随着时间的推移变得混乱。如果您的颜色类已经分离到 CSS 中,则可以跳过此步骤。
我发现我的 HTML 代码中散布着 Bootstrap 颜色类。某些 div 和 footer 标签在 HTML 中使用了 text-light、text-dark、bg-light 和 bg-dark。由于处理光明和黑暗主题依赖于 CSS,因此必须删除颜色类。因此,我将它们全部从 HTML 移动到我的自定义 SASS 文件。
我保留了上下文颜色类(bg-primary、bg-warning、text-muted 等)。我为光明和黑暗主题选择的颜色不会干扰它们。确保您的主题颜色与上下文颜色配合良好。否则,您也应该将它们移动到 CSS 中。
到目前为止,我已在本网站上撰写了 100 多篇文章。因此,我必须扫描 _posts/
目录下的所有帖子,以查找颜色类。与上面的步骤一样,确保将所有颜色类移动到 CSS 中。不要忘记检查 Jekyll 集合 和 页面。
步骤 2:尽可能合并样式
合并和重用样式元素可确保您减少需要担心的事项。我主页上的 项目 和 精选文章 部分显示了卡片式布局。这些布局使用了自己的自定义 CSS 样式。我 重新设置了它们的样式以匹配文章链接,现在我需要担心的事情更少了。
还有其他几个元素使用了自己的样式。我选择删除它们,而不是重新设置它们的样式。
例如,页脚使用了自己的背景颜色。这将需要两种不同的颜色用于光明和黑暗主题。我选择从页脚中删除背景以简化迁移。现在,页脚采用了背景的颜色。
如果您的网站使用了太多样式,则在迁移时删除它们可能是明智之举。在完成向光明/黑暗主题的迁移后,您可以将它们添加回去。
目标是保持迁移简单,并在需要时稍后添加新样式。
步骤 3:添加光明和黑暗配色方案
完成清理后,我现在可以专注于为光明和黑暗主题添加样式元素。我定义了新的颜色样式并将它们应用于 HTML 元素。我选择从以下内容开始
- --body-bg 用于背景颜色。
- --body-color 用于主体/文本的主要颜色。
- --body-link-color 用于链接。
- --card-bg 用于 Bootstrap 卡片背景颜色。
:root {
--body-bg: #EEE2DC;
--body-color: #AC3B61;
--body-link-color: #AC3B61;
--card-bg: #EDC7B7;
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
:root {
--body-bg: #303C6C;
--body-color: #E2E8E4;
--body-link-color: #FFCCBB;
--card-bg: #212529;
}
}
定义颜色后,我更改了 CSS 以使用新颜色。例如,body 元素现在看起来像这样
body {
background-color: var(--body-bg);
color: var(--body-color) !important;
}
如果 Bootstrap 5 是使用您的 Jekyll 源代码编译的,而不是来自 CDN,您可以覆盖 Bootstrap 5 默认值。这可能有助于简化您需要处理的自定义样式。例如,关闭链接装饰 使我的生活轻松了一些。
$link-hover-decoration: none !default;
步骤 4:Navbar 切换器
最后但并非最不重要的一点:navbar 切换器。在 Bootstrap 5 中,navbar-light 和 navbar-dark 控制切换器的颜色。这些在主 nav 元素和 .navbar 中定义。由于我不再在 HTML 中硬编码颜色类,因此我需要复制 CSS。我 扩展了默认 Sass 并添加了我的主题颜色。
.navbar-toggler {
@extend .navbar-toggler;
color: var(--text-color);
border-color: var(--text-color);
}
.navbar-toggler-icon {
@extend .navbar-toggler-icon;
background-image: escape-svg(url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#000000' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>"));
}
上面的代码是默认的 Bootstrap 5 切换器 CSS 代码,进行了一些小的更改。这里需要注意的一件事:对于切换器图标,我硬编码了 stroke= #000000,因为黑色适用于我的主题颜色。您可能需要更具创意地选择在所有方面都适用的配色方案。

(Ayush Sharma,CC BY-SA 4.0)
就这样!光明模式和黑暗模式现在可以按预期工作了!

(Ayush Sharma,CC BY-SA 4.0)

(Ayush Sharma,CC BY-SA 4.0)

(Ayush Sharma,CC BY-SA 4.0)

(Ayush Sharma,CC BY-SA 4.0)
总结
至少可以说,Bootstrap 5 是复杂的。当使用自定义样式覆盖它时,有很多事情需要考虑。为每个 Bootstrap 5 组件提供光明和黑暗变体是困难的,但如果您没有太多组件要处理,这是可能的。
通过确保标记保留在 Sass/CSS 中,重用样式,并覆盖一些 Bootstrap 5 默认值,可以实现光明模式和黑暗模式。这不是一种全面的方法,但在 Bootstrap 5 决定开箱即用地提供此功能之前,它是一种实用且可用的方法。
我希望这能为您提供更多关于如何为自己的网站添加光明和黑暗主题的实用想法。如果您找到更好的方法来使用自己的 CSS 魔力,请不要忘记与社区分享。
编码愉快 :)
本文最初出现在作者的博客上,并已获得许可重新发布。
评论已关闭。