颜色是数学:它们如何匹配——以及如何构建颜色选择器
为什么有些颜色组合比其他颜色组合看起来更好?剧透:这和数学有关。
前几天,我在我的新网站上写了有关颜色主题工具的文章。
此工具以及我将在本文中介绍的一些其他颜色工具均基于HSL颜色格式。
HSL 代表色调、饱和度和亮度。
色相是主要颜色,以度数表示。
如果你观察色轮,你会发现它是一系列以 30° 为间隔的颜色:
在 CSS 中,它是:
.wheel {
background: conic-gradient(
hsl(0, 100%, 50%),
hsl(30, 100%, 50%),
hsl(60, 100%, 50%),
hsl(90, 100%, 50%),
hsl(120, 100%, 50%),
hsl(150, 100%, 50%),
hsl(180, 100%, 50%),
hsl(210, 100%, 50%),
hsl(240, 100%, 50%),
hsl(270, 100%, 50%),
hsl(300, 100%, 50%),
hsl(330, 100%, 50%),
hsl(360, 100%, 50%)
);
border-radius: 50%;
}
要将其变成水平或垂直滑块,请将渐变类型更改为linear-gradient
:
匹配颜色
当颜色搭配在一起时看起来很棒,这完全取决于它们在色环中之间的关系。
当您选择一种颜色(我们称之为原色)时,与该颜色正对面的颜色(180° 度)称为补色 - 这两种颜色搭配在一起总是很好看。
我们将 HSL 拆分为 3 个 CSS 自定义属性:
--h
,--s
和--l
。
– 看看我们如何使用简单的数学来calc
匹配我们的原色:
.primary {
hsl(var(--h), var(--s), var(--l));
}
补色加180°为--h
:
.complimentary {
hsl(calc(var(--h) + 180), var(--s), var(--l));
}
分裂互补色与原色之间的夹角为 150° 和 210° :
.splitcom1 {
hsl(calc(var(--h) + 150), var(--s), var(--l));
}
.splitcom1 {
hsl(calc(var(--h) + 210), var(--s), var(--l));
}
类似色是所选颜色旁边的颜色(两侧)——在本例中是我们的原色:
.analogous1 {
hsl(calc(var(--h) + 30), var(--s), var(--l));
}
.analogous2 {
hsl(calc(var(--h) - 30), var(--s), var(--l));
}
三色在色轮上均匀分布,因此从我们的原色来看,它的 120° 和 240°(或:负 120°):
.triad1 {
hsl(calc(var(--h) + 120), var(--s), var(--l));
}
.triad2 {
hsl(calc(var(--h) - 120), var(--s), var(--l));
}
方形颜色由我们的原色以及 90°、180°(补色)和 270° 的颜色组成:
.square1 {
hsl(calc(var(--h) + 90), var(--s), var(--l));
}
.square2 {
hsl(calc(var(--h) + 270), var(--s), var(--l));
}
四色矩形与正方形类似,由 60°、180°(互补色)和 240° 的颜色组成:
.tetra1 {
hsl(calc(var(--h) + 60), var(--s), var(--l));
}
.tetra2 {
hsl(calc(var(--h) + 240), var(--s), var(--l));
}
色调
色彩为亮度增添光彩--l
:
.tint10 {
hsl(var(--h), var(--s), calc(var(--l) + ((100% - var(--l)) / 10) * 1));}
.tint20 {
hsl(var(--h), var(--s), calc(var(--l) + ((100% - var(--l)) / 10) * 2));
}
/* etc. */
色调
阴影会消除--l
亮度中的光:
.shade10 {
hsl(var(--h), var(--s), calc(var(--l) - ((100% - var(--l)) / 10) * 1));
}
.shade20 {
--c-sh2: hsl(var(--h), var(--s), calc(var(--l) - ((100% - var(--l)) / 10) * 2));
}
/* etc. */
所有这些 CSS calc
ulated -colors 都是我在CSS 颜色主题工具中使用的,基于--h
、--s
和--l
属性:
现在,让我们看看如何构建颜色选择器。
HSL 颜色选择器
创建一个简单的、基于 HSL 的颜色选择器只需要三个<input type="range">
控件,每个 CSS 自定义属性一个:--h
、--s
和--l
:
<form id="hsl">
<input type="range" name="--h" min="0" max="360" value="0" />
<input type="range" name="--s" min="0" max="100" value="100" data-suffix="%" />
<input type="range" name="--l" min="0" max="100" value="50" data-suffix="%" />
<div class="hsl"></div>
</form>
在 CSS 中,根据需要设置滑块的样式,并将计算出的 HSL 颜色分配给颜色预览<div class="hsl">
:
.hsl {
aspect-ratio: 1/1;
background-color: hsl(var(--h,0), var(--s,100%), var(--l, 50%));
width: 20rem;
}
最后,在 JavaScript 中,在表单上添加一个 eventListener ,它将更新 CSS 自定义属性:
hsl.addEventListener('input', (event) => {
const input = event.target;
document.documentElement.style.setProperty(input.name, `${input.valueAsNumber}${input.dataset.suffix||''}`)
})
就这样!我用这个方法(以及一些 JavaScript)创建了这些小型颜色选择器:
稍微复杂一点的是,这个颜色工具还使用基于 HSL 的滑块和 JavaScript 在各种格式(rgb、cmyk、hex)之间进行转换:
它还具有渐变编辑器,适用于所有类型的 CSS 渐变:圆锥渐变、线性渐变和径向渐变:
您可以在 Codepen 上找到该工具:
奖励:HSB 颜色选择器
Photoshop 颜色选择器的主要区域由三层组成,如果您查看HSB格式,则更容易理解。
B代表亮度,使用与HSL 的亮度略有不同的算法。
如果将 HSB 区域视为坐标系,则饱和度是x 轴(从左到右,0 到 100),亮度是y 轴(从下到上,0 到 100)。
因此,右上角的位置是100, 100
,左下角的位置是0, 0
。
要在 HTML 和 CSS 中重新创建此内容,请使用三个层:
<div class="hue">
<div class="brightness"></div>
<div class="saturation"></div>
</div>
.hue {
--h: 0;
background-color: hsl(var(--h), 100%, 50%);
}
.saturation {
background-image: linear-gradient(to bottom, transparent, hsl(var(--h), 0%, 0%));
}
.brightness {
background-image: linear-gradient(to right, hsl(var(--h), 100%, 100%), transparent);
}
和层需要相对于层进行定位.saturation
。.brightness
absolute
hue
CSS 并不反映实际的饱和度和亮度,但像这样分层,幻觉就完成了:
尝试改变的值--h
。
如果您想在 JavaScript 中构建类似 Photoshop 的颜色选择器,请检测指针设备的x和ygetBoundingClientRect()
位置,使用来获取“选择器区域”的尺寸,然后进行转换,这样您总是会得到0,0
和之间的坐标100,100
。
再次:x
等于饱和度和y
等于亮度。
您还必须将 HSB 转换为 HSL(使用 JavaScript),因为浏览器不理解 HSB 格式。
所以...我认为基于 HSL 的颜色选择器更易于编码和使用!
感谢阅读!
文章来源:https://dev.to/madsstoumann/colors-are-math-how-they-match-and-how-to-build-a-color-picker-4ei8