当前位置: 首页 > news >正文

【CSS Tricks】在css中尝试一种新的颜色模型HSL

目录

  • 引言
  • 浏览器支持性
  • HSL介绍
  • HSL相较于RGB的优势在哪?
  • HSL在网页设计的应用场景
  • 如何用代码转换hsl
    • RGB转HSL
    • HSL转RGB
    • HEX格式的互转
  • 总结

引言

本篇不会对rgb颜色模型或是hsl颜色模型的显色原理进行深入的探究,仅从前端开发角度去论述在工作中选择哪种比较合适。

  • 大多数电视机、显示器、投影仪通过将不同强度的红、绿、蓝色光混合来生成不同的颜色,这就是RGB三原色的加色法。通过这种方法可以在RGB色彩空间生成大量不同的颜色,然而,这三种颜色分量的取值与所生成的颜色之间的联系并不直观。
  • 艺术家有时偏好使用HSL或HSV而不选择三原色光模式(即RGB模型)或 印刷四分色模式(即CMYK模型),因为它类似于人类感觉颜色的方式,具有较强的感知度。HSL以人类更熟悉的方式封装了关于颜色的信息:“这是什么颜色?深浅如何?明暗如何?”。

浏览器支持性

  • 在Can i use?网站上查询到hsl的支持性结果为:
    caniuse
    目前为止主流的浏览器均支持hsl颜色,所以可以放心使用。

HSL介绍

HLS 有三个分量,hue(色相)、saturation(饱和度)、lightness(亮度)。
在这里插入图片描述

  • hue代表色相(色相环角度),色相的定义中,许多的颜色分布在一个圆环上,取值范围则是 0-360度,每个角度代表着一种颜色。以六大主色为基础,他们分别按 60 度的间隔排列在圆环上。这六大主色分别是:360°/0°红、60°黄、120°绿、180°青、240°蓝、300°洋红。
    在这里插入图片描述

  • saturation代表饱和度。饱和度是指颜色的强度或纯度,使用 0 ~ 100% 的百分比来度量。表示色相中颜色成分所占的比例,数值越大,颜色中的灰色越少,颜色越鲜艳,呈现的是一种从灰色到色相颜色的变化。
    在这里插入图片描述

  • lightness代表亮度,表现颜色的明暗程度,使用 0 ~ 100% 的百分比来度量。反映色彩中混入的黑白两色,50% 处只有纯色,小于 50% 时,数值越小混入的黑色越多,越接近于黑色;大于 50% 时,数值越大混入的白色越多,越接近于白色。
    在这里插入图片描述

  • 一般在css中写法为:hsl( 255, 90%, 50% ) 或是带透明度 hsal( 255, 90%, 50%, 0.5 )。

HSL相较于RGB的优势在哪?

  • 感知相关性:RGB模型中的颜色分量并不直接对应人类对颜色的感知。在RGB中改变一个颜色的单个分量(红、绿或蓝),通常不会产生直观的颜色变化。相比之下,HSL模型的设计更接近人类对颜色的认知,其中色相(Hue)代表颜色的基本色调,饱和度(Saturation)代表颜色的纯度,亮度(Lightness)代表颜色的明暗程度。因此,在需要根据感知调整颜色时,HSL往往更为直观。
  • 颜色混合:当需要混合颜色以获得新的颜色时,使用RGB模型可能不容易预测结果。而在HSL模型中,可以通过较为简单的方式调整颜色的各个方面,如改变色相来得到类似的颜色变化,调整饱和度来控制颜色的鲜艳度等。
  • 计算复杂性:虽然RGB模型直接对应于硬件上的颜色生成,但在需要进行复杂的颜色运算时,如颜色渐变、颜色过滤或者颜色对比度调整等,HSL模型可能提供更加简便的方法。
  • 易于编程和算法实现:对于某些图形处理算法来说,使用HSL模型可以使某些任务变得更简单,比如色彩校正、图像分割和颜色过滤等。

