RGB、HEX、HSL、RGBA、HSLA 傻傻分不清楚?一文详解 CSS 的各种颜色单位

354 阅读3分钟

在前端开发中,颜色是设计和用户体验的重要组成部分。

CSS 提供了多种方式来定义颜色,比如我们常见的 RGBHEXHSLRGBAHSLA 等。

很多兄弟们在实际使用中一般都是逮到一种用,我也如此,但是看到别人写的代码时候有点儿小懵逼。

所以我们详细了解一下这些颜色单位的原理、用法以及它们之间的区别,帮助咱们彻底理清思路。

基本概念:颜色模型与颜色格式的区别

首先,我们需要明确两个概念:

  • 颜色模型(Color Model):是指描述颜色的数学方式,例如 RGB 和 HSL。
  • 颜色格式(Color Format):是具体实现颜色模型的方式,例如 HEX 是对 RGB 模型的一种十六进制表达形式。

RGB —— 最基础的颜色表示方式

RGB 表示 Red(红)、Green(绿)、Blue(蓝),是一种基于加色法的颜色模型(加色模型中的三原色)。

通过不同强度的红、绿、蓝三原色组合,可以表示出各种颜色。就好像调色盘里面增减颜色来创建出各种颜色。

color: rgb(255, 0, 0); /* 红色 */

每个通道的取值范围为 0~255,其中:

  • 0, 0, 0 表示黑色;
  • 255, 255, 255 表示白色;
  • 255, 0, 0 表示纯红色。

特点

  • 直观但不易调整色调;
  • 可读性一般,需要记住数字含义;

rgb.gif

HEX —— 更简洁的十六进制写法

HEX 就是 RGB 颜色的十六进制表示方式。

/* 红色 */
color: #ff0000; 

/* 重复的可以简写 */
color: #f00;

特点

  • 更紧凑,适合代码书写;
  • 不支持透明度;

hex.gif

HSL —— 更符合人眼感知的颜色模型

HSL 表示 Hue(色相)、Saturation(饱和度)、Lightness(亮度)。

它从人类视觉的角度出发,更易于理解和调整颜色。

color: hsl(0, 100%, 50%); /* 红色 */

各参数含义如下:

  • Hue(色相):0~360 度,代表色轮上的角度;
  • Saturation(饱和度):0% 表示灰色,100% 表示完全饱和;
  • Lightness(亮度):0% 表示黑色,100% 表示白色,50% 是正常亮度。

特点

  • 更容易调节颜色的明暗、饱和度;
  • 对设计师友好,适合配色方案调整;

hsl.gif

RGBA —— 升级方案(加入透明度)

在 RGB 基础上增加了一个 alpha 通道,表示透明度。

color: rgba(255, 0, 0, 0.5); /* 半透明红色 */
  • 第四个参数是透明度(alpha),取值范围为 0(完全透明)1(完全不透明)

rgba.gif

HSLA —— 升级方案(加入透明度)

在 HSL 基础上增加了一个 alpha 通道,表示透明度。

color: hsla(0, 100%, 50%, 0.5); /* 半透明红色 */

特点

  • 可以创建半透明效果;
  • 更灵活地控制视觉层次;

hsla.gif

