
做前端这些年我几乎每天都要跟CSS颜色代码打交道。刚入行的时候最头疼的就是记不住那些花花绿绿的色值写个红色要么用red要么翻PS去吸色再不然就是百度搜#FF0000是什么颜色。后来项目做多了才慢慢发现颜色代码这件事看着简单其实里面的门道不少——从十六进制到RGBA、HSL再到CSS变量管理色板每一层都有坑也都有技巧。这篇东西就把我这些年积累的CSS颜色对照经验整理成一套完整笔记不管你是刚接触CSS的新手还是写了好几年样式的老手在配色调色这块应该都能找到点能用上的东西。1. 先理清CSS颜色到底有哪几种写法很多教程一上来就甩给你一张颜色对照表让你背。我的建议恰恰相反先搞清楚颜色在CSS里有几种书写方式每种方式的适用场景是什么你再回头去看对照表会发现它不再是一串死记硬背的代码而是一套有逻辑的颜色表达系统。1.1 颜色的三种基础表示法CSS里的颜色值最常见的就是三种关键字、十六进制、函数表示法rgb/rgba、hsl/hsla还有一种是直接用CSS变量引用。我先把前三种摆出来。关键字写法最直白比如red、blue、transparent。浏览器支持的颜色关键字总共有148个这里面真正高频使用的可能不到30个。关键字最大的问题是颗粒度太粗浅一点的红发灰一点的蓝很难用单词精确表达而且不同浏览器在个别关键字上的渲染会有细微差异所以只建议在写原型、做快速验证的时候用正经项目里基本都靠后两种。十六进制写法是前端最常用的格式是#RRGGBB也就是用两位十六进制数分别表示红、绿、蓝三原色的强度范围从00到FF。每个颜色分量换算成十进制就是0到255。举个很典型的例子#FFFFFF是白色三个255#000000是黑色三个0#FF0000是纯红红色拉满绿蓝为零。这个规则背下来后面遇到任何十六进制色值你都能心算出它大概长什么样。RGB和RGBA函数写法是rgb(255, 0, 0)这种形式参数直接用十进制的0到255后面加一个/再接透明度就是RGBA比如rgba(0, 0, 0, 0.5)。RGB写法适合从设计稿里直接抄数值比如PS里吸色显示的就是R 255 G 0 B 0和CSS的rgb参数一一对应抄起来零误差。1.2 我说下十六进制和RGB的换算逻辑我见过不少新手对#6B7B8C这种色值完全没概念只会复制粘贴。其实十六进制转成RGB用小学数学就够了每组两位数字对应一个颜色分量。拿#6B7B8C举例第一位6B十六进制数6 * 16 BB等于11所以6 * 16 11 107第二位7B7 * 16 11 123第三位8C8 * 16 12 140。所以#6B7B8C实际上就是rgb(107, 123, 140)一个偏灰调的蓝灰色你把这个数值往PS里一填颜色完全一致。反过来从RGB到十六进制就是做除法。比如设计稿给了R 255 G 200 B 100先用255除以16商15余15商是15对应F余数15也对应F所以红色分量是FF200除以16商12余812对应C所以绿色分量是C8100除以16商6余4写成64最后拼起来就是#FFC864。这套换算逻辑熟练之后你看#FFA500橙色就不会觉得它神秘因为你能直接读出红色满格绿色偏中蓝色没有。1.3 为什么颜色越来越流行用HSL最近几年我看见很多前辈写的样式表里开始频繁出现HSL写法。HSL的全称是Hue色相、Saturation饱和度、Lightness亮度更贴近人眼感知颜色的方式。色相是一个0到360的角度值代表色环上的位置0是红120是绿240是蓝中间那些数值就是从红渐变到绿再渐变到蓝的过程。后面两个参数是百分比饱和度越高颜色越鲜艳亮度越高颜色越亮。HSL最大的优势是调起来直观。你觉得当前颜色太暗直接把L值从40%改成60%不用在十六进制和RGB里来回推算。比如hsl(210, 50%, 50%)是一个中等饱和度的蓝色你想做整套同色系配色只改L值就能得到深浅不同的几个蓝色这在做卡片悬停、按钮按下等状态色时效率极高。现在Chrome的开发者工具里取色器也能直接显示HSL数值方便得很。2. 高频使用颜色代码对照速查网上搜CSS颜色对照表出来的多半是一张巨大的纯色色块图看着气势磅礴真用起来眼花缭乱。所以我自己整理了一套按使用频率排序的色板以实际项目里出现最多的色系为主。下面这张表是我平时会用到的基本涵盖了页面设计里90%以上的颜色需求。2.1 按色系整理一套常用色板色系颜色名十六进制RGB适用场景红色纯红#FF0000rgb(255,0,0)警告、错误、必填标记红色绯红#DC143Crgb(220,20,60)强调色、价格标签红色番茄红#FF6347rgb(255,99,71)按钮、提示条橙色橙色#FFA500rgb(255,165,0)提醒、促销橙色深橙#FF8C00rgb(255,140,0)视觉重心、活动页黄色金色#FFD700rgb(255,215,0)会员标识、星标黄色淡黄#FFF8DCrgb(255,248,220)背景底色、高亮区块绿色纯绿#008000rgb(0,128,0)成功、通过绿色酸橙绿#32CD32rgb(50,205,50)成功按钮、在线状态青色青色#00FFFFrgb(0,255,255)科技感点缀蓝色道奇蓝#1E90FFrgb(30,144,255)链接、主色调蓝色钢蓝#4682B4rgb(70,130,180)表格表头、信息面板紫色蓝紫#8A2BE2rgb(138,43,226)品牌色、创意元素紫色薰衣草紫#E6E6FArgb(230,230,250)浅背景、装饰区灰色灰色#808080rgb(128,128,128)禁用文字、次要信息灰色银白#C0C0C0rgb(192,192,192)边框、分割线棕色马鞍棕#8B4513rgb(139,69,19)复古风、正文辅助色黑色纯黑#000000rgb(0,0,0)主文字、深底色白色纯白#FFFFFFrgb(255,255,255)背景、文字反白这只是个出发点千万不要把这张表当成金科玉律。实际项目里最稳妥的做法是从设计规范中抽色如果公司UI给的设计稿没有规范色板我也会主动整理一份类似的表让团队在写样式时有个统一参照避免出现这个红和那个红不一样的尴尬。2.2 配色时的亮度与对比度判断有了色板还不能直接乱用亮度和对比度是最容易翻车的环节。你先要在心里有个概念同一色系里深色文字配浅色背景可读性就好浅色文字配深色背景但只要字号不够大照样看不清。我个人的判断方法很简单把颜色转成灰度再看深浅。用HSL里的L值最方便L在80%以上的颜色适合做背景文字用深色L在30%以下的颜色适合做底文字用白色中间那些50%到70%的亮色最尴尬既不适合白字也不适合黑字最好做点缀或者渐变过渡。举个例子#1E90FF这个蓝色L值大约在59%背景上用白字对比度一般但如果把它压深到#0B5ED7再用白色对比度就非常稳。这里给一个实用参考正文文字与背景的对比度建议至少达到4.5:1这是WCAG AA标准业内基本都用它做底线。判断对比度不需要自己算浏览器DevTools的元素检查里颜色旁边会直接提示对比度是否达标我用Chrome实测下来很稳不达标时还会给出建议颜色。2.3 透明颜色rgba与8位hex哪个更省心现代CSS里我身边不少人都开始用8位十六进制来表示透明色比如#00000080是半透明黑后两位代表透明度00全透明FF完全不透明。这种写法的好处是复制粘贴很方便不用单独记住alpha参数。不过我要提醒一句8位hex在旧项目里可能碰到兼容性问题虽然不是大问题但如果你在维护一些老系统还是老老实实用rgba(0, 0, 0, 0.5)更保险。另外从可读性角度rgba(0, 0, 0, 0.5)一眼就能看出是50%黑色而#00000080需要换算一下才知道。所以我的习惯是团队新项目里统一用8位hex老项目里继续rgba两种写法效果完全等价关键是别混着写。3. 把颜色用进具体CSS场景的实操笔记颜色本身是抽象的它必须落到具体的CSS属性上才产生视觉价值。这一节我把高频场景拆开来讲从文字变色、背景渐变到边框阴影和动画里的过渡效果每个场景都聊一聊实际写的时候容易踩的点。3.1 文字变色与文字特效文字颜色是CSS里最基础的颜色用法color属性直接作用于文本。我踩过的一个坑是color对border有默认继承效果当你只设置文字颜色而不写在边框上设颜色边框默认用当前文字颜色某些场景下会显得很怪比如color: #333; border-top: 1px solid;出来的边框是深灰色如果没意识到继承关系排查起来很费劲。文字上还有一个常见的需求是删除线写法是text-decoration: line-through。删除线的颜色默认跟随文字颜色但如果你想让删除线更淡更细可以单独设置text-decoration-color我用它做过价格标签原价text-decoration: line-through加一个#999现价用醒目的红色视觉层次一下就出来了。字体渐变是这几年很炫的玩法纯色文字不够表达时可以用背景渐变配合文字透明来实现。核心技术是这三行.title { background: linear-gradient(90deg, #ff6b6b, #f5a623); -webkit-background-clip: text; background-clip: text; color: transparent; }思路是把渐变色刷到背景上再用background-clip: text把背景裁剪成文字形状最后color: transparent把文字默认颜色置为透明这样露出来的就是那段渐变了。这个技巧在标题、logo、数字大屏上效果很出彩但要记住它依赖background-clip的兼容性在一些浏览器里需要加-webkit-前缀。3.2 背景渐变与hover变色背景颜色的写法这几年变化很大从最简单的background-color: #fff到线性渐变、径向渐变、锥形渐变功能越来越强。我做渐变的时候最常遇到的问题是渐变方向写反linear-gradient的第一个参数是终点方向to right是从左到右to bottom是从上到下默认是to bottom。这里有个容易绕晕的点#ff和#ff这种简写看起来很像但实际一个是两个颜色均匀过渡一个是0%位置颜色A、100%位置颜色B区别很小视觉上有时候要仔细看才察觉。hover变色属于交互动效的高频操作核心是用transition让颜色变化有过渡期而不是瞬间切换。比如.btn { background-color: #2563eb; transition: background-color 0.2s ease; } .btn:hover { background-color: #1d4ed8; }这里#2563eb和#1d4ed8是同一色调下深浅不同的两个蓝比直接跳到完全不同的颜色视觉上舒服得多。我以前写hover样式总爱用filter: brightness(0.8)来压暗背景但它会连带着把里面的图标、文字一起压暗后来还是改成老老实实准备一组状态色更可控。3.3 边框、阴影和动画里的颜色边框颜色常见的坑我已经提过这里再补一个阴影颜色默认是跟随文字颜色的因为box-shadow如果不指定颜色第三个颜色参数缺省时用当前color的值所以写box-shadow: 0 2px 8px rgba(0,0,0,0.1)这些习惯里必须把透明度写清楚。比起直接写纯黑#000用带透明度的黑色来打造投影更自然因为纯黑阴影会显得很脏很重。动画里的颜色过渡我指的是transition和keyframes中对color、background-color、box-shadow这些属性的插值变化。CSS引擎可以自动计算两个颜色之间的中间值所以你可以写出从红到蓝的平滑流动效果。但有个重要限制只有属性值本身是颜色时才能过渡如果你用一个背景图片渐变作为动画对象background-image这个属性不支持插值渐变动画在两帧之间是生硬的跳变。如果确实需要渐变背景的平滑过渡有两个方案用background-position做位移也就是把超长渐变背景左右移动或者叠加两层渐变背景通过透明度的变化实现切换。我实测下来第二种最稳定唯一的代价是代码稍长一些。关于涟漪光圈扩散这类效果它的核心其实就是阴影颜色加动画。实现思路是给元素加box-shadow然后把阴影的透明度从0.5慢慢降到0同时把阴影的扩散半径从0拉到20px以上看起来就像水面涟漪扩散。阴影颜色用带透明度的白色或主题色会更好看。3.4 input居中、光标等小细节里的颜色细节热词里有人问css中怎么把input居中实际上input居中跟颜色关系不大主要是布局层面的事。但我发现一个经常被忽略的细节input的光标颜色默认跟随文字颜色如果你给input设置了深蓝背景、白色文字光标会变成白色看起来不突兀。如果想让光标变成品牌色或者醒目的颜色可以用caret-color单独设置比如caret-color: #f00这在做登录表单时是个很讨巧的细节。placeholder文字的颜色也要单独说::placeholder伪元素可以设置颜色input::placeholder { color: #9ca3af; }默认的placeholder是浅灰色有时候在浅色背景上对比度太低看不清调成一个中性灰色#9ca3af是我常用的方案。还有选中文本的颜色::selection伪元素可以改变搜资料时看到不少站点把选中背景调成品牌色体感很好::selection { background-color: #93c5fd; color: #0f172a; }这些细节单独看不显眼但做出来的页面质感差别往往就藏在这些地方。4. 颜色代码的可维护性与调试经验颜色代码用得多必然带来维护问题。一段代码里散落着十几个色值以后改起需求来简直灾难。这一节我讲的是项目管理层面的经验怎么让颜色代码变得好维护、好调试。4.1 用CSS变量把颜色从样式里抽离出来CSS自定义属性俗称CSS变量是现代CSS里管理颜色的最重要手段。你可以把一套色板定义在:root根选择器上后续所有组件都引用变量而不是直接写死数值:root { --color-primary: #2563eb; --color-primary-hover: #1d4ed8; --color-success: #16a34a; --color-warning: #f59e0b; --color-danger: #dc2626; --color-bg-page: #f8fafc; --color-text-main: #1e293b; --color-text-secondary: #64748b; --color-border: #e2e8f0; }变量命名的关键是语义化。--primary比--blue好因为当品牌色从蓝色换成紫色时你只需要改一个变量值所有引用它的地方全都跟着变而--blue这个名字会让后面接手的人误以为这里是强制蓝色不敢动。我现在做项目都会立一条规矩样式文件里禁止直接出现十六进制色值颜色必须抽成变量变量命名按功能来不按颜色本身来。变量还有一个高级玩法是配合主题切换比如浅色模式定义一套变量深色模式重新覆盖一套页面所有组件自动跟随切换。这个我用下来相当实用比单独为深色模式写一套样式省事得多。4.2 取色、校验和调试的小工具我平时取色基本用浏览器DevTools点开元素样式里的颜色小方块会出现取色器可以从页面上任何地方取色也可以直接看十六进制、RGB、HSL三种数值切换一次性都能看到。这个工具的吸管还可以吸屏幕上任意非浏览器区域的颜色设计稿的色值就是这么吸出来的。写代码前如果想从设计稿快速提取色板我也用过一些在线取色网站其中比较可靠的比如在线调色板工具、渐变生成器之类但说实话我用得最多的还是本地的截图取色工具因为截图时顺手就能取色不用来回切换窗口。如果你想要更专业可以用Figma或Sketch自带的功能把设计稿里的颜色批量导出成CSS变量效率极高。校验环节我推荐两件事一是不管什么颜色养成用浏览器控制台实时修改验证的习惯二是大段颜色用到页面前先用对比度检查工具过一遍。Chrome DevTools的「Live」对比度提示已经很智能可以直接在Color Picker界面里看到当前色彩的对比度等级比手动计算靠谱一万倍。4.3 颜色的一致性和对比度检查一致性检查主要是防同一种白色有的地方#fff有地方#ffffff还有地方rgba(255,255,255,1)这种情况。解决思路很简单所有颜色统统走CSS变量变量名统一数值统一从源头杜绝不一致。如果项目是团队协作建议在代码评审时专门看颜色相关改动。对比度检查过去要打开专门的无障碍检测网站现在直接看DevTools的颜色选择器就行。选中一个元素的颜色值点开颜色方块下方有一块对比度区域它会根据背景色自动算出当前文字颜色和背景色的对比度并用对勾或警告图标提示是否达到AA标准。这里有个细节要注意对比度检测要求文字颜色和背景颜色在同一元素上才能正确计算如果文字在图片上、或者HTML结构嵌套复杂比如背景在外层div上、文字在最内层span上DevTools的计算结果就不一定准确这时候得自己调结构或者用在线工具手动选前景色和背景色来算。5. 常见问题与避坑指南最后汇总一下我在实际写CSS颜色过程中遇到过的典型问题以及对应的排查思路。这些问题不小每一件都是我或身边的人真金白银踩出来的。5.1 颜色在屏幕上看起来不对明明是#2563EB这个蓝色有的显示器上发紫有的发灰有的很艳。这是因为色域和色彩管理的问题。普通LCD屏是sRGB色域广色域屏能显示更多颜色。CSS的color属性可以用color-gamut媒体特性做特定适配但绝大多数时候我们并不用管它保证设计稿和开发稿在同样的屏幕标准下预览即可。现代社会最典型的颜色显示问题是夜间模式。深色模式下前端如果不做适配白底页面会变成闪瞎眼的亮色块。处理思路是用prefers-color-scheme: dark媒体特性配合CSS变量做主题切换这也是我前面说颜色必须变量化管理的原因之一。5.2 opacity和rgba混用的坑这是我在项目里见过最多的低级错误。opacity: 0.5会让元素本身、文字、背景以及所有子元素全变透明而rgba(0, 0, 0, 0.5)只影响当前元素的背景色。一个典型的需求是半透明背景遮罩写background-color: rgba(0, 0, 0, 0.5)遮罩层上的文字保持完全不透明如果错误用了opacity: 0.5下面的文字跟着一起透明化根本没法读。以后遇到背景要半透明但文字不能半透明的需求第一反应就是rgba或者8位hex千万别用opacity。反过来如果就是要整块元素带所有内容一起淡入淡出那用opacity更省事。5.3 渐变方向、透明叠加的细节渐变方向写反的问题前面提过这里说一个更隐蔽的坑多个渐变背景叠加时先写的那层在上方。比如background-image: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)), url(bg.jpg);这样会先覆盖一层半透明黑再显示底下图片形成图片压暗的效果。如果你把顺序写反透明层就被图片盖住看不到任何压暗效果。这个顺序问题和background的简写有关我建议写多个背景时尽量用分开的background-image和background-color少用简写因为简写的background会把background-image重置为none顺序和覆盖关系一不小心就出错。5.4 用颜色做状态反馈时别只依赖颜色这是关于无障碍的一个重要提醒。表单校验失败时把输入框边框变红元素状态还需要配套图标或文字提示。视觉正常的人看红色就知道错了全色盲的用户可能什么都看不出来这是WCAG里不依赖单一颜色传达信息的要求。我做项目时的习惯是状态色同时配合边框样式改变比如加一个error icon、改变输入框的背景、增加状态描述文字保证抱着颜色看不了的用户也能感知状态变化。另一个常见问题是禁用状态的文字色太浅浅灰#CCC在白色背景下对比度远低于4.5:1用户在弱光或者小型设备上会看不清。禁用状态也需要保证可读性不能因为禁用就彻底不让人看。最后再分享一个小技巧如果你刚开始接触CSS颜色我建议你养成一个习惯每做一个新项目先花十分钟把:root里的颜色变量定义好再动手写样式。常年在设计稿和代码之间来回抄色值不如一开始就把色板抽象出来。我现在做前端页面几乎不直接在组件样式里写色值凡是需要颜色的地方都用变量。这套习惯帮我省下了不少反复查颜色的时间也让团队的样式代码干净有序得多。实战中如果你发现某个颜色调用特别频繁也可以往里加变量不一定要等到设计规范完善了才做。