css之RGB和HSL颜色模型

css常用颜色定义

  • 预定义的颜色名称:简单直观,颜色数量有限,语义不明确。
  • 十六进制:使用 # 开头,后跟 3 位或 6 位十六进制数表示红、绿、蓝通道值。简洁紧凑,浏览器兼容性最佳,可读性差,难以直接理解颜色属性。
  • RGB/RGBA:通过红、绿、蓝通道值定义颜色,可附加透明度(Alpha 通道)。直观反映红绿蓝三原色的数值关系,物理意义明确,与屏幕显示原理一致。
  • HSL/HSLA:通过色相(Hue)、饱和度(Saturation)、明度(Lightness)定义颜色。色相单位:角度。饱和度、明度单位:%。符合人类对颜色的直觉描述,方便动态调整颜色属性。



<style>
  div span {
    display: inline-block;
    width: 100px;
    height: 100px;
    line-height: 100px;
    font-size: 0.5rem;
    text-align: center;
    border: 1px solid silver;
    margin: 2px;
  }
</style>
<div>
  <span style="background-color: aliceblue">aliceblue</span>

  <span style="background-color: #00ffff">#00ffff</span>

  <span style="background-color: rgb(0, 255, 255)">rgb(0, 255, 255)</span>
  <span style="background-color: rgb(0, 255, 255, 0.5)">rgb(0, 255, 255, 0.5)</span>

   <span style="background-color: hsl(180, 100%, 50%)">hsl(180, 50%, 50%)</span>
  <span style="background-color: hsl(180, 100%, 50%, 0.5)">hsl(180, 50%, 50%, 0.5)</span>
</div>

常见颜色值

<div>
  <span style="background-color: #ff0000">#ff0000</span>
  <span style="background-color: #ffff00">#ffff00</span>
  <span style="background-color: #00ff00">#00ff00</span>
  <span style="background-color: #00ffff">#00ffff</span>
  <span style="background-color: #0000ff">#0000ff</span>
  <span style="background-color: #ff00ff">#ff00ff</span>
</div>

<div>
  <span style="background-color: rgb(255, 0, 0)">rgb(255, 0, 0)</span>
  <span style="background-color: rgb(255, 255, 0)">rgb(255, 255, 0)</span>
  <span style="background-color: rgb(0, 255, 0)">rgb(0, 255, 0)</span>
  <span style="background-color: rgb(0, 255, 255)">rgb(0, 255, 255)</span>
  <span style="background-color: rgb(0, 0, 255)">rgb(0, 0, 255)</span>
  <span style="background-color: rgb(255, 0, 255)">rgb(255, 0, 255)</span>
</div>

<div>
  <span style="background-color: hsl(0, 100%, 50%)">hsl(0, 100%, 50%)</span>
  <span style="background-color: hsl(60, 100%, 50%)">hsl(60, 100%, 50%)</span>
  <span style="background-color: hsl(120, 100%, 50%)">hsl(120, 100%, 50%)</span>
  <span style="background-color: hsl(180, 100%, 50%)">hsl(180, 100%, 50%)</span>
  <span style="background-color: hsl(240, 100%, 50%)">hsl(240, 100%, 50%)</span>
  <span style="background-color: hsl(300, 100%, 50%)">hsl(300, 100%, 50%)</span>
</div>

HSL颜色配色

<div>
  <!-- 高饱和度+高明度	活泼、轻盈 -->
  <span style="background-color: hsl(222, 80%, 80%)">hsl(240, 80%, 80%)</span>
  <!-- 高饱和度+低明度	沉稳、力量感  -->
  <span style="background-color: hsl(222, 80%, 30%)">hsl(240, 80%, 30%)</span>
  <!-- 低饱和度+高明度	柔和、干净 -->
  <span style="background-color: hsl(222, 30%, 90%)">hsl(240, 30%, 90%)</span>
  <!-- 低饱和度+低明度	内敛、高级灰 -->
  <span style="background-color: hsl(222, 20%, 40%)">hsl(240, 20%, 40%)</span>
</div>

弱对比过渡 :相近饱和度+相近明度

<div>
  <span style="background-color: hsl(222, 60%, 50%)">hsl(180, 60%, 50%)</span>
  <span style="background-color: hsl(222, 50%, 60%)">hsl(180, 50%, 60%)</span>
</div>

主次分明: 主体元素使用中高饱和度,次要元素降低饱和度或提升明度,形成焦点差异

<div>
  <span style="background-color: hsl(222, 70%, 40%)">hsl(180, 70%, 40%)</span>
  <span style="background-color: hsl(222, 40%, 60%)">hsl(180, 40%, 60%)</span>
