在网络上,有很多方法可以处理颜色。我认为了解您正在使用的机制背后的原理非常有帮助,颜色也不例外。让我们深入探讨一下网络上颜色的某些技术细节。
颜色混合
处理颜色的很大一部分是理解,您小时候使用颜色的方式与您在计算机上使用颜色的方式不同,因为颜色混合方式不同。小时候,您使用的是颜料。来自打印机的颜料和墨水含有称为颜料的微小颗粒,这些颗粒混合在一起并反射到您的眼睛中,呈现出颜色。**这是减色混合**。您添加的颜色越多,它就变得越暗,直到变成棕色。原色接近您习惯的颜色:红色、黄色、蓝色。但是,当您使用减色混合混合这些颜色时,最终会得到棕色。

在计算机(或任何显示器)上,我们使用的是光。这意味着当所有颜色混合在一起时,它们会产生白色。在艾萨克·牛顿著名的棱镜颜色实验之前,人们认为颜色包含在物体内部,而不是从物体反射和吸收。艾萨克·牛顿使用棱镜证明了他的理论,即阳光或明亮的白色光实际上是几种颜色,他使用棱镜将颜色分开以形成彩虹,然后随后使用棱镜试图进一步分裂蓝色。蓝色没有分裂,表明颜色不在棱镜内部,而是棱镜正在分裂光线。这意味着在**加色混合**中,您在显示器中获得的颜色混合类型,红色、绿色和蓝色可用于生成所有颜色,或 rgb。在这种混合类型中,红色和绿色产生黄色。

显示器是许多组合的小光点组合在一起,产生无数种颜色。分辨率是指显示器上包含的单个彩色点(称为像素)的数量。在我们拥有显示器之前,艺术家们正在使用这种类型的灯光频率。修拉和点彩派在像“La Grande Jatte”这样的绘画中使用红色和绿色来创造黄色(尽管他更喜欢术语色光主义。其他人称之为分色法)这种类型的绘画是在这样的信念下创作的:光学混合在您的眼睛中产生了比传统的减色颜料颜色混合更纯净的共振。

显示器以几种不同的显示模式制造,这些模式改变了我们通过它们感知颜色的方式。我们用术语“颜色位深度”来表达这一点。一次可以显示的颜色数量由该颜色位深度决定。如果我们的位深度为 1,我们可以产生两种颜色,或单色。两位深度创建 4 种颜色,依此类推,直到我们达到 32 位深度,尽管通常投影网页的显示器具有 24 位深度密度和 16,777,216 种颜色,即真彩色和 Alpha 通道。
我们称之为真彩色,因为我们人类的眼睛可以识别 10,000,000 种独特的颜色,因此 24 位深度当然可以做到这一点。在这 24 位深度中,8 位专用于红色、绿色和蓝色。其余部分用于透明度或 alpha 通道。
让我们使用这些信息来解开我们在网络上可用的颜色属性。
颜色值
RGB 值
上一节说明了rbga(x, x, x, y);
传达的内容,但让我们更详细地分解一下,并展示一些其他属性及其用途。在 RGB 通道中的网页颜色值方面,我们在 0-255 的范围内指定颜色。
x is a number from 0-255
y is a number from 0.0 to 1.0
rgb(x, x, x); or rgba(x, x, x, y);
Example: rbga(150, 150, 150, 0.5);
十六进制值
十六进制颜色是表示相同值的略微不同的格式。十六进制值可能是开发人员在网络上指定颜色的最常见方式。
如果您记得**一个字节是 8 位**,则每个十六进制颜色或数字都表示一个字节。颜色根据其红色、绿色和蓝色组件的强度指定,因此我们称之为三元组,每个都用两个位置表示。一个字节表示 00 到 FF(以十六进制表示法)范围内的数字,或 0 到 255(以十进制表示法)范围内的数字。字节 1 是红色,字节 2 是绿色,字节 3 是蓝色。**十六进制**之所以这样命名,是因为它使用**基数 16 系统**。这些值使用 0-9 和 A-F 的范围,0 是最低值,F 是最高值,或#000000
是黑色,#FFFFFF
是白色。
对于具有重复值的三个一组,您可以通过使用简写消除重复,例如,#00FFFF
变为 #0FF
。这个系统易于计算机理解,并且编写起来相当简短,这使得它对于快速复制粘贴和在编程中指定很有用。但是,如果您要以更复杂的方式处理颜色,则 HSL 更易于人类阅读。
HSL 值
Hsl 值使用与 rgb 类似的语义和范围,但它不是像显示器解释颜色那样使用值,而是使用色相、饱和度、亮度值。这在语法上与 rgb 值类似,但范围不同。该系统基于孟塞尔颜色系统(他是第一个将颜色分离到这三个通道中的人,或者创建了一个基于与实际人类视觉相关的数学原理的三维系统)。

