构建配色方案

有关如何建立动态且可配置的配色方案的基础知识

在这篇博文中,我想分享一些管理多种配色方案的方法 。试用演示版

<ph type="x-smartling-placeholder">
</ph>
演示

如果你更喜欢视频,可以参阅此博文的 YouTube 版本:

概览

我们将使用自定义属性和 calc() 构建一个易于访问的颜色系统, 制作可适应用户偏好的网页,同时保留原作品 体验极简。我们先设定基本品牌颜色,然后构建一个 :2 种文本颜色、4 种 Surface 颜色和匹配的阴影。

本指南首先为每种配色方案定义所有颜色 。直到最后,他们才会更改页面。

品牌

通常,已经确定了品牌颜色,并以 十六进制rgb。此 GUI 挑战 基本品牌颜色为 #0af。首先,对于这个颜色系统, 需要转换为 hsl

* {
  --brand: #0af;
  --brand: hsl(200 100% 50%);
}

为了形成能够调暗或调亮品牌颜色的概念,比如 20%,hsl 颜色值的 3 个通道需要提取到自己的自定义 属性,如下所示:

* {
  --brand-hue: 200;
  --brand-saturation: 100%;
  --brand-lightness: 50%;
}

CSS 可以对这些颜色属性进行数学运算,例如,使用 calc(var(--brand-lightness) - 20%) 将亮度值降低 20%。这是构建 因为 CSS 可通过调整颜色集的 hsl 饱和度和亮度量。

浅色主题

每种颜色变体都将使用其匹配方案进行标记,在本例中,每个 附加了 -light

浅色主题最终结果预览

品牌

从品牌颜色开始,通过封装 --brand-hue--brand-saturation 对其进行重建。 以及 hsl () 函数圆括号内的 --brand-lightness 自定义属性。 不进行任何计算:

* {
  --brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
}

文字颜色

接下来,配色方案的基本要素需要文本颜色。在浅色主题中,文字 应该很暗请注意以下颜色的亮度较低 远低于 50%

* {
  --text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
  --text2-light: hsl(var(--brand-hue) 30% 30%);
}

--text1-light,因为 10% 的亮度时非常暗,所以会使较深的亮度保持为 100% 饱和度,使品牌颜色仍然能够透过深色海军蓝显现。

--text2-light,不像第 1 种颜色那么深,颜色好 它的饱和度也要低得多

Surface 颜色

Surface 颜色是指背景、边框和其他装饰性表面, 位于或内部。在浅色主题中,这些是浅色 与深色的文字颜色形成了鲜明的对比。要使用 hsl 创建浅色 我们将在第三个亮度值中使用较高的百分比值。我们还会降低 所以浅灰色看起来不会太着色

* {
  --surface1-light: hsl(var(--brand-hue) 25% 90%);
  --surface2-light: hsl(var(--brand-hue) 20% 99%);
  --surface3-light: hsl(var(--brand-hue) 20% 92%);
  --surface4-light: hsl(var(--brand-hue) 20% 85%);
}

创建了 4 种表面颜色,因为装饰色往往需要更多颜色 变体,用于 :focus:hover 等互动时刻,或创建 纸张层的外观。在这类情况下 --surface2-light,悬停在 --surface3-light 上,那么悬停鼠标时,系统会显示 提高对比度(99% 亮度到 92% 亮度;降低亮度)。

阴影

配色方案中的阴影效果更胜一筹,但又能增添逼真效果 并帮助它从不真实的黑色阴影中脱颖而出。待办事项 阴影的颜色将使用色调自定义属性, 但仍然非常暗实质上是在构建 浅蓝色的阴影。

* {
  --surface-shadow-light: var(--brand-hue) 10% 20%;
  --shadow-strength-light: .02;
}

--surface-shadow-light 未封装在 hsl 函数中。这是因为 --shadow-strength 值会被组合起来以产生一定的不透明度,而 CSS 提供商需要 以便进行计算。跳至 rad 阴影 部分了解详情。

融合所有灯光色彩

不用再四处走动,看看这些浅色是如何制作出来的 都在 CSS 中的一处位置。

* {
  --brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
  --text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
  --text2-light: hsl(var(--brand-hue) 30% 30%);
  --surface1-light: hsl(var(--brand-hue) 25% 90%);
  --surface2-light: hsl(var(--brand-hue) 20% 99%);
  --surface3-light: hsl(var(--brand-hue) 20% 92%);
  --surface4-light: hsl(var(--brand-hue) 20% 85%);
  --surface-shadow-light: var(--brand-hue) 10% calc(var(--brand-lightness) / 5);
  --shadow-strength-light: .02;
}
所有浅色的屏幕截图
CodePen 上的沙盒

深色主题

大多数品牌一开始都不会使用深色主题,而是主要的深色主题的变体 通常是较轻的主题另一方面,用户通常会为 不同的情境(例如夜晚时)。这些因素促使我保留了两个 使用深色主题时需要注意的事项:

  1. 用户在使用此主题时通常处于黑屏状态,因此请在 深色。
  2. 色彩饱和度应降低,以免屏幕振动,因为

深色主题最终结果的预览

品牌

