在前端开发中,颜色是设计和用户体验的重要组成部分。
CSS 提供了多种方式来定义颜色,比如我们常见的 RGB
、HEX
、HSL
、RGBA
和 HSLA
等。
很多兄弟们在实际使用中一般都是逮到一种用,我也如此,但是看到别人写的代码时候有点儿小懵逼。
所以我们详细了解一下这些颜色单位的原理、用法以及它们之间的区别,帮助咱们彻底理清思路。
基本概念:颜色模型与颜色格式的区别
首先,我们需要明确两个概念:
- 颜色模型(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
表示纯红色。
特点
- 直观但不易调整色调;
- 可读性一般,需要记住数字含义;
HEX —— 更简洁的十六进制写法
HEX 就是 RGB 颜色的十六进制表示方式。
/* 红色 */
color: #ff0000;
/* 重复的可以简写 */
color: #f00;
特点
- 更紧凑,适合代码书写;
- 不支持透明度;
HSL —— 更符合人眼感知的颜色模型
HSL 表示 Hue(色相)、Saturation(饱和度)、Lightness(亮度)。
它从人类视觉的角度出发,更易于理解和调整颜色。
color: hsl(0, 100%, 50%); /* 红色 */
各参数含义如下:
- Hue(色相):0~360 度,代表色轮上的角度;
- Saturation(饱和度):0% 表示灰色,100% 表示完全饱和;
- Lightness(亮度):0% 表示黑色,100% 表示白色,50% 是正常亮度。
特点
- 更容易调节颜色的明暗、饱和度;
- 对设计师友好,适合配色方案调整;
RGBA —— 升级方案(加入透明度)
在 RGB 基础上增加了一个 alpha 通道,表示透明度。
color: rgba(255, 0, 0, 0.5); /* 半透明红色 */
- 第四个参数是透明度(alpha),取值范围为
0(完全透明)
到1(完全不透明)
。
HSLA —— 升级方案(加入透明度)
在 HSL 基础上增加了一个 alpha 通道,表示透明度。
color: hsla(0, 100%, 50%, 0.5); /* 半透明红色 */
特点
- 可以创建半透明效果;
- 更灵活地控制视觉层次;
<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>