色相以 360 度旋转,一个完整的圆圈,而饱和度和亮度是从 0 到 100 的百分比。
x is a number from 0 - 360
y is a percentage from 0% to 100%
z is a number from 0.0 to 1.0
hsl(x, y, y); or hsla(x, y, y, z);
Example: hsla(150, 50%, 50%, 0.5);
对于浏览器来说,在 rgb 和 hsl 值之间交换是一个相对容易的更改(准确地说,大约 11 行代码),但对于我们人类来说,使用 hsl 会更容易解释。想象一个轮子,中心是密集且饱和的内容。此演示很好地展示了它是如何表达的。

如果您不认为自己特别擅长处理颜色,hsla() 允许使用一些非常简单的规则为开发人员创建不错的效果。我们在下面的生成颜色部分中将详细介绍此内容。
命名颜色
命名颜色也作为开发人员可以使用。但是,命名颜色因其不精确而臭名昭著。最著名和“著名”的例子是深灰色实际上比灰色浅,石灰和石灰绿是完全不同的颜色。这里有一个游戏,您可以尝试猜测网络上的命名颜色,由Chris Heilmann制作。在过去,chucknorris
是一种血红色(据我所知,它现在仅在 HTML 中受支持),但那是我最喜欢的。命名颜色可用于快速演示颜色使用,但开发人员通常使用 Sass 或其他预处理器通过十六进制、rgba 或 hsla 存储颜色值,并将它们映射到公司中使用的颜色名称。
颜色变量
一个好的做法是存储颜色变量并**永远不要直接使用它们**,而是将它们映射到具有更多语义命名方案的其他变量。CSS 具有本机变量,例如
:root {
--brandColor: red;
}
body {
background: var(--brandColor);
}
但它们相当新,并且在撰写本文时尚未进入 Microsoft 浏览器。
CSS 预处理器也支持变量,因此您可以设置像$brandPrimary
这样的变量以在您的代码库中使用。或一个映射
$colors: (
mainBrand: #FA6ACC,
secondaryBrand: #F02A52,
highlight: #09A6E4
);
@function color($key) {
@if map-has-key($colors, $key) {
@return map-get($colors, $key);
}
@warn "Unknown `#{$key}` in $colors.";
@return null;
}
// _component.scss
.element {
background-color: color(highlight); // #09A6E4
}
请记住,命名在这里很重要。抽象命名有时很有用,因此,如果您将表示蓝色颜色的变量更改为橙色颜色,则不必遍历并重命名所有颜色值。或者更糟糕的是,竖起一个牌子上面写着“$blue 现在是橙色了。” *悲伤的长号声*
currentColor
currentColor
是一个非常有用的值。它遵循 CSS 样式的层叠规则,并可用于将颜色值扩展到诸如阴影、轮廓、边框,甚至是背景等属性。
假设你创建了一个 div,并在其中嵌套了另一个 div。这将为内部 div 创建橙色的边框。
.div-external { color: orange; }
.div-internal { border: 1px solid currentColor; }
这对于图标系统(无论是 SVG 图标还是字体图标)都非常有用。你可以将 currentColor
设置为填充、描边或颜色的默认值,然后使用语义化的 CSS 类来对图标进行样式化。
预处理器
CSS 预处理器非常适合调整颜色。以下是一些关于颜色函数的不同预处理器文档的链接。
以下是一些我们使用 Sass 可以实现的有趣功能。
mix($color1, $color2, [$weight])
adjust-hue($color, $degrees)
lighten($color, $amount)
darken($color, $amount)
saturate($color, $amount)
实际上,使用预处理器以编程方式混合和修改颜色的方法有很多种,我们不会深入探讨所有方法,但这里有一个很棒的交互式资源,可以提供更深入的信息。
颜色属性
作为 CSS 属性,颜色指的是字体颜色。如果你要在一个大区域设置颜色,则应使用 background-color
,除非是 SVG 元素,在这种情况下,应使用 fill
。边框是 HTML 元素周围的边框,而 stroke
是其 SVG 等效项。
阴影
box-shadow
和 text-shadow
属性接受颜色值。文本阴影接受 2-3 个值:水平阴影 (h-shadow)、垂直阴影 (v-shadow) 和可选的模糊半径。盒子阴影接受 2-4 个值:水平阴影、垂直阴影、可选的模糊距离和可选的扩展距离。你也可以在开头指定 inset
以创建反向阴影。这个网站有一个很棒的演示,并提供易于粘贴的代码。
渐变
线性渐变通过指定方向来工作。从/到(取决于浏览器前缀)顶部、底部、左侧、右侧、度数或径向渐变。然后我们指定颜色停止点和我们希望在每个停止点处的颜色。这些也可以接受透明度。
这是一个示例。
渐变的大部分语法编写起来并不困难,但我真的很喜欢使用这个在线渐变生成器,因为它还为 IE6-9 浏览器创建了复杂的滤镜属性以保证兼容性。还有一个非常漂亮的UI 渐变生成器。这个也很酷,它是开源的,你可以为它做出贡献。
在 SVG 中创建渐变也同样容易。我们定义一个 块,并通过 id 进行引用。我们也可以选择定义渐变的表面区域。
<linearGradient id="Gradient">
<stop id="stop1" offset="0" stop-color="white" stop-opacity="0" />
<stop id="stop2" offset="0.3" stop-color="black" stop-opacity="1" />
</linearGradient>
这些渐变也支持不透明度,因此我们可以获得一些不错的效果和图层效果,例如将其作为蒙版进行动画处理。
仅在 WebKit 中也支持渐变文本,我们有一个非常好的代码片段在 CSS-Tricks 上。
生成颜色
有一些很酷的方法可以一次生成大量令人惊叹的颜色。在创建生成艺术或使用代码的 UI 元素时,我发现这些方法非常有趣。
只要你保持在上一节中指定的范围内,你就可以在 Sass(或任何 CSS 预处理器)或 JavaScript 中使用 for
循环,或者使用 Math.Random()
和 Math.floor()
获取颜色值。这里我们需要 Math.floor()
或 Math.ceil()
,因为如果我们不返回完整的整数,就会出现错误,并且无法获得颜色值。
一个好的经验法则是,你不应该更新所有三个值。我在一个值范围内的大偏差、第二个值范围的小偏差以及第三个值范围没有偏差的情况下取得了不错的效果,不一定按此顺序。例如,**hsl 非常易于使用以逐步遍历颜色**,因为你知道从 0 到 360 循环遍历色相将提供一个完整的范围。色相旋转(以度为单位)的另一个优点是,因为它是一个完整的圆,所以你不需要坚持 0-360 的范围,即使是 -480 或 600 也仍然是浏览器可以解释的值。
Sass
@mixin colors($max, $color-frequency) {
$color: 300/$max;
@for $i from 1 through $max {
.s#{$i} {
border: 1px solid hsl(($i - 10)*($color*1.25), ($i - 1)*($color / $color-frequency), 40%);
}
}
}
.demo {
@include colors(20,2);
}
我使用它在这个演示中创建彩虹糖颜色。
以及这个,使用了不同的范围(**快速滚动列表内部**)。
在下面的代码中,我使用 Math.random()
在 rgb 值内生成大量相同范围内的颜色。此演示使用 React 创建了一个三维 VR 体验。我也可以使用 for 循环来逐步完成它,但我希望颜色随机化以反映运动。这个功能的可能性是无限的。