</div>

渐变层次:同一色相下,按「明度阶梯」或「饱和度阶梯」生成渐变色

<div>
  <span style="background-color: hsl(222, 100%, 17%)">hsl(222, 100%, 17%)</span>
  <span style="background-color: hsl(222, 72%, 29%)">hsl(222, 72%, 29%)</span>
  <span style="background-color: hsl(222, 50%, 45%)">hsl(222, 50%, 45%)</span>
  <span style="background-color: hsl(222, 55%, 62%)">hsl(180, 55%, 62%)</span>
  <span style="background-color: hsl(222, 100%, 83%)">hsl(180, 100%, 83%)</span>
</div>

HSL、RGB、十六进制颜色转换

算法说明及原理略,算法来自于AI生成

<script src="../plugins/alpine.min.js"></script>
<script>
  function colorPicker() {
    return {
      hex: "#2a5298",

      hue: null,
      saturation: null,
      lightness: null,

      get hslColor() {
        return `hsl(${this.hue}, ${this.saturation}%, ${this.lightness}%)`;
      },

      // 自动文字颜色计算
      get textColor() {
        return this.lightness > 50 ? "#000" : "#fff";
      },

      get rgbColor() {
        return this.hslToRgb(this.hue, this.saturation, this.lightness);
      },

      hslToRgb(h, s, l) {
        // 将输入值归一化到0-1范围
        h = h / 360;
        s = s / 100;
        l = l / 100;

        // 处理饱和度为零的特殊情况(灰色)
        if (s === 0) {
          const gray = Math.round(l * 255);
          return [gray, gray, gray];
        }

        // 计算中间变量
        const temp2 = l < 0.5 ? l * (1 + s) : l + s - l * s;
        const temp1 = 2 * l - temp2;

        // 将色相转换为0-1的六段式值
        const hueToSegment = (hue) => {
          hue = hue < 0 ? hue + 1 : hue > 1 ? hue - 1 : hue;
          if (hue * 6 < 1) return temp1 + (temp2 - temp1) * hue * 6;
          if (hue * 2 < 1) return temp2;
          if (hue * 3 < 2) return temp1 + (temp2 - temp1) * (2 / 3 - hue) * 6;
          return temp1;
        };

        // 计算三个颜色通道
        let r = hueToSegment(h + 1 / 3);
        let g = hueToSegment(h);
        let b = hueToSegment(h - 1 / 3);
        r = Math.round(r * 255);
        g = Math.round(g * 255);
        b = Math.round(b * 255);

        this.hex = this.rgbToHex(r, g, b);
        return `rgb(${r},${g},${b})`;
      },

      hexToHsl() {
        // 移除可能存在的#号
        let hex = this.hex.replace(/^#/, "");

        // 处理3位缩写形式(如#fff → #ffffff)
        if (hex.length === 3) {
          hex = hex
            .split("")
            .map((c) => c + c)
            .join("");
        }

        // 解析RGB分量(十六进制转十进制)
        let r = parseInt(hex.substring(0, 2), 16);
        let g = parseInt(hex.substring(2, 4), 16);
        let b = parseInt(hex.substring(4, 6), 16);

        (r /= 255), (g /= 255), (b /= 255);
        const max = Math.max(r, g, b),
          min = Math.min(r, g, b);
        let h,
          s,
          l = (max + min) / 2;

        if (max === min) {
          h = s = 0;
        } else {
          const d = max - min;
          s = d / (1 - Math.abs(2 * l - 1));
          switch (max) {
            case r:
              h = ((g - b) / d + (g < b ? 6 : 0)) * 60;
              break;
            case g:
              h = ((b - r) / d + 2) * 60;
              break;
            case b:
              h = ((r - g) / d + 4) * 60;
              break;
          }
        }
        this.hue = Math.round(h);
        this.saturation = Math.round(s * 100);
        this.lightness = Math.round(l * 100);
      },

      rgbToHex(r, g, b) {
        // 数值处理:四舍五入 + 范围限定 [0-255]
        const clamp = (value) => {
          const intValue = Math.round(Number(value));
          return Math.min(255, Math.max(0, intValue));
        };

        // 转换单通道为两位十六进制
        const toHex = (value) => {
          const hex = clamp(value).toString(16);
          return hex.padStart(2, "0"); // 自动补零
        };

        return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
      },
    };
  }
</script>
<div x-data="colorPicker()" :style="`background-color: ${hslColor}; color: ${textColor}`" x-effect="hexToHsl()">
  <dl>
    <dt>16进制颜色</dt>
    <dd><input type="text" x-model="hex" /></dd>
  </dl>

  <!-- 色相控制 -->
  <dl>
    <dt>色相 Hue</dt>
    <dd><input type="range" x-model="hue" min="0" max="360" /> <input type="number" x-model="hue" min="0" max="360" /></dd>
  </dl>

  <!-- 饱和度控制 -->
  <dl>
    <dt>饱和度 Saturation</dt>
    <dd><input type="range" x-model="saturation" min="0" max="100" /> <input type="number" x-model="saturation" min="0" max="100" /></dd>
  </dl>

  <!-- 明度控制 -->
  <dl>
    <dt>明度 Lightness</dt>
    <dd><input type="range" x-model="lightness" min="0" max="100" /> <input type="number" x-model="lightness" min="0" max="100" /></dd>
  </dl>

  <!-- 颜色代码显示 -->
  <div>当前HSL颜色:<span x-text="hslColor"></span></div>
  <div>当前RGB颜色:<span x-text="rgbColor"></span></div>
</div>

不同HSL色相下的配色

<style>
  div span {
    display: inline-block;
    width: 100px;
    height: 100px;
    line-height: 100px;
    font-size: 0.5rem;
    text-align: center;
    border: 1px solid silver;
    margin: 2px;
  }
</style>
<script src="../plugins/alpine.min.js"></script>
<script>
  function huePicker() {
    return {
      hue: 220,
    };
  }
</script>
<div x-data="huePicker()" :style="`background-color: hsl(${hue}, 50%, 45%); color: #fff`">
  <dl>
    <dt>色相 Hue</dt>
    <dd><input type="range" x-model="hue" min="0" max="360" /> <input type="number" x-model="hue" min="0" max="360" /></dd>
  </dl>

  <div>
    <span :style="`background-color: hsl(${hue}, 100%, 17%);`" x-text="`hsl(${hue}, 100%, 17%)`"></span>
    <span :style="`background-color: hsl(${hue}, 72%, 29%);`" x-text="`hsl(${hue}, 50%, 45%)`"></span>
    <span :style="`background-color: hsl(${hue}, 55%, 62%);`" x-text="`hsl(${hue}, 50%, 45%)`"></span>
    <span :style="`background-color: hsl(${hue}, 100%, 83%);`" x-text="`hsl(${hue}, 50%, 45%)`"></span>
  </div>
</div>

自义定css变量切换不同的颜色

<style>
  /* 定义CSS变量‌ */
  /* ‌语法‌:--变量名: 值; */

  /* 全局定义‌:通常在 :root 伪类中定义全局变量(相当于HTML根元素) */
  :root {
    --primary-color: hsl(222, 55%, 62%);
    --font-normal: 16px;
    --font-color: black;
    --spacing: 10px;
  }

  /* 作用域‌:变量定义在选择器内,作用域为该元素及其子元素。 */
  .theme1 {
    --primary-color: hsl(222, 100%, 17%);
    --font-color: white;
  }

  .theme2 {
    --primary-color: hsl(222, 72%, 29%);
    --font-color: white;
  }

  .text-con {
    display: inline-block;
    width: 100px;
    height: 100px;
    line-height: 100px;
    text-align: center;
    margin: 10px;
    font-size: var(--font-normal);
    background-color: var(--primary-color);
    color: var(--font-color);
    padding: var(--spacing);
    border-radius: 5px;
  }
</style>
<script>
  function alterGlobalCssVar() {
    // 修改全局变量
    document.documentElement.style.setProperty("--primary-color", "#2a5298");
  }

  function alterCssVar() {
    // 修改局部变量
    document.querySelector(".theme1").style.setProperty("--primary-color", "#2a5298");
    document.querySelector(".theme2").style.setProperty("--primary-color", "#2a5298");
  }

  function changeTheme(class_name) {
    document.querySelector("#show").classList.toggle(class_name);
  }
</script>

<div>
  <span class="text-con" id="show">原始颜色</span>
  <span class="text-con theme1">主题1</span>
  <span class="text-con theme2">主题2</span>
  <br />

  <button onclick="alterGlobalCssVar()">修改全局CSS颜色变量</button>
  <button onclick="alterCssVar()">修改局部CSS颜色变量</button>
  <button onclick="changeTheme('theme1')">切换主题1</button>
  <button onclick="changeTheme('theme2')">切换主题2</button>
</div>
posted @ 2025-05-07 15:21  carol2014  阅读(63)  评论(0)    收藏  举报