浅色主题使用 3 个品牌 hsl 颜色通道值,而不做任何改动, 而深色主题则不然饱和度减半,亮度降低 相对的 50%

* {
  --brand-dark: hsl(
    var(--brand-hue)
    calc(var(--brand-saturation) / 2)
    calc(var(--brand-lightness) / 1.5)
  );
}

文字颜色

在深色主题中,文本颜色应为浅色。以下颜色的得分偏高 让它们更接近于白色

* {
  --text1-dark: hsl(var(--brand-hue) 15% 85%);
  --text2-dark: hsl(var(--brand-hue) 5% 65%);
}

Surface 颜色

在深色主题中,Surface 颜色应为深色。以下颜色 低亮度和饱和度,第一个表面最暗,为 10%。

* {
  --surface1-dark: hsl(var(--brand-hue) 10% 10%);
  --surface2-dark: hsl(var(--brand-hue) 10% 15%);
  --surface3-dark: hsl(var(--brand-hue) 5%  20%);
  --surface4-dark: hsl(var(--brand-hue) 5% 25%);
}

阴影

在深色主题中,阴影可能非常难以看到。有道理,因为这很难 把已经很暗的东西调暗这就是 --shadow-strength-dark 非常方便,它能让我们调暗 添加阴影效果。

* {
  --surface-shadow-dark: var(--brand-hue) 50% 3%;
  --shadow-strength-dark: .8;
}

另外,看看阴影中的饱和度如何。你能注意到颜色吗 您看界面时的情况呢?请尝试去掉 devtools,你更喜欢哪一个?!

深色调

* {
  --brand-dark: hsl(var(--brand-hue) calc(var(--brand-saturation) / 2) calc(var(--brand-lightness) / 1.5));
  --text1-dark: hsl(var(--brand-hue) 15% 85%);
  --text2-dark: hsl(var(--brand-hue) 5% 65%);
  --surface1-dark: hsl(var(--brand-hue) 10% 10%);
  --surface2-dark: hsl(var(--brand-hue) 10% 15%);
  --surface3-dark: hsl(var(--brand-hue) 5%  20%);
  --surface4-dark: hsl(var(--brand-hue) 5% 25%);
  --surface-shadow-dark: var(--brand-hue) 50% 3%;
  --shadow-strength-dark: .8;
}
所有深颜色的屏幕截图
CodePen 上的沙盒

调暗主题

此配色方案主要是协调亮度和饱和度。那里 饱和度应足以确保仍能看到色相 对比度得分, 就是意在呈现暗淡的低对比度

调暗主题最终结果的预览

品牌

* {
  --brand-dim: hsl(
    var(--brand-hue)
    calc(var(--brand-saturation) / 1.25)
    calc(var(--brand-lightness) / 1.25)
  );
}

文字颜色

* {
  --text1-dim: hsl(var(--brand-hue) 15% 75%);
  --text2-dim: hsl(var(--brand-hue) 10% 61%);
}

Surface 颜色

* {
  --surface1-dim: hsl(var(--brand-hue) 10% 20%);
  --surface2-dim: hsl(var(--brand-hue) 10% 25%);
  --surface3-dim: hsl(var(--brand-hue) 5%  30%);
  --surface4-dim: hsl(var(--brand-hue) 5% 35%);
}

阴影

* {
  --surface-shadow-dim: var(--brand-hue) 30% 13%;
  --shadow-strength-dim: .2;
}

调暗所有颜色

* {
  --brand-dim: hsl(var(--brand-hue) calc(var(--brand-saturation) / 1.25) calc(var(--brand-lightness) / 1.25));
  --text1-dim: hsl(var(--brand-hue) 15% 75%);
  --text2-dim: hsl(var(--brand-hue) 10% 61%);
  --surface1-dim: hsl(var(--brand-hue) 10% 20%);
  --surface2-dim: hsl(var(--brand-hue) 10% 25%);
  --surface3-dim: hsl(var(--brand-hue) 5%  30%);
  --surface4-dim: hsl(var(--brand-hue) 5% 35%);
  --surface-shadow-dim: var(--brand-hue) 30% 13%;
  --shadow-strength-dim: .2;
}
调暗所有颜色在一起的屏幕截图
CodePen 上的沙盒

易于辨认的颜色

请注意,深色文本颜色集中的最低亮度为 65%, 暗表面的最高亮度为 25%。也就是亮度的 40% 彼此之间留有一定的呼吸空间在浅色主题中 浅色主题保持文本颜色和表面颜色之间的亮度差异 约 40-50% 有助于保持较高的色彩对比度 在得分不佳时进行调整。

我将它称为“bump bump til ya Pass”, 亮度值,直到工具显示我正经过。

<ph type="x-smartling-placeholder">
</ph>
同时按 Shift + 向下箭头可降低亮度并增加对比度,直到通过

在此挑战中创建的每个主题都会传递对比度分数。暗色调配色方案的对比度最低,但仍满足最低要求。为了帮助团队中的其他人使用对比鲜明的颜色,最好创建一个类名称,将 Surface 颜色与无障碍文本颜色配对。

.surface1 {
  background-color: var(--surface1);
  color: var(--text2);
}

