网页开发入门|08 颜色

人类眼睛中负责感受颜色的视锥细胞只有三种,分别只能感受到红、绿、蓝,因此红绿蓝成为了三原色。

网页开发入门|08 颜色

在前两节课中,咱们费劲心机终于让代码没有那么「丑」了,但是页面本身却并没有因为我们的折腾变得更好看,反而看起来更加「不和谐」了。

原本的设计稿
原本的设计稿
一言难尽的成稿
一言难尽的成稿

别着急,正所谓磨刀不误砍柴工,接下来咱们就开始应用CSS这把利器,去一一解决页面目前遗留下的问题。

而本节课,咱们就先聊一下其中比较轻松的——颜色!

三原色

众所周知,世界上颜色千千万,但都是由3个基本颜色相互混合而成的:红Red、绿Green、蓝Blue,也简称为RGB。

红+绿=黄,绿+蓝=青,蓝+红=品红(紫),红+绿+蓝=白,如果什么颜色都没有那就是黑。

三原色与组合色
三原色与组合色

可是,你有没有想过,牛顿明明通过三棱镜实验告诉我们白光里包含了众多颜色,而红、绿、蓝只不过是其中众多的颜色之三,为什么他们却能组合出别的颜色呢?

牛顿的三棱镜实验
牛顿的三棱镜实验

这是因为颜色原本就不是物理世界里本来就有的东西,它只是人类的感觉啊!

人的眼睛中负责感受颜色的视锥细胞只有三种,分别只能感受到红、绿、蓝。

图中三角形的细胞就是视锥细胞,每一种细胞可以感受红、绿、蓝中的一个颜色
图中三角形的细胞就是视锥细胞,每一种细胞可以感受红、绿、蓝中的一个颜色

更加准确的说,是这三种视锥细胞在看到波长为445nm,535nm,575nm的光时,感光能力达到了顶点。而我们看到其他的颜色,就是这三种细胞在不同感光水平下组合的结果。

不同波长的光
不同波长的光

既然是这样,那么电脑的屏幕只需要能发射出这三个波长的光,并控制他们的强弱,就可以让用户看到任何颜色!

著名的周冬雨排列,因三种颜色的发光组件的形状与小黄鸭周冬雨有种莫名相似
著名的周冬雨排列,因三种颜色的发光组件的形状与小黄鸭周冬雨有种莫名相似

但是世上不可能有那么完美的发光组件,所以一台显示器能显示的颜色总量一定会比人眼能看到所有颜色少一些,我们管显示器能显示的色彩范围叫做它的色域或者色彩空间(Color Space)。

RGB表示法

既然,我们知道了显示器能显示的颜色是由三原色的发光元器件决定的,我们便可以通过量化每一个器件的发光强度,来准确的表示任何一个在色域中的颜色。

将其中每一个颜色的发光器件,完全不发光定义为0,达到最大亮度定义为255,然后以RGB的顺序来书写变得到了一个准确的颜色。

rgb(0, 0, 0) /* 纯黑色 */
rgb(255, 255, 255) /* 纯白色 */
rgb(255, 0, 0) /* 纯红色 */
rgb(0, 255, 0) /* 纯绿色 */
rgb(0, 0, 255) /* 纯蓝色 */
rgb(255, 255, 0) /* 纯黄色 */
rgb(135, 206, 250) /* 淡天蓝色 */

这便是RGB表示法。

我们可以通过在CSS中使用RGB表示法,准确的表达我们需要的颜色。

为了不影响之前已经生效的代码,建议再复制一下上节课peom3.htmlpoem4.html,在新文件中改造它。
a {
  color: rgb(38, 115, 219);
}
将超链接的颜色与设计稿中的修改为一致
将超链接的颜色与设计稿中的修改为一致

如果你了解十六进制,RGB表示法还有一种更常用的简便写法:0-255刚好可以用2位十六进制表示(即00-ff),于是就可以用一个6位的十六进制数表示颜色,如:

#000000 /* 纯黑色 */
#ffffff /* 纯白色 */
#ff0000 /* 纯红色 */
#00ff00 /* 纯绿色 */
#0000ff /* 纯蓝色 */
#ffff00 /* 纯黄色 */
#87cefa /* 淡天蓝色 */

如果你不懂十六进制也完全没有关系,只需要知道当看到一个以#打头的6位十六进制数字时,它指的是一种颜色即可。

让我们使用RGB表示法,将poem4.html中的颜色进行修正。

/* 省略了与颜色不相关的部分代码 */
h1 {
  color: #333333;
}

