惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
美团技术团队
Last Week in AI
Last Week in AI
WordPress大学
WordPress大学
博客园 - 三生石上(FineUI控件)
博客园 - 聂微东
雷峰网
雷峰网
阮一峰的网络日志
阮一峰的网络日志
博客园 - 叶小钗
IT之家
IT之家
Google DeepMind News
Google DeepMind News
D
Docker
J
Java Code Geeks
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 【当耐特】
V
V2EX
Hugging Face - Blog
Hugging Face - Blog
博客园 - Franky
月光博客
月光博客
宝玉的分享
宝玉的分享
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活
是时候介绍这几个全新的CSS颜色函数了 « 张鑫旭-鑫空间-鑫生活
张鑫旭,zhangxinxu · 2023-02-19 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=10728 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

调色板占位图CSS颜色

今天打开caniuse查了下,几个全新的颜色函数Chrome浏览器也支持了,这可是为数不多的落后Safari浏览器支持数年(2023年 vs 2021年)的CSS新特性了。

Chrome浏览器支持LCH

与此同时,Firefox浏览器也已经开启“实验支持”,说明这几个颜色函数被所有现代浏览器支持已经是板上钉钉的事情了,这就意味着时机成熟,可以好好介绍这几个全新的CSS颜色函数了。

一、最先支持的hwb()色值

hwb()色值是这批颜色函数(CSS Level 4 Color Module)中最早支持的,兼容性如下图所示:

hwb()颜色模型

HWB颜色模型是RGB颜色模型中点的圆柱坐标表示,类似于HSL和HSV。它是由HSV的创建者阿尔维·雷·史密斯于1996年开发的,以解决HSV的一些问题,相对而言,HWB对人类而言要更加直观,计算速度也更快一些。

此颜色模型使用的时候先选择一个主色,然后再和白色和(或)黑色“混合”以产生所需的颜色。其中,第一个坐标H(色调)与HSL和HSV中的色调坐标相同,而后面的W和B分别代表白度和黑度,范围为0–100%(或0–1)。

下图示意的就是不同H、W、B值下的色块显示图。

色块显示示意图

由于HWB更符合人类的直观认知,因此,HWB模型的颜色更容易脑补出来。

例如 hwb(0 0% 30%),就是红色加入30%的黑色,效果就是偏深一点的红色。

实际渲染效果如下所示(实时渲染,若无效果,多半非原站):

案例演示

为了方便大家体验HWB颜色效果,我做了个演示页面,您可以狠狠地点击这里:CSS HWB()颜色函数渲染demo

拖动滑块,可以看到对应的颜色变化效果。

如下GIF录屏所示:

hwb颜色变化示意

颜色转换

下面展示下如何使用JS实现 RGB 和 HWB 之间的颜色转换(出自这里)。

// RGB [0, 255]
// HWB [0, 1]
function rgb2hwb(r, g, b) {
  
  r /= 255;
  g /= 255;
  b /= 255;
  
  var f, i,
      w = Math.min(r, g, b);
      v = Math.max(r, g, b);
      black = 1 - v;
  
  if (v === w) return {h: 0, w: w, b: black};
  f = r === w ? g - b : (g === w ? b - r : r - g);
  i = r === w ? 3 : (g === w ? 5 : 1);

  return {h: (i - f / (v - w)) / 6, w: w, b: black}
}

// HWB [0, 1]
// RGB [0, 255]
function hwb2rgb(h, w, b) {
  
  h *= 6;
  
  var v = 1 - b, n, f, i;
  if (!h) return {r:v, g:v, b:v};
  i = h|0;
  f = h - i;
  if (i & 1) f = 1 - f;
  n = w + f * (v - w);
  v = (v * 255)|0;
  n = (n * 255)|0;
  w = (w * 255)|0;

  switch(i) {
    case 6:
    case 0: return {r:v, g:n, b: w};
    case 1: return {r:n, g:v, b: w};
    case 2: return {r:w, g:v, b: n};
    case 3: return {r:w, g:n, b: v};
    case 4: return {r:n, g:w, b: v};
    case 5: return {r:v, g:w, b: n};
  }
}

//zxx: 传统色值,如rgb, hsl #RRGGBB之间的颜色转换JS可以访问我之前这篇文章:“JS HEX十六进制与RGB, HSL颜色的相互转换”。

