文字发灰主因是l值过低而非色相或饱和度问题,需按背景l值+55确定文字最低l值,推荐l设为82%–85%,小字号s≤12%,避免纯白并用color-mix(in lch)动态适配深色主题,辅以font-weight≥500和工具实测对比度。

文字发灰不是颜色不对,是L值太低
深色背景下文字看不清,90%的情况不是色相或饱和度问题,而是HSL里的L(亮度)值没拉够。比如hsl(0, 0%, 70%)在#2d2d2d背景上实际对比度可能只有≈3.2:1,远低于WCAG最低要求4.5:1。
别碰H和S瞎调——先查背景LCH亮度值(用ColorMe等工具),再按“背景L + 55”算出文字最低L值。例如背景#2d2d2d实测L≈20,文字L至少得75,对应rgb(220, 220, 220)这类去色灰白,比硬写rgb(255, 255, 255)更稳、OLED边缘更干净。
-
L建议设为82%–85%,比如hsl(210, 10%, 83%),冷调稳白,不刺眼也不泛灰 - 小字号(≤14px)时,
S别超12%,否则红/绿通道干扰聚焦 - 避免
hsl(0, 0%, 100%)或rgb(255, 255, 255):在偏蓝/紫深灰背景(如#1e1e1e)上反而边缘虚化、泛青
用color-mix(in lch)动态适配多套深色主题
如果你有多个深色背景(#1e1e1e、#2d2d2d、#0f0f0f),硬写多套hsl()容易漏配、难维护。color-mix(in lch)能按当前背景自动算出文字色,Chrome 111+、Safari 16.4+、Firefox 119+已支持。
关键点:
- 必须用
in lch,不用in srgb:后者在暗区混合易突然偏粉或泛青 - 混入背景色比例控制在5%–15%,例如
color: color-mix(in lch, white 85%, var(--bg) 15%) - 务必加降级:
color: #e0e0e0; color: color-mix(in lch, white 85%, var(--bg) 15%)
字体渲染和字重会吃掉一半对比度
再准的颜色,在深色背景下也撑不住font-weight: 400——尤其小字号时,系统抗锯齿弱化会让文字毛边、发虚。
- 正文至少用
font-weight: 500;按钮/标题建议600或更高 - 加
text-rendering: optimizeLegibility启用字距优化(Chrome/Firefox支持) - OLED设备上可加
-webkit-font-smoothing: antialiased抑制子像素彩色镶边 - 禁用已废弃的
font-smooth: always或无意义的paint-order: stroke
验证不能只靠眼睛,得跑工具
同一段文字,在MacBook Pro LCD屏和iPhone OLED屏上的清晰度差异显著。人工判断误差大,必须实测:
- VS Code插件
Color Highlight悬停即可看实时对比度数值 - Chrome DevTools → Elements → Styles面板右侧
Accessibility标签页,选中元素直出Contrast ratio - 命令行扫描:
npx axe http://localhost:3000 --rule=contrast - 警惕“伪达标”:工具报4.6:1,但如果字号≤14px、字体细、背景有纹理或图片,实际可读性仍可能崩
复杂点在于:LCH计算、color-mix兼容性、渲染参数联动这三者必须同时对齐,漏一个,文字就发虚。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