<template>
    <div class="slider-result">
        <div class="card-wrap">
            <div class="card-head" :style="{backgroundColor: `rgb(${valueR}, ${valueG}, ${valueB})`}">
                {{ `rgb(${valueR}, ${valueG}, ${valueB})` }}
            </div>
            <el-form label-width="30px" label-position="left" label-suffix=":">
                <el-form-item label="R">
                    <el-slider v-model="valueR" :min="0" :max="255" />
                </el-form-item>
                <el-form-item label="G">
                    <el-slider v-model="valueG" :min="0" :max="255" />
                </el-form-item>
                <el-form-item label="B">
                    <el-slider v-model="valueB" :min="0" :max="255" />
                </el-form-item>
            </el-form>
        </div>

        <div class="card-wrap">
            <div class="card-head" :style="{backgroundColor: `#${decimalToHexadecimal(valueH)}${decimalToHexadecimal(valueE)}${decimalToHexadecimal(valueX)}`}">
                {{`#${decimalToHexadecimal(valueH)}${decimalToHexadecimal(valueE)}${decimalToHexadecimal(valueX)}`}}
            </div>
            <el-form label-width="30px" label-position="left" label-suffix=":">
                <el-form-item label="H">
                    <el-slider v-model="valueH" :min="0" :max="255" />
                </el-form-item>
                <el-form-item label="E">
                    <el-slider v-model="valueE" :min="0" :max="255" />
                </el-form-item>
                <el-form-item label="X">
                    <el-slider v-model="valueX" :min="0" :max="255" />
                </el-form-item>
            </el-form>
        </div>

        <div class="card-wrap">
            <div class="card-head" :style="{backgroundColor: `hsl(${valueH1}, ${valueS}%, ${valueL}%)`}">
                {{`hsl(${valueH1}, ${valueS}%, ${valueL}%)`}}
            </div>
            <el-form label-width="30px" label-position="left" label-suffix=":">
                <el-form-item label="H">
                    <el-slider v-model="valueH1" :min="0" :max="360" />
                </el-form-item>
                <el-form-item label="S">
                    <el-slider v-model="valueS" :min="0" :max="100" />
                </el-form-item>
                <el-form-item label="L">
                    <el-slider v-model="valueL" :min="0" :max="100" />
                </el-form-item>
            </el-form>
        </div>

        <div class="card-wrap">
            <div class="card-head" :style="{backgroundColor: `rgba(${valueR}, ${valueG}, ${valueB}, ${valueA})`}">
                {{ `rgba(${valueR}, ${valueG}, ${valueB}, ${valueA})` }}
            </div>
            <el-form label-width="30px" label-position="left" label-suffix=":">
                <el-form-item label="R">
                    <el-slider v-model="valueR" :min="0" :max="255" />
                </el-form-item>
                <el-form-item label="G">
                    <el-slider v-model="valueG" :min="0" :max="255" />
                </el-form-item>
                <el-form-item label="B">
                    <el-slider v-model="valueB" :min="0" :max="255" />
                </el-form-item>
                <el-form-item label="A">
                    <el-slider v-model="valueA" :min="0" :max="1" :step="0.01" />
                </el-form-item>
            </el-form>
        </div>

        <div class="card-wrap">
            <div class="card-head" :style="{backgroundColor: `hsla(${valueH1}, ${valueS}%, ${valueL}%, ${valueA1})`}">
                {{`hsla(${valueH1}, ${valueS}%, ${valueL}%), ${valueA1}`}}
            </div>
            <el-form label-width="30px" label-position="left" label-suffix=":">
                <el-form-item label="H">
                    <el-slider v-model="valueH1" :min="0" :max="360" />
                </el-form-item>
                <el-form-item label="S">
                    <el-slider v-model="valueS" :min="0" :max="100" />
                </el-form-item>
                <el-form-item label="L">
                    <el-slider v-model="valueL" :min="0" :max="100" />
                </el-form-item>
                <el-form-item label="A">
                    <el-slider v-model="valueA1" :min="0" :max="1" :step="0.01" />
                </el-form-item>
            </el-form>
        </div>
    </div>
</template>

<script>

export default {
    name: 'SliderResult',
    data(){
        return {
            valueR: 0,
            valueG: 0,
            valueB: 0,
            valueH: 0,
            valueE: 0,
            valueX: 0,
            valueH1: 0,
            valueS: 0,
            valueL: 0,
            valueA: 0,
            valueA1: 0
        }
    },
    computed: {
        rgbResult() {
            return {
                r: this.valueR,
                g: this.valueG,
                b: this.valueB
            }
        }
    },
    methods: {
        decimalToHexadecimal(decimalNumber) {
            if (typeof decimalNumber !== 'number' || decimalNumber < 0 || !Number.isInteger(decimalNumber)) {
                return '无效输入,请输入一个非负整数。';
            }
            return decimalNumber.toString(16).toUpperCase();
        }
    }
}
</script>

<style scoped>
.slider-result {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 10px;
}

.card-wrap {
    width: 300px;
    border: 1px solid #ddd;
    border-radius: 6px;
    padding: 12px;
    box-sizing: border-box;
    margin-bottom: 10px;
}

.card-head {
    width: 100%;
    height: 120px;
    text-align: center;
    line-height: 120px;
}
</style>