二、lch()和lab()函数

lch()和lab()颜色函数都是基于CIE LAB颜色空间定义的,是一种更符合人类感知的颜色表示方式,这两种颜色函数提供比通常RGB颜色空间更宽广的颜色范围。

lch()函数

LCH函数三个字母分别表示:

L: 明度(Lightness),0%~100%
C: 彩度(Chroma),0~ ∞
H: ⾊相(Hue),0~360(隐藏单位是角度单位deg)

LCH颜色示意

如果要判断一个水果是否新鲜诱人,则最适合的颜色函数就是lch()函数,因为明度、彩度对应的就是水果表面是否反光,颜色是否饱满等。

使用示意:

lch(29.2345% 44.2 27);
lch(52.2345% 72.2 56.2);
lch(52.2345% 72.2 56.2 / .5);

对应的颜色分别如下所示(不支持的浏览器背景灰色):

lab()函数

LAB函数三个字母分别表示:

L: 明度(Lightness),0%~100%
A: 颜⾊通道,从深绿⾊(低亮度)到灰⾊(中亮度)再到亮粉红⾊(⾼亮度),是Lab颜色空间中沿a轴的距离。
B: 颜⾊通道,从亮蓝⾊(低亮度)到灰⾊(中亮度)再到⻩⾊(⾼亮度),Lab颜色空间中沿b轴的距离(见下图示意)。

lab颜色空间示意

Lab颜色空间最大的优点是其可以在不同的软件中使用同一种量化颜色,也就是Lab颜色空间与设备无关,这在印刷中非常受用,可以抹消印刷中的颜色偏差,从而实现设计同步。

使用示意:

lab(29.2345% 39.3825 20.0664);
lab(52.2345% 40.1645 59.9971);
lab(52.2345% 40.1645 59.9971 / .5);

对应的颜色分别如下所示(实时渲染,若无效果,多半非原站):

LAB历史小背景

1900年代,理查德·亨特发明了LAB色彩空间。尽管它能够消除颜色的微小变化并保持均匀性,但它从未被接受为标准。

几年后,CIE推出了一个名为CIElab的实验室的更新版本。它发音为c-lab,但也被称为lab或L*A*B*。

CIElab是无许可证和版权的,因此您可以在任何设备上使用它。

颜色转换

LAB颜色和LCH颜色之间的转换其实还挺简单的,因为至少L是一样的,不变,下面就是代码示意:

function lab2lch(labL, labA, labB) {
    const [ lchC, lchH ] = [
        Math.sqrt(Math.pow(labA, 2) + Math.pow(labB, 2)), // 转换为 chroma
        (Math.atan2(labB, labA)) * 180 / Math.PI // 转换为 hue,角度值
    ];
    return [ labL, lchC, lchH ];
}

function lch2lab(lchL, lchC, lchH) {
    const [ labA, labB ] = [
        lchC * Math.cos(lchH * Math.PI / 180),
        lchC * Math.sin(lchH * Math.PI / 180)
    ];
    return [ lchL, labA, labB ];
}

console.log(lab2lch(0.292345, 39.3825, 20.0664));
console.log(lch2lab(0.292345, 44.2, 27));

输出结果是:

输出结果示意

符合预期。

三、指定颜色空间函数color()

CSS color()函数允许浏览器在显示任何的颜色空间,例如P3颜色空间,它可以显示默认sRGB颜色空间之外的颜色。

其语法如下,第一个参数就是用来指定所使用的颜色空间的。

color( [ [ | ]? [ + ] [ /  ]? ] )

简化下就是:

color(颜色空间 颜色数值 / 透明度);

支持的颜色空间包括下面这些:

display-p3
srgb
rec2020
prophoto-rgb
srgb-linear
a98-rgb

下面通过一个实例看下各自支持的效果,下面是演示代码:

<ul>
    <li class="color1">第1项 - display-p3</li>
    <li class="color2">第2项 - rec2020</li>
    <li class="color3">第3项 - xyz-d50</li>
    <li class="color4">第4项 - srgb</li>
    <li class="color5">第5项 - prophoto-rgb</li>