div {
 color: #999999;
}

p {
  color: #333333;
}

a {
  color: #2673db;
}

#tag {
  color: #666666;
}

#tag a {
  background-color: #f1f2f6;
}
校正颜色过后的成稿
校正颜色过后的成稿

HSL表示法

RGB表示法的优势显然易见,它符合我们看到颜色的原理,也非常准确的告诉了显示器该如何显示颜色;但它的劣势也非常明显,人类很难想象出每一组数字对应的颜色是什么。

比如,请问rgb(155, 89, 182)也就是把「155强度的红,89强度的绿,182强度的蓝」混在一起是什么颜色?

rgb(155, 89, 182)是弦五说logo中紫色部分的色号
rgb(155, 89, 182)是弦五说logo中紫色部分的色号

我们人类更愿意说这个颜色是「一种略微发黑的暗紫色」,这样的一种说法正是HSL表示法想要解决的问题。

把红、绿、蓝三个颜色相互隔120°均匀的分布到一个圆上,越往圆心颜色越暗淡,越往圆周颜色越鲜艳,然后其他的补上过度的颜色,就形成了下图中的色盘。

在色盘里每个角度都代表了一个色系,比如180 °就是青色系等等。角度在数学上也称作相位,所以用来选择色系的这个这个角度被称作色相Hue

在同一个色系里,越往圆心颜色就越暗淡,可以理解为更接近灰色。这个相对圆心的距离称作饱和度Saturation。饱和度的取值是一个从0到100的百分数,0%就是在圆心,100%就是在圆周。

但即使都饱和度为0%的纯灰色,其实也是有层次的,更白一些的灰,或者更黑一些的灰。

这个层次被称作亮度Lightness,也是一个从0到100的百分数,纯白是100%,纯黑是0%。

色相Hue、饱和度Saturation、亮度Lightness这三者组成了一个圆柱型的色彩空间,即HSL,如下图:

HSL的色彩空间
HSL的色彩空间

HSL更加符合我们人类对颜色的感知,所以设计师会更喜欢,因为方便进行调色:比如想要让颜色看起来更加鲜艳一些,就只需调整饱和度这一个参数即可;此外,因为饱和度对任何颜色都适用,就可以将整张图片的饱和度进行统一处理。

随着饱和度增高,红色更红,绿色更绿
随着饱和度增高,红色更红,绿色更绿

相对的,RGB是工程师更加喜欢的颜色表示法,因为它接近于电子设备的底层工作原理。

好的是RGB与HSL之间是可以相互转化的。但转化过程涉及到较为复杂的数学公式,此处不再赘述。

幸运的是在CSS中,是直接支持HSL表示法的,类似于这样:

/* 省略了与颜色不相关的部分代码 */
h1 {
  color: hsl(0, 0%, 20%);
}

div {
  color: hsl(0, 0%, 60%);
}

p {
  color: hsl(0, 0%, 20%);
}

a {
  color: hsl(214, 71.5%, 50.4%);
}

#tag {
  color: hsl(0, 0%, 40%);
}

#tag a {
  background-color: hsl(228, 71.4%, 1.4%);
}
与RGB表示法所使用的颜色一致
与RGB表示法所使用的颜色一致

在网页开发中,还是更加推荐采用RGB表示法。

延伸阅读:透明

其实,还有一种特殊的颜色——透明。

透明不是白,也不是黑,也不是没有颜色。准确的说,透明是一个要求,它要求把背景中颜色混一些进来,组成一个新的颜色。

半透明的球每一处的颜色都是与背景色的混合
半透明的球每一处的颜色都是与背景色的混合

如果前景颜色为A,背景颜色为B,那么混合出的新颜色便可通过这个方程算出来:

αA + (1-α)B

方程里的α(阿尔法)就是混合度,也可以理解为不透明度,取值从0到1。α越低就是要混入更多的背景色,α越高就是要混入更少的背景色。当α=0的时候就完全透明了。

α(阿尔法)不太容易通过键盘输入,所以在CSS中,使用了长得比较像的英文字母a来代替。用下面的方式,可以在RGBHSL的基础上设定透明度:

div {
  color: rgba(255, 0, 0, 0.5) /* 半透明的红色 */
}

p {
  color: hsla(0, 100%, 50%, 0.5) /* 半透明的红色 */
}
我将本课程所有的代码托管在gitee上了,你可以点击这个链接,或到gitee.com上搜索弦五 网页开发入门,查看和获取本课程的全部代码。