HSL在网页设计的应用场景

  1. 颜色主题生成:使用HSL可以方便地生成一系列颜色,这些颜色共享相同的色相或亮度,但有不同的饱和度,从而创建出和谐的颜色主题。
  2. 生成互补色:使用HSL可以快速的为网站logo或标题icon设置强烈对比的互补色,只需要将hue值+180即可,根据实际需求动态调整。
  3. 交互反馈:在设计交互元素时,可以使用HSL来创建动态的颜色变化,例如当用户悬停或点击按钮时,通过调整饱和度或亮度来提供视觉反馈。
  4. 其实只要是小幅度调整参数即可获得颜色变化的场景都适合使用hsl,hsl带来的好处就是可以更符合直觉的去生成颜色,而不用像rgb一样变换颜色毫无规律。

举个交互反馈的例子:

button{
    background: hsl(200, 50%, 50%); /* 蓝色调背景 */
    transition: background-color 2s;
}
// 仅提高亮度即可提供选中的视觉反馈效果
button:hover {
    background: hsl(200, 50%, 70%); /* 亮一点的蓝色 */
}

如何用代码转换hsl

RGB转HSL

设(r,g,b)分别是一个颜色的红、绿和蓝坐标,它们的值是在0到1之间的实数。设 max等价于(r,g,b)中的最大者。设 min等于这些值中的最小者。要找到在HSL空间中的(r,g,b)值,这里的h∈[0,360)度是角度的色相角,而s,l∈[0,1] 是饱和度和亮度,计算为:
在这里插入图片描述
h的值通常规范化到位于0到360°之间。

以下是js代码实现,返回值为数组,分别对应hue(色相)、saturation(饱和度)、lightness(亮度)。

/**
 * rgb2hsl
 *
 * @param {number} r 红色颜色值 0~255
 * @param {number} g 绿色颜色值 0~255
 * @param {number} b 蓝色颜色值 0~255
 */
function rgb2hsl(r, g, b) {
    r /= 255;
    g /= 255;
    b /= 255;

    const max = Math.max(r, g, b);
    const min = Math.min(r, g, b);
    const diff = max - min;

    let h = 0;
    let l = (max + min) / 2;
    let s = 0;

    if (max === min) {
        h = 0;
    } else if (max === r && g >= b) {
        h = 60 * ((g - b) / diff);
    } else if (max === r && g < b) {
        h = 60 * ((g - b) / diff) + 360;
    } else if (max === g) {
        h = 60 * ((b - r) / diff) + 120;
    } else if (max === b) {
        h = 60 * ((r - g) / diff) + 240;
    };

    if (l === 0 || max === min) {
        s = 0;
    } else if (0 < l && l <= 0.5) {
        s = diff / (2 * l);
    } else if (l > 0.5) {
        s = diff / (2 - 2 * l);
    };

    return [Math.round(h), Math.round(s * 100), Math.round(l * 100)];
}

HSL转RGB

给定HSL空间中的(h,s,l)值定义的一个颜色,h在指示色相角度的值域 [0,360] 中,s和l在饱和度和亮度的值域 [0,1] 中。相应在RGB空间中的(r,g,b)三原色,r,g和b也分别对应于红色、绿色和蓝色的值域[0,1]中,它们可计算为:
首先,如果s=0,则结果的颜色是非彩色的、或灰色的。在这个特殊情况,r,g和b都等于l。注意h的值在这种情况下是未定义的。
当s≠0的时候,可以使用下列过程:
在这里插入图片描述
以下是js代码实现,返回值为数组,分别对应R(红)、g(绿)、b(蓝)。

/**
 * hsl2rgb
 *
 * @param {number} h Hue 色调 0 ~ 360
 * @param {number} s Saturation 饱和度 0 ~ 100
 * @param {number} l Lightness 亮度 0 ~ 100
 */
function hsl2rgb(h, s, l) {
    h /= 360;
    s /= 100;
    l /= 100;

    let r = 0;
    let g = 0;
    let b = 0;
    let p = 0;
    let q = 0;

    function rgb(t, p, q) {
        if (t < 1.0 / 6.0) {
            return p + (q - p) * 6.0 * t;
        } else if (t >= 1.0 / 6.0 && t < 1.0 / 2.0) {
            return q;
        } else if (t >= 1.0 / 2.0 && t < 2.0 / 3.0) {
            return p + (q - p) * ((2.0 / 3.0) - t) * 6.0;
        } else {
            return p;
        }
    }

    function _rgb(t) {
        if (t < 0) {
            return t + 1.0;
        } else if (t > 1) {
            return t - 1.0;
        } else {
            return t;
        }
    }

    if (s === 0) {
        r = g = b = l;
    } else {
        q = l < 0.5 ? l * (1.0 + s) : l + s - l * s;
        p = 2.0 * l - q;
        r = rgb(_rgb(h + 1.0 / 3.0), p, q);
        g = rgb(_rgb(h), p, q);
        b = rgb(_rgb(h - 1.0 / 3.0), p, q);
    }

    return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}

