无论你是在构建设计系统、调试 CSS,还是将设计稿转换为代码,一个可靠的颜色转换器都是开发者工具箱中最常用的工具之一。在 HEX 转 RGB、RGB 转 HEX、HSL 转 HEX 等格式之间转换是日常任务,涉及前端样式、数据可视化、无障碍审计甚至后端图像处理。本综合指南涵盖所有主要颜色模型、转换背后的数学原理、JavaScript/Python/Bash 代码示例以及现代 CSS 颜色特性。如果你需要一个快速的颜色代码转换器,请试用我们的免费在线工具。
理解颜色模型:RGB、HEX、HSL、HSV 和 CMYK
RGB(红、绿、蓝)是屏幕显示的基础颜色模型。显示器上的每个像素以 0-255 的强度混合红、绿、蓝光。rgb(255, 87, 51) 表示全红、中等绿、低蓝,产生鲜艳的橙色。RGB 是加色模型:三个通道最大值混合产生白色。RGB 是显示器、Canvas API、WebGL 着色器和大多数图像处理库的原生语言。
HEX(十六进制)是网页上最常见的颜色表示法,是 RGB 值的十六进制紧凑表示。#FF5733 分解为 FF=255红、57=87绿、33=51蓝。HEX 代码支持 3 位简写(#F53)、6 位标准(#FF5733)和 8 位含透明度(#FF573380)格式。由于 HEX 值紧凑且明确,是 CSS、Figma、Sketch 的默认格式。
HSL(色相、饱和度、亮度)旨在更直观。色相是色轮上的度数(0-360),饱和度是颜色强度百分比(0-100%),亮度从黑色(0%)到纯色(50%)再到白色(100%)。hsl(14, 100%, 60%) 描述我们的橙色。HSL 使创建明暗变体变得简单,只需调整 L 通道。CSS 原生支持 hsl()。
HSV/HSB(色相、饱和度、明度)是大多数颜色选择器使用的模型,包括 Photoshop、Figma 和系统原生选择器。它与 HSL 共享色相轮,但用明度替换亮度。CSS 不直接支持 HSV,但理解 HSL 和 HSV 的区别有助于将设计准确转换为代码。
CMYK(青、品红、黄、黑)是印刷用的减色模型。油墨吸收光而非发光,混合所有油墨产生黑色。CMYK 与 CSS 无关,但在生成 PDF 和印刷文件时必不可少。RGB 和 CMYK 之间的准确转换需要 ICC 颜色配置文件。
颜色模型对比表
以下表格总结了每种颜色模型的关键属性,帮助你选择适合的格式:
| Model | Format | Range | Use Case | CSS Support | Human-Readable |
|---|---|---|---|---|---|
| RGB | rgb(R, G, B) | 0-255 per channel | Screen display, Canvas, WebGL | Yes | Low |
| HEX | #RRGGBB | 00-FF per channel | CSS, design tools, tokens | Yes | Low |
| HSL | hsl(H, S%, L%) | H: 0-360, S/L: 0-100% | Theming, shade generation | Yes | High |
| HSV/HSB | hsv(H, S%, V%) | H: 0-360, S/V: 0-100% | Color pickers (Photoshop, Figma) | No | High |
| CMYK | cmyk(C%, M%, Y%, K%) | 0-100% per channel | Print, PDF generation | No | Medium |
| OKLCH | oklch(L C H) | L: 0-1, C: 0-0.4, H: 0-360 | Modern CSS, wide gamut | Yes | High |
颜色转换原理:HEX、RGB、HSL 和 HSV 背后的数学
每个颜色代码转换器都实现了一套公知的数学公式。理解这些公式有助于调试边界情况、编写自己的转换器或验证库的输出结果。
HEX 转 RGB:十六进制颜色代码如 #FF5733 由三对十六进制数字组成。将每对独立解析:parseInt("FF", 16) = 255、parseInt("57", 16) = 87、parseInt("33", 16) = 51,结果为 rgb(255, 87, 51)。3 位简写如 #F53 先将每位翻倍。
RGB 转 HEX:将每个通道值(0-255)转换为两位十六进制字符串,用 # 前缀连接。例如 rgb(255, 87, 51) 变为 #ff5733。
RGB 转 HSL:首先将 R、G、B 归一化到 0-1 范围。找到三个通道的最大值(Cmax)和最小值(Cmin),计算差值 delta。亮度 = (Cmax + Cmin) / 2。饱和度取决于亮度:若 delta 为 0 则饱和度为 0;否则 S = delta / (1 - |2L - 1|)。色相取决于哪个通道最大。
HSL 转 HEX:先将 HSL 转为 RGB,再将每个 RGB 通道转为十六进制。HSL 转 RGB 算法计算色度值 C、中间值 X 和匹配值 m,根据色相所在的 60 度扇区分配通道值。
RGB 转 HSV:色相计算与 RGB 转 HSL 相同。明度 = Cmax。饱和度 = delta / Cmax(Cmax 为 0 时为 0)。HSV 比 HSL 更简单,因为不涉及亮度平均步骤。
HSL 与 HSV 互转:虽然两者共享色相分量,但饱和度和亮度/明度之间的转换需要特定公式。V = L + S * min(L, 1-L);Sv = (V > 0) ? 2 * (1 - L/V) : 0。
颜色转换代码示例
JavaScript / CSS 颜色转换
JavaScript 没有内置颜色转换器,但 CSS 颜色函数和简单解析使转换变得直接。以下是 HEX 转 RGB、RGB 转 HEX 和 RGB 转 HSL 的可复用函数:
// ===== HEX to RGB =====
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
hexToRgb('#FF5733'); // { r: 255, g: 87, b: 51 }
// ===== RGB to HEX =====
function rgbToHex(r, g, b) {
return '#' + [r, g, b]
.map(x => x.toString(16).padStart(2, '0'))
.join('');
}
rgbToHex(255, 87, 51); // "#ff5733"
// ===== RGB to HSL =====
function rgbToHsl(r, g, b) {
r /= 255; g /= 255; b /= 255;
const max = Math.max(r, g, b), min = Math.min(r, g, b);
const l = (max + min) / 2;
if (max === min) return { h: 0, s: 0, l: Math.round(l * 100) };
const d = max - min;
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
let h = 0;
switch (max) {
case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;
case g: h = ((b - r) / d + 2) / 6; break;
case b: h = ((r - g) / d + 4) / 6; break;
}
return {
h: Math.round(h * 360),
s: Math.round(s * 100),
l: Math.round(l * 100)
};
}
rgbToHsl(255, 87, 51); // { h: 11, s: 100, l: 60 }
// ===== HSL to RGB =====
function hslToRgb(h, s, l) {
s /= 100; l /= 100;
const c = (1 - Math.abs(2 * l - 1)) * s;
const x = c * (1 - Math.abs((h / 60) % 2 - 1));
const m = l - c / 2;
let r = 0, g = 0, b = 0;
if (h < 60) { r = c; g = x; b = 0; }
else if (h < 120) { r = x; g = c; b = 0; }
else if (h < 180) { r = 0; g = c; b = x; }
else if (h < 240) { r = 0; g = x; b = c; }
else if (h < 300) { r = x; g = 0; b = c; }
else { r = c; g = 0; b = x; }
return {
r: Math.round((r + m) * 255),
g: Math.round((g + m) * 255),
b: Math.round((b + m) * 255)
};
}
hslToRgb(11, 100, 60); // { r: 255, g: 87, b: 51 }
// ===== CSS native color parsing (modern browsers) =====
// Use CSS.supports() and getComputedStyle for runtime conversion
const el = document.createElement('div');
el.style.color = 'hsl(14 100% 60%)';
document.body.appendChild(el);
const rgb = getComputedStyle(el).color;
// "rgb(255, 87, 51)" - browser converts any format to RGB
document.body.removeChild(el);Python 颜色转换
Python 标准库包含用于 HSL/HSV 转换的 colorsys,第三方库如 Pillow 和 matplotlib 提供扩展颜色处理:
import colorsys
# ===== RGB to HSL (colorsys uses HLS order) =====
r, g, b = 255, 87, 51
r_norm, g_norm, b_norm = r / 255, g / 255, b / 255
h, l, s = colorsys.rgb_to_hls(r_norm, g_norm, b_norm)
print(f"HSL: ({h*360:.0f}, {s*100:.0f}%, {l*100:.0f}%)")
# HSL: (11, 100%, 60%)
# ===== HSL to RGB =====
r2, g2, b2 = colorsys.hls_to_rgb(h, l, s)
print(f"RGB: ({r2*255:.0f}, {g2*255:.0f}, {b2*255:.0f})")
# RGB: (255, 87, 51)
# ===== RGB to HSV =====
h_hsv, s_hsv, v_hsv = colorsys.rgb_to_hsv(r_norm, g_norm, b_norm)
print(f"HSV: ({h_hsv*360:.0f}, {s_hsv*100:.0f}%, {v_hsv*100:.0f}%)")
# HSV: (11, 80%, 100%)
# ===== HEX to RGB =====
def hex_to_rgb(hex_color):
hex_color = hex_color.lstrip('#')
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
print(hex_to_rgb("#FF5733")) # (255, 87, 51)
# ===== RGB to HEX =====
def rgb_to_hex(r, g, b):
return f"#{r:02x}{g:02x}{b:02x}"
print(rgb_to_hex(255, 87, 51)) # #ff5733
# ===== Using matplotlib colors =====
import matplotlib.colors as mcolors
rgb_tuple = mcolors.to_rgb('#FF5733') # (1.0, 0.341, 0.2)
hex_value = mcolors.to_hex((1.0, 0.341, 0.2)) # '#ff5733'
rgba = mcolors.to_rgba('steelblue', alpha=0.5)
# ===== Using Pillow/PIL for image colors =====
from PIL import Image
img = Image.new('RGB', (1, 1), (255, 87, 51))
pixel = img.getpixel((0, 0)) # (255, 87, 51)
img_hsv = img.convert('HSV') # Convert to HSV color spaceBash / CLI 颜色转换
命令行工具如 printf 和 ImageMagick 的 convert 可以在终端直接处理基本颜色转换:
# ===== HEX to RGB using printf =====
hex="FF5733"
printf "RGB: %d, %d, %d\n" 0x${hex:0:2} 0x${hex:2:2} 0x${hex:4:2}
# RGB: 255, 87, 51
# ===== RGB to HEX using printf =====
r=255 g=87 b=51
printf "#%02x%02x%02x\n" $r $g $b
# #ff5733
# ===== ImageMagick color conversion =====
# Convert HEX to RGB
magick convert xc:"#FF5733" -format "%[fx:int(255*r)],%[fx:int(255*g)],%[fx:int(255*b)]" info:
# 255,87,51
# Get color info in multiple formats
magick convert xc:"#FF5733" -colorspace HSL -format "HSL: %[fx:r*360],%[fx:g*100]%%,%[fx:b*100]%%" info:
# ===== Convert named color to HEX =====
magick convert xc:"tomato" -format "#%02[hex:r]%02[hex:g]%02[hex:b]" info:
# #FF6347
# ===== Batch convert colors from file =====
# colors.txt: one hex color per line
while IFS= read -r color; do
printf "%s -> RGB: %d, %d, %d\n" "$color" \
0x${color:1:2} 0x${color:3:2} 0x${color:5:2}
done < colors.txt现代 CSS 颜色特性
CSS 已远超基本的 rgb() 和 hsl()。现代 CSS 支持感知均匀色彩空间、广色域颜色和强大的颜色操作函数:
/* ===== Modern CSS color syntax (no commas) ===== */
.element {
/* RGB - modern space-separated */
color: rgb(255 87 51);
color: rgb(255 87 51 / 0.5); /* with alpha */
/* HSL - modern space-separated */
background: hsl(14 100% 60%);
background: hsl(14 100% 60% / 0.8);
/* HWB - Hue, Whiteness, Blackness */
border-color: hwb(14 0% 0%); /* pure orange */
border-color: hwb(14 20% 10%); /* muted orange */
}
/* ===== OKLCH - perceptually uniform ===== */
.brand {
--brand-primary: oklch(0.65 0.25 29); /* vivid red-orange */
--brand-light: oklch(0.85 0.12 29); /* light variant */
--brand-dark: oklch(0.45 0.20 29); /* dark variant */
/* Same hue, predictable lightness changes */
}
/* ===== color-mix() - blend colors ===== */
.mixed {
background: color-mix(in oklch, #FF5733 70%, #3366FF);
border: 1px solid color-mix(in srgb, currentColor 40%, transparent);
}
/* ===== Relative color syntax ===== */
.derived {
--base: #FF5733;
/* Lighten by increasing L in oklch */
color: oklch(from var(--base) calc(l + 0.2) c h);
/* Desaturate by reducing chroma */
background: oklch(from var(--base) l calc(c * 0.5) h);
/* Shift hue by 180 degrees (complementary) */
border-color: hsl(from var(--base) calc(h + 180) s l);
}
/* ===== Wide gamut P3 colors ===== */
@supports (color: color(display-p3 1 0 0)) {
.vivid {
color: color(display-p3 1 0.3 0.1); /* more vivid than sRGB */
}
}
/* ===== Dark mode with light-dark() ===== */
:root {
color-scheme: light dark;
--text: light-dark(#1a1a1a, #e5e5e5);
--surface: light-dark(#ffffff, #121212);
}
/* ===== CSS custom properties for theming ===== */
:root {
--color-primary-h: 14;
--color-primary-s: 100%;
--color-primary-l: 60%;
--color-primary: hsl(
var(--color-primary-h)
var(--color-primary-s)
var(--color-primary-l)
);
--color-primary-hover: hsl(
var(--color-primary-h)
var(--color-primary-s)
calc(var(--color-primary-l) - 10%)
);
}CSS 颜色函数深度解析
现代 CSS 提供丰富的颜色函数。经典 rgb() 函数现在接受空格分隔语法:rgb(255 87 51)。hsl() 使用 hsl(14 100% 60%) 无需逗号。hwb() 函数(色相、白度、黑度)是更直观的替代方案。
oklch() 函数代表了网页颜色的突破。基于 Oklab 感知颜色空间,oklch(亮度 色度 色相) 确保相同亮度值的颜色看起来确实同样明亮。OKLCH 还解锁 P3 广色域,在现代显示器上产生更鲜艳的颜色。
color-mix() 函数在任何颜色空间中混合两种颜色。color() 函数直接访问命名颜色空间。相对颜色语法可以从现有颜色派生新颜色。
其他有用的 CSS 颜色值包括 currentColor(继承当前文本颜色)、transparent(完全透明黑色)和用于主题的 CSS 自定义属性。light-dark() 函数根据用户颜色方案偏好自动选择颜色。
颜色无障碍与对比度
WCAG 对比度是无障碍颜色设计的基础。AA 级要求普通文本最低 4.5:1 对比度,大文本 3:1。AAA 级要求普通文本 7:1,大文本 4.5:1。对比度使用相对亮度计算。
色盲考虑:约 8% 的男性有某种形式的色觉缺陷。切勿仅依靠颜色传达信息;始终配合文本标签、图标或图案。避免红/绿、绿/棕、蓝/紫等问题组合。
构建无障碍调色板:从品牌颜色开始,生成在白色和深色背景上都符合 WCAG AA 的色阶。使用 OKLCH 进行感知均匀的色阶生成。测试每种前景/背景组合的对比度。
开发者颜色最佳实践
设计令牌和 CSS 自定义属性:将颜色定义为设计令牌并映射到 CSS 自定义属性。使用语义命名如 --color-text-primary 而非 --blue-500。将令牌存储在单一数据源中,从中生成各平台所需格式。
暗色模式策略:简单反转亮度是常见错误。应将暗色模式设计为独立主题。在 OKLCH 中,可以系统性降低暗背景的亮度和色度。使用 CSS prefers-color-scheme 检测用户偏好。
一致的颜色命名:采用颜色阶梯命名约定(如 50、100、200...900)。映射到语义角色。永远不要在组件样式中直接使用原始 HEX 或 RGB 值,始终引用令牌。
性能考虑:CSS 自定义属性在运行时解析。动画中优先使用 oklch() 插值以获得更平滑的感知过渡。服务端颜色转换在热路径中使用 C/Rust 库。
常见问题
如何在 HEX 和 RGB 之间转换?
HEX 转 RGB:将十六进制代码拆分为三对(如 #FF5733 变为 FF、57、33),将每对解析为十六进制整数。RGB 转 HEX:将每个通道转换为 2 位十六进制字符串并连接。我们的在线颜色转换工具可以即时完成这些转换。
Web 开发中最佳的颜色格式是什么?
对于大多数项目,HEX 是默认选择;HSL 更适合主题系统;现代浏览器中 oklch() 是最佳选择,因为它提供感知均匀的颜色和更宽的色域。使用设计令牌存储颜色值并生成各平台所需格式。
WCAG 颜色对比度的无障碍要求是什么?
WCAG 2.1 定义两个级别:AA 级要求普通文本至少 4.5:1 对比度,大文本 3:1。AAA 级要求普通文本 7:1,大文本 4.5:1。非文本元素如图标需要至少 3:1 对比度。始终使用自动化对比度检查器测试。
颜色转换是连接设计工具、CSS 编写、无障碍和后端处理的基础技能。无论你需要快速的 HEX 转 RGB 查询还是可靠的颜色代码转换器,本指南都提供了全面的参考。