JavaScript
class App extends React.Component {
render () {
const items = [],
amt1 = 5,
amt2 = 7;
for (let i = 0; i < 30; i++) {
let rando = Math.floor(Math.random() * (amt2 - 0 + 1)) + 0,
addColor1 = parseInt(rando * i),
addColor2 = 255 - parseInt(7 * i),
updateColor = `rgb(200, ${addColor1}, ${addColor2})`;
items.push(
// ...
);
}
return (
// ...
{items}
);
}
}
GreenSock 推出了一个工具,允许你对相对颜色值进行动画处理,这很有用,因为它意味着你可以一次获取大量元素并相对于其当前颜色坐标对其进行动画处理。以下是一些演示该想法的示例。
TweenMax.to(".turtle2 path, .turtle2 circle, .turtle2 ellipse", 1.5, {fill:"hsl(+=0, +=50%, +=0%)"});
其他不错的颜色效果
混合模式
如果你使用过 Photoshop 中的图层效果,你可能熟悉混合模式。90 年代几乎每个网站都使用过它们(我的网站也用过,*脸红*)。混合模式和背景混合模式将两个不同的分层图像组合在一起,并且有 16 种模式可用。逐一讲解每种模式超出了本文的范围,但这里有一些关键示例。
顶部图像或颜色称为 source
(源),底部图层称为 destination
(目标)。两者之间的区域是混合魔法发生的地方,称为 backdrop
(背景)。我们根据相当简单的数学公式混合两者。