</ul>
.color1 {
    color: color(display-p3 1 0.5 0);
}
.color2 {
    color: color(rec2020 0.42053 0.979780 0.00579);
}
.color3 {
    color: color(xyz-d50 0.2005 0.14089 0.4472);
}
.color4 {
    color: color(srgb 0.691 0.139 0.259);
}
.color5 {
    color: color(prophoto-rgb 0.691 0.139 0.259);
}

结果在浏览器中(注意自己的Chrome浏览器版本,需要Chrome 111+)每个列表都有了颜色变化(如果浏览器不支持,会是默认的黑色):

color()函数效果示意

眼见为实,您可以狠狠地点击这里:CSS color()函数与颜色空间demo

颜色空间的自定义

除了浏览器内置的这些经典的颜色空间,我们还可以自已颜色空间,这个是使用@color-profile规则实现的,使用示意(案例源自MDN文档):

@color-profile --swop5c {
  src: url("https://example.org/SWOP2006_Coated5v2.icc");
}
.header {
  background-color: color(--swop5c 0% 70% 20% 0%);
}

颜色空间的检测

颜色空间是否被当前浏览器支持可以使用color-gamut查询实现,使用示意:

@media (color-gamut: srgb) {
  p {
    background: #f5f3f9;
  }
}

此查询语句目前所有现代浏览器都支持。

color-gamut兼容性

兼容性

color()函数Firefox目前似乎还没有支持,Chrome已经完全支持了。

color()函数兼容性

四、颜色混合函数color-mix()

color-mix()函数可以让两个颜色进行指定比例的混合。

使用示意:

color-mix(in lch, purple 40%, gold);
color-mix(in srgb, #34c9eb 20%, white);

实时渲染效果如下所示(如果背景灰色则说明浏览器并不支持):

我们日常开发,就使用in srgb就可以了,最常用,上手成本低。

此颜色函数我期盼已久,挺实用的,我过段时间,等Safari和Firefox浏览器也完全支持的时候(目前是实验支持),会专门详细介绍下。

color-mix兼容性示意

五、了解oklch()和oklab()函数

oklch()和oklab()函数目前仅Safari15.4+支持,因此,大家暂时先了解下即可。

oklch()颜色空间和lch()函数区别在于,oklch()的C(彩度)和H(色调)使用的是极坐标系。

其中第二个值C的它的最小值为0,而最大值理论上是无限的(但实际上不超过0.4)。

使用示意:

oklch(40.1% 0.123 21.57)
oklch(59.69% 0.156 49.77)
oklch(59.69% 0.156 49.77 / .5)

oklab()函数

oklab()函数表示的颜色使用的是oklab颜色空间,它试图模拟人眼如何感知颜色。

oklab()在oklab颜色空间的a轴和b轴上使用的是笛卡尔坐标系。如果您想要极坐标系、或者使用彩度和色调表示颜色,请使用oklch()函数。

使用示意:

/* oklab(lightness a-axis b-axis) */
oklab(40.1% 0.1143 0.045);
oklab(59.69% 0.1007 0.1191);

/* oklab(lightness a-axis b-axis / Alpha) */
oklab(59.69% 0.1007 0.1191 / 0.5);

六、关于颜色更多知识

除了以前这些颜色函数,CSS颜色规范level4中还有几个新特性浏览器很早就支持了,例如#RRGGBBAA色值表示,以及更加自由的rgb和hsl颜色表示方法,详见之前写的这篇文章:“快速学习CSS Color Level 4的色值新语法”。

本文所介绍的这些时间函数,除了hwb()还有点眼缘,color-mix()函数值得期待外,其他几个颜色函数,我相信大家日常开发都是没多少机会接触的。

就我个人感觉,相比颜色函数,CSS新支持的那些数学函数要实用的多,例如exp(),round(), sin(), hypot(), abs() 等,很多,十来个有的,我查了下,Safari和Firefox111已经都支持,Chrome111也开始支持部分数学函数。

CSS果然是越来越强了,能做的事情也越来越多的。

不过短期还是看不到CSS地位的崛起,因为转变是需要时间的,人都是有惯性的,以前JS能够搞定的且运行良好的事情,是很难有动力去换成一个全新的未知的可能有风险的新事物的。

……这需要时间。

好,以上就是本文的全部内容了,博闻强识,拓展视野。

?❤️????

本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=10728

(本篇完)