颜色代码转换与设计应用:HEX、RGB、HSL完全指南
颜色是UI设计的灵魂。无论是网页设计还是移动应用,掌握颜色代码的转换和应用都是前端开发者的必备技能。本文将系统讲解各种颜色表示方法及其在实际开发中的应用。
目录
颜色模型基础
RGB颜色模型
RGB(Red, Green, Blue) 是最基础的颜色模型,通过红、绿、蓝三原色的组合产生各种颜色。
// RGB值范围:0-255 const red = { r: 255, g: 0, b: 0 }; const green = { r: 0, g: 255, b: 0 }; const blue = { r: 0, g: 0, b: 255 }; // 白色:所有通道最大值 const white = { r: 255, g: 255, b: 255 }; // 黑色:所有通道最小值 const black = { r: 0, g: 0, b: 0 }; // 灰色:三个通道值相等 const gray = { r: 128, g: 128, b: 128 };
为什么是0-255?
- 每个通道使用8位(1字节)存储
- 2^8 = 256种可能(0-255)
- RGB共24位,可表示16,777,216种颜色
HSL颜色模型
HSL(Hue, Saturation, Lightness) 更符合人类对颜色的感知:
-
Hue(色相):0-360度,表示颜色类型
- 0°/360° = 红色
- 60° = 黄色
- 120° = 绿色
- 180° = 青色
- 240° = 蓝色
- 300° = 品红
-
Saturation(饱和度):0-100%,表示颜色纯度
- 0% = 灰色
- 100% = 纯色
-
Lightness(亮度):0-100%,表示明暗
- 0% = 黑色
- 50% = 正常
- 100% = 白色
// HSL示例 const red = { h: 0, s: 100, l: 50 }; const pink = { h: 0, s: 100, l: 75 }; // 提高亮度 const darkRed = { h: 0, s: 100, l: 25 }; // 降低亮度 const desaturatedRed = { h: 0, s: 50, l: 50 }; // 降低饱和度
HSL的优势:
// 轻松生成同色系 function generateShades(baseHue) { return [ `hsl(${baseHue}, 100%, 20%)`, // 深色 `hsl(${baseHue}, 100%, 40%)`, `hsl(${baseHue}, 100%, 50%)`, // 标准色 `hsl(${baseHue}, 100%, 60%)`, `hsl(${baseHue}, 100%, 80%)`, // 浅色 ]; } const blueShades = generateShades(240); // ["hsl(240, 100%, 20%)", "hsl(240, 100%, 40%)", ...]
HSV/HSB颜色模型
HSV(Hue, Saturation, Value) 或 HSB(Hue, Saturation, Brightness):
- Hue:色相(同HSL)
- Saturation:饱和度(不同于HSL)
- Value/Brightness:明度
// HSV vs HSL const color = { hsl: { h: 0, s: 100, l: 50 }, // 纯红色 hsv: { h: 0, s: 100, v: 100 }, // 相同颜色的HSV表示 };
区别:
- HSL的亮度50%是正常颜色
- HSV的明度100%是正常颜色
- 设计软件(如Photoshop)常用HSV
颜色代码格式详解
HEX(十六进制)
格式:#RRGGBB 或 #RGB
/* 完整格式 */ #FF0000 /* 红色 */ #00FF00 /* 绿色 */ #0000FF /* 蓝色 */ /* 缩写格式(相同数字可省略) */ #F00 /* = #FF0000 */ #0F0 /* = #00FF00 */ #00F /* = #0000FF */ /* 带透明度(Alpha通道) */ #FF000080 /* 50%透明的红色 */ #F008 /* 缩写形式 */
十六进制转换:
function hexToRgb(hex) { // 移除#号 hex = hex.replace(/^#/, ''); // 处理缩写格式 if (hex.length === 3) { hex = hex .split('') .map((c) => c + c) .join(''); } // 解析RGB const r = parseInt(hex.substring(0, 2), 16); const g = parseInt(hex.substring(2, 4), 16); const b = parseInt(hex.substring(4, 6), 16); return { r, g, b }; } console.log(hexToRgb('#FF5733')); // { r: 255, g: 87, b: 51 } console.log(hexToRgb('#F00')); // { r: 255, g: 0, b: 0 }
function rgbToHex(r, g, b) { const toHex = (n) => { const hex = n.toString(16); return hex.length === 1 ? '0' + hex : hex; }; return `#${toHex(r)}${toHex(g)}${toHex(b)}`.toUpperCase(); } console.log(rgbToHex(255, 87, 51)); // "#FF5733"
RGB/RGBA
/* RGB */ rgb(255, 0, 0) /* 红色 */ rgb(0, 255, 0) /* 绿色 */ rgb(0, 0, 255) /* 蓝色 */ /* RGBA(带透明度) */ rgba(255, 0, 0, 0.5) /* 50%透明的红色 */ rgba(0, 0, 0, 0.1) /* 10%透明的黑色 */ /* 现代CSS语法(可选透明度) */ rgb(255 0 0) /* 空格分隔 */ rgb(255 0 0 / 50%) /* 带透明度 */
HSL/HSLA
/* HSL */ hsl(0, 100%, 50%) /* 红色 */ hsl(120, 100%, 50%) /* 绿色 */ hsl(240, 100%, 50%) /* 蓝色 */ /* HSLA(带透明度) */ hsla(0, 100%, 50%, 0.5) /* 50%透明的红色 */ /* 现代语法 */ hsl(0 100% 50%) hsl(0 100% 50% / 50%)
颜色关键字
/* CSS预定义颜色 */ red /* #FF0000 */ blue /* #0000FF */ green /* #008000(注意不是纯绿) */ white /* #FFFFFF */ black /* #000000 */ transparent /* 完全透明 */ /* 特殊值 */ currentColor /* 继承文本颜色 */
常用颜色关键字:
const namedColors = { // 基础色 red: '#FF0000', green: '#008000', blue: '#0000FF', yellow: '#FFFF00', cyan: '#00FFFF', magenta: '#FF00FF', // 灰度 black: '#000000', white: '#FFFFFF', gray: '#808080', silver: '#C0C0C0', // 常用色 orange: '#FFA500', purple: '#800080', pink: '#FFC0CB', brown: '#A52A2A', };
颜色转换算法
RGB ↔ HEX
前面已展示,这里补充带透明度的版本:
function rgbaToHex(r, g, b, a = 1) { const toHex = (n) => { const hex = Math.round(n).toString(16); return hex.length === 1 ? '0' + hex : hex; }; const alpha = Math.round(a * 255); const hex = `#${toHex(r)}${toHex(g)}${toHex(b)}${toHex(alpha)}`; return hex.toUpperCase(); } console.log(rgbaToHex(255, 0, 0, 0.5)); // "#FF000080"
RGB ↔ HSL
function rgbToHsl(r, g, b) { // 归一化到0-1 r /= 255; g /= 255; b /= 255; const max = Math.max(r, g, b); const min = Math.min(r, g, b); const delta = max - min; let h, s, l; // 计算亮度 l = (max + min) / 2; if (delta === 0) { // 灰色 h = 0; s = 0; } else { // 计算饱和度 s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min); // 计算色相 switch (max) { case r: h = ((g - b) / delta + (g < b ? 6 : 0)) / 6; break; case g: h = ((b - r) / delta + 2) / 6; break; case b: h = ((r - g) / delta + 4) / 6; break; } } return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100), }; } console.log(rgbToHsl(255, 87, 51)); // { h: 11, s: 100, l: 60 }
function hslToRgb(h, s, l) { // 归一化 h /= 360; s /= 100; l /= 100; let r, g, b; if (s === 0) { // 灰色 r = g = b = l; } else { const hue2rgb = (p, q, t) => { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; return p; }; const q = l < 0.5 ? l * (1 + s) : l + s - l * s; const p = 2 * l - q; r = hue2rgb(p, q, h + 1 / 3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1 / 3); } return { r: Math.round(r * 255), g: Math.round(g * 255), b: Math.round(b * 255), }; } console.log(hslToRgb(11, 100, 60)); // { r: 255, g: 87, b: 51 }
RGB ↔ HSV
function rgbToHsv(r, g, b) { r /= 255; g /= 255; b /= 255; const max = Math.max(r, g, b); const min = Math.min(r, g, b); const delta = max - min; let h, s, v; // Value(明度) v = max; // Saturation(饱和度) s = max === 0 ? 0 : delta / max; // Hue(色相) if (delta === 0) { h = 0; } else { switch (max) { case r: h = ((g - b) / delta + (g < b ? 6 : 0)) / 6; break; case g: h = ((b - r) / delta + 2) / 6; break; case b: h = ((r - g) / delta + 4) / 6; break; } } return { h: Math.round(h * 360), s: Math.round(s * 100), v: Math.round(v * 100), }; }
配色原理与实践
色彩理论基础
1. 互补色(Complementary)
色环上相对的两种颜色:
function getComplementary(hue) { return (hue + 180) % 360; } const baseHue = 30; // 橙色 const complementary = getComplementary(baseHue); // 210(蓝色) console.log(`hsl(${baseHue}, 100%, 50%)`); // 橙色 console.log(`hsl(${complementary}, 100%, 50%)`); // 蓝色
2. 类似色(Analogous)
色环上相邻的颜色:
function getAnalogous(hue, angle = 30) { return [(hue - angle + 360) % 360, hue, (hue + angle) % 360]; } const analogous = getAnalogous(120); // 绿色为中心 // [90, 120, 150] - 黄绿、绿、青绿
3. 三色组(Triadic)
色环上等距的三种颜色:
function getTriadic(hue) { return [hue, (hue + 120) % 360, (hue + 240) % 360]; } const triadic = getTriadic(0); // 红色为起点 // [0, 120, 240] - 红、绿、蓝
4. 分裂互补色(Split-Complementary)
function getSplitComplementary(hue, angle = 150) { const complement = (hue + 180) % 360; return [hue, (complement - angle + 360) % 360, (complement + angle) % 360]; }
生成配色方案
class ColorScheme { constructor(baseHue, saturation = 70, lightness = 50) { this.baseHue = baseHue; this.saturation = saturation; this.lightness = lightness; } // 单色方案(不同明度) monochromatic(steps = 5) { const colors = []; const lightStep = 80 / (steps - 1); for (let i = 0; i < steps; i++) { const l = 20 + lightStep * i; colors.push(`hsl(${this.baseHue}, ${this.saturation}%, ${l}%)`); } return colors; } // 互补色方案 complementary() { return [ `hsl(${this.baseHue}, ${this.saturation}%, ${this.lightness}%)`, `hsl(${(this.baseHue + 180) % 360}, ${this.saturation}%, ${this.lightness}%)`, ]; } // 类似色方案 analogous() { return [ `hsl(${(this.baseHue - 30 + 360) % 360}, ${this.saturation}%, ${this.lightness}%)`, `hsl(${this.baseHue}, ${this.saturation}%, ${this.lightness}%)`, `hsl(${(this.baseHue + 30) % 360}, ${this.saturation}%, ${this.lightness}%)`, ]; } // 三色组方案 triadic() { return [ `hsl(${this.baseHue}, ${this.saturation}%, ${this.lightness}%)`, `hsl(${(this.baseHue + 120) % 360}, ${this.saturation}%, ${this.lightness}%)`, `hsl(${(this.baseHue + 240) % 360}, ${this.saturation}%, ${this.lightness}%)`, ]; } } // 使用 const scheme = new ColorScheme(210); // 蓝色为基础 console.log(scheme.monochromatic()); // 蓝色系深浅变化 console.log(scheme.complementary()); // 蓝色和橙色 console.log(scheme.triadic()); // 蓝、红、黄
Material Design配色
// Material Design风格的颜色生成 function generateMaterialPalette(baseHue) { const palette = { 50: `hsl(${baseHue}, 100%, 97%)`, 100: `hsl(${baseHue}, 100%, 90%)`, 200: `hsl(${baseHue}, 100%, 80%)`, 300: `hsl(${baseHue}, 100%, 70%)`, 400: `hsl(${baseHue}, 100%, 60%)`, 500: `hsl(${baseHue}, 100%, 50%)`, // 主色 600: `hsl(${baseHue}, 100%, 45%)`, 700: `hsl(${baseHue}, 100%, 40%)`, 800: `hsl(${baseHue}, 100%, 30%)`, 900: `hsl(${baseHue}, 100%, 20%)`, }; return palette; } const blue = generateMaterialPalette(210); console.log(blue[500]); // 标准蓝色 console.log(blue[900]); // 深蓝色
CSS颜色应用
现代CSS颜色特性
/* CSS变量 */ :root { --primary: #3b82f6; --primary-rgb: 59, 130, 246; --primary-hsl: 217, 91%, 60%; } .button { background: var(--primary); /* 使用rgb值添加透明度 */ box-shadow: 0 4px 6px rgba(var(--primary-rgb), 0.3); } /* CSS颜色函数 */ .card { /* 相对颜色语法(CSS Color Module Level 5) */ background: hsl(from var(--primary) h s calc(l * 1.2)); } /* 颜色混合 */ .mixed { background: color-mix(in srgb, red 30%, blue); }
动态主题切换
class ThemeManager { constructor() { this.themes = { light: { '--bg-primary': '#ffffff', '--bg-secondary': '#f3f4f6', '--text-primary': '#111827', '--text-secondary': '#6b7280', '--accent': '#3b82f6', }, dark: { '--bg-primary': '#111827', '--bg-secondary': '#1f2937', '--text-primary': '#f9fafb', '--text-secondary': '#9ca3af', '--accent': '#60a5fa', }, }; } setTheme(themeName) { const theme = this.themes[themeName]; const root = document.documentElement; Object.entries(theme).forEach(([key, value]) => { root.style.setProperty(key, value); }); } // 根据基础色生成主题 generateTheme(primaryColor, mode = 'light') { const { h, s, l } = rgbToHsl(...hexToRgb(primaryColor)); if (mode === 'light') { return { '--primary': `hsl(${h}, ${s}%, ${l}%)`, '--primary-light': `hsl(${h}, ${s}%, ${Math.min(l + 20, 95)}%)`, '--primary-dark': `hsl(${h}, ${s}%, ${Math.max(l - 20, 10)}%)`, '--bg': `hsl(${h}, 10%, 98%)`, '--text': `hsl(${h}, 10%, 10%)`, }; } else { return { '--primary': `hsl(${h}, ${s}%, ${Math.min(l + 10, 70)}%)`, '--primary-light': `hsl(${h}, ${s}%, ${Math.min(l + 30, 85)}%)`, '--primary-dark': `hsl(${h}, ${s}%, ${Math.max(l - 10, 20)}%)`, '--bg': `hsl(${h}, 10%, 10%)`, '--text': `hsl(${h}, 10%, 98%)`, }; } } } // 使用 const themeManager = new ThemeManager(); themeManager.setTheme('dark'); // 或基于品牌色生成 const customTheme = themeManager.generateTheme('#3b82f6', 'light');
渐变色生成
function generateGradient(color1, color2, steps = 10) { const rgb1 = hexToRgb(color1); const rgb2 = hexToRgb(color2); const colors = []; for (let i = 0; i < steps; i++) { const ratio = i / (steps - 1); const r = Math.round(rgb1.r + (rgb2.r - rgb1.r) * ratio); const g = Math.round(rgb1.g + (rgb2.g - rgb1.g) * ratio); const b = Math.round(rgb1.b + (rgb2.b - rgb1.b) * ratio); colors.push(rgbToHex(r, g, b)); } return colors; } // 使用 const gradient = generateGradient('#FF0000', '#0000FF', 5); // ["#FF0000", "#BF003F", "#7F007F", "#3F00BF", "#0000FF"] // CSS渐变 const css = `linear-gradient(90deg, ${gradient.join(', ')})`;
实战案例
案例1:颜色选择器组件
class ColorPicker { constructor(initialColor = '#000000') { this.color = hexToRgb(initialColor); this.listeners = []; } setRgb(r, g, b) { this.color = { r, g, b }; this.notify(); } setHex(hex) { this.color = hexToRgb(hex); this.notify(); } setHsl(h, s, l) { this.color = hslToRgb(h, s, l); this.notify(); } getHex() { return rgbToHex(this.color.r, this.color.g, this.color.b); } getRgb() { return this.color; } getHsl() { return rgbToHsl(this.color.r, this.color.g, this.color.b); } onChange(callback) { this.listeners.push(callback); } notify() { this.listeners.forEach((callback) => callback(this.color)); } } // 使用 const picker = new ColorPicker('#3b82f6'); picker.onChange((color) => { document.querySelector('#preview').style.background = picker.getHex(); document.querySelector('#hex').value = picker.getHex(); const hsl = picker.getHsl(); document.querySelector('#hsl').value = `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)`; });
案例2:无障碍对比度检查
// WCAG 2.0对比度计算 function getContrastRatio(color1, color2) { const getLuminance = (r, g, b) => { const [rs, gs, bs] = [r, g, b].map((c) => { c = c / 255; return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4); }); return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs; }; const rgb1 = typeof color1 === 'string' ? hexToRgb(color1) : color1; const rgb2 = typeof color2 === 'string' ? hexToRgb(color2) : color2; const lum1 = getLuminance(rgb1.r, rgb1.g, rgb1.b); const lum2 = getLuminance(rgb2.r, rgb2.g, rgb2.b); const brighter = Math.max(lum1, lum2); const darker = Math.min(lum1, lum2); return (brighter + 0.05) / (darker + 0.05); } function checkAccessibility(foreground, background) { const ratio = getContrastRatio(foreground, background); return { ratio: ratio.toFixed(2), AA_Normal: ratio >= 4.5, // 普通文字AA级 AA_Large: ratio >= 3, // 大文字AA级 AAA_Normal: ratio >= 7, // 普通文字AAA级 AAA_Large: ratio >= 4.5, // 大文字AAA级 }; } // 使用 const result = checkAccessibility('#3b82f6', '#ffffff'); console.log(result); // { ratio: "4.56", AA_Normal: true, AA_Large: true, AAA_Normal: false, AAA_Large: true }
案例3:智能文字颜色
// 根据背景色自动选择黑或白文字 function getTextColor(backgroundColor) { const rgb = typeof backgroundColor === 'string' ? hexToRgb(backgroundColor) : backgroundColor; // YIQ公式 const yiq = (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000; return yiq >= 128 ? '#000000' : '#ffffff'; } // 使用 document.querySelectorAll('.tag').forEach((tag) => { const bgColor = getComputedStyle(tag).backgroundColor; tag.style.color = getTextColor(bgColor); });
总结
掌握颜色代码转换和应用是前端开发的重要技能:
核心要点
- 理解模型:RGB基于硬件,HSL基于感知
- 转换算法:掌握各种颜色格式互转
- 配色理论:互补、类似、三色组
- 实际应用:主题切换、无障碍检查
最佳实践
- ✅ 使用HSL进行颜色调整(更直观)
- ✅ 存储时使用HEX或RGB(兼容性好)
- ✅ CSS变量管理主题色
- ✅ 检查对比度确保可访问性
- ✅ 使用色彩系统保持一致性
相关工具
关键词: 颜色转换, HEX, RGB, HSL, CSS颜色, 配色理论, 前端设计
更新时间: 2026-01-05
相关阅读
TypeScript 类型体操:什么时候值,什么时候在炫技
务实的 TypeScript 高级类型指南 — mapped types、conditional types、template literal types 真正能给你什么,什么时候用,什么时候应该退回到朴素代码。
Kubernetes 资源 requests / limits 实战:不会把生产搞挂的设法
怎么在生产里实际设 Kubernetes CPU 与内存的 requests/limits — QoS 类、CPU 节流、OOM kill、那些害公司钱的差别,以及好使的模式。
Vue 3 vs React 2026:下个项目的诚实对比
2026 年 Vue 3 与 React 的诚实对比 — Composition API vs Hooks、性能、生态、TypeScript 表现,以及真正决定选型的标准。