如果你想和我一起深入研究,混合模式的颜色公式取决于所使用的效果类型。例如,正片叠底是 destination × source = backdrop
。其他效果是使用减法、乘法、加法和除法的简单数学运算的变体。线性是 A+B−1
,而颜色加深是 1−(1−B)÷A
。不过,你不需要了解任何这些内容即可使用它们。
这里有一些更详细的文档,这里还有一个非常简单的演示来说明颜色与其中一些效果的配合使用。
Robin 的这篇很棒的文章展示了一些非常复杂和令人印象深刻的效果,你也可以通过叠加多个混合模式来实现。下面我们将介绍如何将它们与滤镜混合使用。如今,在浏览器中真的可以做很多事情。
滤镜
CSS 滤镜提供了许多很酷的色彩效果,以及将彩色图像转换为灰度色的能力。我们在 CSS-Tricks 上有一个很棒的资源 展示了它们的工作原理,并且现在浏览器的支持度相当高。如果你想探索一下,Bennett Feely 还有一个不错的滤镜库。
滤镜和模糊模式可以一起工作!Una Kravets 创建了一个很酷的工具,叫做CSS Gram,它结合了一些效果来创建典型的 Instagram 滤镜,她在底部提供了一些不错的文档。
feColorMatrix
Una 还有另一篇文章 探讨了使用feColorMatrix
创建这些图像的方法,它是一个 SVG 中的滤镜基本元素,也可以应用于 HTML 元素。它非常强大,允许你微调和优化颜色。顾名思义,feColorMatrix
的基本标记使用了一个值的矩阵,我们使用它的相对 ID 来应用它。
<filter id="imInTheMatrix">
<feColorMatrix in="SourceGraphic"
type="matrix"
values="0 0 0 0 0
1 1 1 1 0
0 0 0 0 0
0 0 0 1 0" />
</filter>
<path filter="url(#imInTheMatrix)" … />
我们还可以扩展这个矩阵并调整这些值的色相、饱和度等。
<filter id="imInTheHueMatrix">
<feColorMatrix in="SourceGraphic"
type="hueRotate"
values="150" />
</filter>
Una 的文章深入探讨了这里的所有功能,但你也可以从 Amelia Belamy-Royd 的 O'Reilly 图书《SVG 颜色、图案和渐变》或Mike Mullany 的探索性演示中获取更多关于此以及许多其他疯狂的 SVG 颜色和渐变工具的信息。