HEX格式的互转

HEX只是由16进制数字代表了0-255,都可以通过rgb作为桥梁去转换hsl格式。
以下是hex和rgb的互转的js实现:

/**
 * rgb2hex
 *
 * @param {number} r 红色颜色值 0~255
 * @param {number} g 绿色颜色值 0~255
 * @param {number} b 蓝色颜色值 0~255
 * @param {number} a 透明度 0~100,默认100
 */
function rgb2hex(r, g, b, a) {
    if (typeof a === 'undefined') {
        a = '';
    }
    else {
        a = Math.round(255 * a / 100);
        a = (a | 1 << 8).toString(16).slice(1);
    }
    const val = ((b | g << 8 | r << 16) | 1 << 24).toString(16).slice(1);
    return val.toUpperCase() + a.toUpperCase();
}

/**
 * hex2rgb
 *
 * @param {string} hex hex颜色值 eg: #000、#325312、#b2c343
 */
function hex2rgb(hex) {
    hex = hex.replace(/^#/, '');

    let a = null;

    if (hex.length === 8) {
        a = parseInt(hex.slice(6, 8), 16) / 255;
        hex = hex.slice(0, 6);
    }

    if (hex.length === 4) {
        a = parseInt(hex.slice(3, 4).repeat(2), 16) / 255;
        hex = hex.slice(0, 3);
    }

    if (hex.length === 3) {
        hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
    }

    const num = parseInt(hex, 16);
    const r = num >> 16;
    const g = (num >> 8) & 255;
    const b = num & 255;
    const rgb = [r, g, b];

    if (a !== null) {
        rgb.push(Math.round(a * 100));
    }

    return rgb;
}

总结

在日常开发过程中,大多数情况下UI提供的颜色值为rgb或者hex格式,有些设计网站会直接提供hsl格式的色值。通过这篇文章主要想阐述一个事实,那就是hsl相对于rgb在前端开发领域是有很大优势的,尤其是编码层面上。使用hsl会使css的编码更加清晰,得到的颜色大概率不会偏离预期。可能现阶段大家用的不是很多,所以会有所抵触,在使用一段时间后,相信你会爱上这种颜色模式。

相关文章:

  • 向日葵好用吗?4款稳定的远程控制软件推荐。
  • C++ : 继承问题 [virtual函数调用,为什么禁止在virtual使用默认参数]
  • 深入探讨IDSIPS:信息安全的未来趋势与应用
  • Python | Leetcode Python题解之第401题二进制手表
  • 代码管理-使用TortoiseGit同步项目到Github/Gitee
  • 近期值得关注的3个线性时序模型及其未来发展综述
  • html加载页面
  • XWiki中添加 html 二次编辑失效
  • C++初阶学习第六弹------标准库中的string类
  • 微信小程序页面制作——婚礼邀请函(含代码)
  • linux 解压缩
  • sql server 分区表查询
  • Android 12系统源码_窗口管理(八)WindowConfiguration的作用
  • springboot通过tomcat部署项目(包含jar、war两种方式,迄今为止全网最详细!2024更新..建议收藏,教学!万字长文!)
  • 二叉树的链式结构和递归程序的递归流程图
  • JavaScript substring() 方法
  • 关于循环Socket创建超Linux文件句柄限制现象分析
  • Etcd权限认证管理
  • HTML——基本标签
  • Basler 相机与LabVIEW进行集成
  • 外交部:各方应为俄乌双方恢复直接对话创造条件
  • 黄仕忠丨戏曲文献研究之回顾与展望
  • 山西临汾哪吒主题景区回应雕塑被指抄袭:造型由第三方公司设计
  • 央媒评网红质疑胖东来玉石定价暴利:对碰瓷式维权不能姑息
  • 体坛联播|C罗儿子完成国家队首秀,德约结束与穆雷合作
  • 印称印巴军事行动总指挥同意将局势降级