.surface2 {
  background-color: var(--surface2);
  color: var(--text2);
}

.surface3 {
  background-color: var(--surface3);
  color: var(--text1);
}

.surface4 {
  background-color: var(--surface4);
  color: var(--text1);
}
暗表面和文本对的屏幕截图
VisBug 显示暗表面和文本配对的屏幕截图

辐射阴影

这些主题使用一个名为 .rad-shadow 的实用程序类。此阴影已生成 Smooth Shadow 工具。 。我获取生成的代码段,并用自己的颜色对其进行自定义, 计算不透明度这样做是为了形成可以调整的阴影 不同的颜色方案

每个阴影相邻

为此,我为每个配色方案创建了 2 个变量来进行调整: 阴影颜色和阴影强度。颜色代表饱和度和暗度 而强度则有助于轻松增加阴影 为深色调。最终结果差不多就是这样。

:root {
  --surface-shadow-light: var(--brand-hue) 10% 20%;
  --shadow-strength-light: .02;
}

.rad-shadow {
  box-shadow:
    0 2.8px 2.2px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
    0 6.7px 5.3px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .01)),
    0 12.5px 10px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
    0 22.3px 17.9px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
    0 41.8px 33.4px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
    0 100px 80px hsl(var(--surface-shadow) / var(--shadow-strength))
  ;
}

如果我在配色方案中进一步运用阴影, 角也是一个设计令牌常量,因为光照方向应该相同

配色方案的使用

自定义完颜色后,是时候将它们变成 架构无关的属性。我是说 作者,则应该很少需要访问 特定配色方案的值。我希望可以轻松地保持在主题之内。

为了实现这一点,应该只能通过 通用自定义属性,稍后我们将定义这些属性这样, 使用设计变量的人永远不必担心 只需使用 Surface 和 Text 颜色即可。而不是 color: var(--text1-light) 使用 color: var(--text1)。所有调整和转换 在 CSS 中,颜色的级别要高得多。

在以下代码块中,深入了解浅色主题的关联样式: 将通用自定义属性与浅色主题专用颜色相关联。现在,全部 如果使用了 var(--brand),则会使用浅色品牌颜色。

浅色主题(自动)

:root {
  color-scheme: light;
  --brand: var(--brand-light);
  --text1: var(--text1-light);
  --text2: var(--text2-light);
  --surface1: var(--surface1-light);
  --surface2: var(--surface2-light);
  --surface3: var(--surface3-light);
  --surface4: var(--surface4-light);
  --surface-shadow: var(--surface-shadow-light);
  --shadow-strength: var(--shadow-strength-light);
}

该网站目前正在使用浅色主题。这是非常有趣的成功时刻! 让我们再看几个时刻,因为我们在其他 配色方案上下文。

深色主题(自动)

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;

    --brand: var(--brand-dark);
    --text1: var(--text1-dark);
    --text2: var(--text2-dark);
    --surface1: var(--surface1-dark);
    --surface2: var(--surface2-dark);
    --surface3: var(--surface3-dark);
    --surface4: var(--surface4-dark);
    --surface-shadow: var(--surface-shadow-dark);
    --shadow-strength: var(--shadow-strength-dark);
  }
}

浅色主题

[color-scheme="light"] {
  color-scheme: light;

  --brand: var(--brand-light);
  --text1: var(--text1-light);
  --text2: var(--text2-light);
  --surface1: var(--surface1-light);
  --surface2: var(--surface2-light);
  --surface3: var(--surface3-light);
  --surface4: var(--surface4-light);
  --surface-shadow: var(--surface-shadow-light);
  --shadow-strength: var(--shadow-strength-light);
}

深色主题

[color-scheme="dark"] {
  color-scheme: dark;

  --brand: var(--brand-dark);
  --text1: var(--text1-dark);
  --text2: var(--text2-dark);
  --surface1: var(--surface1-dark);
  --surface2: var(--surface2-dark);
  --surface3: var(--surface3-dark);
  --surface4: var(--surface4-dark);
  --surface-shadow: var(--surface-shadow-dark);
  --shadow-strength: var(--shadow-strength-dark);
}

调暗主题

[color-scheme="dim"] {
  color-scheme: dark;

  --brand: var(--brand-dim);
  --text1: var(--text1-dim);
  --text2: var(--text2-dim);
  --surface1: var(--surface1-dim);
  --surface2: var(--surface2-dim);
  --surface3: var(--surface3-dim);
  --surface4: var(--surface4-dim);
  --surface-shadow: var(--surface-shadow-dim);
  --shadow-strength: var(--shadow-strength-dim);
}

此时,作者可以随意使用所提供的配色方案泛型, 而无需再操心主题。

总结

现在你知道我怎么做到的了,你会怎么做?!🙂

让我们一起采用多样化的方法,学习所有在 Web 上构建应用的方法。 创建一个 Codepen 或托管自己的演示,将它发到 Twitter 微博中,然后我会将其添加到 下方的“社区混剪作品”部分。

来源

社区混剪作品 - @chris-kruining 添加了色调滑块, no-preferencemoreless 的状态颜色和对比度模式: 演示