可访问性和关于颜色的其他注意事项
颜色只有在参考另一种颜色时才是一种颜色。这是使颜色如此困难的部分原因。在可访问性方面,你可能对此有点熟悉。浅绿色在黑色背景上可能是可访问的,但是当你将其更改为白色背景时,它就不再可访问了。
可以使用多种工具来衡量颜色的可访问性。以下是我的一些最喜欢的工具:
从一开始就为可访问性设置调色板也是非常好的。Color Safe 是一个非常棒的工具,可以帮助你做到这一点。一旦你全部设置完毕,WAVE(Web 可访问性工具) 将帮助你评估你的网页。
颜色和氛围
颜色受氛围的影响,如果你要创建任何类型的深度错觉,这是一个非常重要的需要了解的事情。离你近的事物具有更高的饱和度和对比度。离你远的事物看起来会更模糊。

阴影
阴影不是灰色的,它们是光线颜色的补色。如果你用手照射黄色的光,阴影就会呈现紫色。如果你要制作任何超酷的长阴影,这将是一个有用的知识。

原生颜色输入
有一个原生的浏览器颜色选择器,你可以使用它来帮助用户动态选择颜色。你可以编写或
,如果你想从颜色提示开始。使用起来就这么简单。浏览器做得好。需要注意的一点是,它的外观在不同的浏览器中会有细微的差别,就像任何其他原生控件一样。Noah Blon 的这个示例展示了如何将其与色相 CSS 颜色滤镜结合使用,以动态选择图像的某些部分来更改颜色。图像的其余部分为灰度色,因此不受影响。非常聪明。
有趣的开发者工具和其他资源
- 我使用Sublime Text 的 Color Highlighter 插件来轻松查看浏览器将解释的颜色。我喜欢使用
{"ha_style": "outlined"}
,但我知道从这篇文章中,Wes Bos 更喜欢“filled”。 - 有一些不同的传统调色板组合,以及可以帮助你创建这些组合的在线网络资源。对于更科学的人来说,可以使用Paletton或Adobe Color。Benjamin Knight在 CodePen 上用 d3 重现了 Adobe 的颜色工具,这非常厉害,值得一看。如果你希望网络为你完成繁重的工作(谁不希望呢?),Coolors 就简单得不能再简单了。
- 如果你需要帮助解释颜色,并且想要一个快速简单的工具来为你交换各种颜色属性,Colorhexa 可以满足你在你能想到的几乎所有类型的颜色交换方面的需求。
- 对于最狂热的颜色爱好者,你甚至可以将控制台输出以颜色的形式显示给你。这里有一个很棒的示例展示了它是如何工作的。
- Super Color Palette 是一个用于创建颜色组合的小型游乐场,它提供了各种控件,并且能够以不同的图像格式导出颜色,包括 SVG、JPG 和 PNG。这是一个免费的项目,有一个 Discord 频道用于分享你的调色板和讨论颜色相关的专业知识。
结论
本文的范围相当广泛,网络有很多颜色可以深入研究,但希望这篇简短的文章能为你提供一些实验和理解的起点。
这并不准确。24 位颜色是每个 RGB 通道 8 位,不包含透明度。32 位颜色是每个通道 8 位,包括 alpha。
这就是为什么 HSL 是 24 位 RGB 颜色的一个子集。HSL 实际上只能处理 3,492,722 种不同的颜色(360 × 99 × 98 + 2)。从技术上讲,RGB 具有更好的保真度,多个 RGB 值映射到相同的 HSL。
当我注意到这篇文章时,我实际上正在撰写一篇关于 HSL 与 RGB 的文章(http://blog.armstrongest.com/why-i-love-hsl-more-than-rgb/),但我还是决定发布。
非常棒的文章。感谢您纠正了 rgb 是 24 位而 rgba 是 32 位。
这是对 Gary Armstrong 关于 hsl 中最大颜色数的评论的回应,我刚刚进行了一些测试。
我只是想让你知道,你关于rgb比hsl保真度更高的评论是不正确的,因为你可以使用小数百分比表示饱和度和亮度。但是你不能对rgb使用小数值。
例如(在Mac Chrome上)
hsl(290,60%,70%) = #D185E1
hsl(290,60.5%,70%) = #D284E1
看起来你似乎不能使用小数色相值。
我不确定hsl值是否被转换为十六进制或rgb。如果hsl值在显示之前被四舍五入为其中一个,那么你可能已经用尽了所有可能的十六进制或rgb颜色。
但我认为可以公平地说,hsl至少拥有与rgb一样多的颜色,甚至可能更多。
缺少一个零。
background-clip: text
也称为渐变文本,即将在 Firefox 中推出(Beta 版已支持)。哇!这篇文章必须算得上我最喜欢的文章之一。
我喜欢你深入探讨每个子主题的方式;有些主题深入到足以真正理解如何以及为什么,而另一些主题则足够让我们知道为什么我们应该有兴趣阅读更多。
阅读时我无需任何休息,也没有发现自己跳过任何内容。即使你在解释我已牢牢掌握的内容时,我仍然对你的概述感兴趣。
现在我回顾 Sarah 撰写的其他文章时,发现它们往往是我添加了书签或记在心里的文章。
谢谢 Sarah。期待你下一篇文章,屏息以待。
哇!精彩的文章,文笔流畅,结构合理。
你对这个主题的热情确实体现出来了。
确实值得收藏。
很棒的文章!!这篇文章应该获奖什么的 :)
很棒的文章!
一个小小的说明。你写道
“在过去,
chucknorris
是一种血红色(据我所知,它现在只在 HTML 中受支持),但那是我最喜欢的颜色。”实际上比你说的更有意思。
chucknorris
不是一种命名颜色——完整列表在这里,最初是基于X11 颜色。但是,为什么
chucknorris
会变成红色呢?你链接到的StackOverflow 答案详细解释了这一点。浏览器被训练为忽略无效数据。缺失的数字和无效的十六进制数字被视为
0
。因此,CHUCKNORRIS
被转换为C00C0000000
。十六进制颜色数字的数量必须是 3 的倍数;由于它是 11,因此在末尾添加一个额外的填充数字0
。然后,浏览器将代码分成三个相等的部分用于 RGB,因此我们得到
C00C 0000 0000
。最后,它们将每个部分截断为两个字符:C0 00 00
,也就是#C00000
,也就是暗红色。评论者指出,其他随机字符串也会生成颜色,包括一些奇怪的恰当颜色,包括
grass
(绿色)和crap
(棕色)。你可以使用这个有趣的工具输入随机字符串并发现解释的颜色。无论如何,很棒的文章!
这是一篇令人印象深刻的文章。
有一点,关于
currentColor
代码段以上示例可能不是展示
currentColor
强大功能的最佳示例,因为在这种情况下,currentColor
已经是border-color
的默认值。我过去常玩油画,会往天空颜色中添加黑色或灰色来表现阴影。我总是能感觉到哪里不对劲,但无法弄清楚;现在我知道了。很棒的技巧,谢谢!
很棒的文章,
我在访问 HSL 部分开头提到的演示时收到了病毒感染警告。我不确定它是否合法,或者演示代码是否混淆了我的病毒软件,但我还是想提一下……
检测到感染!
http://www.workwithcolor.com/hsl-color-picker-01.htm
请求的 URL 包含可能损坏您计算机的恶意代码。如果您仍要访问该 URL,请关闭 Avast 网络防护盾并重试。
感染类型:JS:Redirector-BNI [Trj]
RGB 函数也可以使用 3 个百分比值来表示要应用的红色、绿色和蓝色的比例,0% = 0(或 00 十六进制),100% = 255(或 FF 十六进制)。所有三个值都必须是百分比,它们可以精确到小数点后两位 (12.34%),但似乎不适用于 RGBA 函数。
为什么我直到现在才知道控制台颜色?!
喜欢文章中很棒的混合模式演示。除此之外,Smashing 上还有一篇关于改进颜色工作流程和为 Web 开发人员创建调色板的有用文章
https://www.smashingmagazine.com/2016/04/web-developer-guide-color/
谢谢!
— Bo
干得漂亮!谢谢。
rbga =)