尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

深色模式底层原理与工程落地:从OLED省电到自适应主题

深色模式底层原理与工程落地:从OLED省电到自适应主题 我第一次被深色模式反噬是在维护一款资讯类App的时候。用户反馈列表里关于深色模式的吐槽整整占了一页深色背景下正文文字发灰、封面图边缘镶了一圈白边、标签颜色刺眼到没法看。我当时的内心独白是一个黑底功能而已怎么搞出这么多幺蛾子。直到后来我自己在深夜打开阅读器被纯白背景刺得眯起眼睛才真正开始从底层弄明白 Dark Mode 是怎么一回事。深色模式远不是把页面背景从 #FFFFFF 改成 #000000这么简单它背后是一整套跨系统、跨设备、跨内容类型的工程与设计问题。这篇内容我会结合这几年做产品、做主题系统时积累的经验从深色模式的历史、底层机制、设计实务、真实收益和未来演进五个方向展开。不论你是 UI/UX 设计师、前端开发者、客户端工程师还是单纯想搞清楚深色模式到底护不护眼的普通用户这篇都值得往下看。1. 深色模式不是新物种一段被 GUI 遗忘的历史1.1 早期终端界面黑色是技术限制不是审美选择很多人以为深色模式是智能手机时代才流行起来的东西这其实是个误会。计算机诞生之初屏幕就是深色的。上世纪 70 到 80 年代CRT 显示器靠电子束轰击荧光粉发光荧光粉在没有被击中的时候基本不发光所以屏幕默认就是黑色。DOS 系统里黑底白字、黑底绿字、或者琥珀色字符不是因为那个年代的人喜欢黑色而是因为做白底的成本太高需要持续激发整屏荧光粉既费电、又发热、还容易加速荧光粉老化。我小时候接触过一台很老的 IBM 兼容机开机后屏幕是深绿色字符每次刷新都能看到字符拖尾。那时候要是有人提出我要一个浅色主题大概率会被当成开玩笑。终端的深色界面延续了很多年直到今天命令行工具、代码编辑器、网管控制台依然大量使用深色背景这直接说明一件事深色界面在信息密度高、需要长时间注视的场景里有它天然的优势。1.2 图形界面时代白底如何成为正统到了 80 年代中期以施乐 Alto、苹果 Macintosh、微软 Windows 为代表的图形用户界面几乎不约而同地选择了白底黑字。这个转向不是技术上的必然而是隐喻上的选择。图形界面的设计者想模仿办公桌面把纸张和文件搬进屏幕。纸质文档就是白底黑字所以屏幕也应该是白底黑字。你打开一个文件夹一张纸铺开来上面是打印体的文字整个 WYSIWYG所见即所得的概念都是建立在纸张隐喻之上的。当时的 LCD 屏幕也助力了这个趋势。早期 LCD 依赖背光像素本身不发光而是通过液晶分子扭转控制透光量。在亮度均匀和色彩表现上白底反而更容易做得均匀、鲜艳而且在室内光线充足的办公环境下白底的可读性确实更好。这个白底正统的阶段差不多持续了三十年期间只有设计工具、开发工具、以及个别视频软件保留了深色皮肤。所以深色模式并不是一小撮极客的执念它是整个图形化浪潮中被暂时压下去的技术传统。到了 2018 年 macOS Mojave 推出系统级深色模式2019 年 iOS 13 也跟进随后 Windows 10、Android 10 全面铺开深色模式才重新回到主流视野。这一次回归跟 OLED 屏幕大规模应用有直接关系这一点下一节展开。1.3 系统级深色模式的军备竞赛从 2018 到 2020 这几年各大操作系统为什么突然都开始做深色模式表面上是为了夜间使用体验背后其实是 OLED 屏幕的普及和电池续航焦虑的叠加。OLED 屏幕让黑色像素不发光成为可能系统级深色模式第一次有了实在的省电收益。与此同时用户在深夜使用手机的时间越来越长纯白高亮的界面在低亮度环境下确实让人不舒服。操作系统把深色模式做成系统级开关之后应用开发者就不得不跟进否则你的 App 在系统切成深色时会像一块白色补丁一样刺眼。这一轮军备竞赛带来一个很现实的结果深色模式从少数开发者的自我表达变成了每个应用的默认义务。你做一个新产品如果完全忽略深色模式用户第一反应不是你有个性而是这个产品有点粗糙。2. 物理学与工程基础OLED省电、对比度与颜色空间2.1 OLED 为什么让深色模式真正有了省电意义先讲一个基础物理事实OLED 的黑是发光的像素直接关闭LCD 的黑只是液晶挡住背光。普通的 LCD 屏幕背后有一整块背光板哪怕你显示全黑背光也一直亮着你看到的黑其实是偏灰的。OLED 不一样每个像素独立发光显示深色内容时对应像素的电流会显著降低。这是深色模式省电的物理前提。屏幕功耗的估算可以用一个简化的模型整屏功耗约等于所有像素点亮度和颜色权重的总和。在 OLED 上如果纯白背景的功耗是 100%那么纯黑背景的功耗接近 0深灰色比如 #121212大概在 50% 到 70% 之间。具体省多少取决于界面里亮色的面积和亮度。在信息流、阅读类这类大面积背景为浅色的界面里切到深色后屏幕功耗可能下降 40% 甚至更多但视频和游戏这类内容本身就亮暗不均的场景深色模式省电效果就非常有限。LCD 屏幕用户基本不用指望这个背光恒定意味着深色模式对省电几乎没有帮助最多只是降低视觉亮度。下面这张表可以大致说明 OLED 在不同界面下的功耗差异显示场景OLED 相对功耗LCD 相对功耗深色模式省电潜力纯白背景100%100%极小深灰背景#12121250% - 70%95% - 100%明显纯黑背景接近 095% - 100%剧烈高清视频取决于画面几乎恒定不确定有一点工程经验想提醒你即使屏幕是 OLED深色模式的省电也不是无条件的。很多 App 的深色模式只是把外框变黑内容区图片、广告、卡片依然大片白色这种半吊子深色模式省电效果会大打折扣。所以如果你的核心诉求是省电第一步是把真正的背景和卡片做暗而不是简单加一个黑色导航栏。2.2 纯黑背景加纯白文字不是最佳方案这是设计深色模式时最典型的误区。很多人第一反应是黑底白字因为这样对比度最高。但纯黑 #000000 和纯白 #FFFFFF 的对比度确实达到 21:1远高于无障碍标准问题恰恰出在太高上。当亮度极高的文字出现在纯黑背景上人眼的晶状体会产生眩光效应和溢光感文字边缘像蒙了一层毛边尤其在低亮度环境下长时间阅读反而更容易疲劳。专业一点的叫法是 halation中文常译作光晕感。所以主流的深色主题几乎都不使用纯黑而是使用带一定灰度的深色比如 Material Design 推荐的 #121212。理由是深灰色背景可以降低笔画边缘的光晕同时为浮层、卡片、侧边栏提供足够的亮度阶梯空间。你想象一下如果背景用了纯黑那卡片用 #121212浮层用 #1E1E1E三者之间亮度差异其实很小可如果背景用 #0D0D0D卡片用 #121212浮层用 #1E1E1E层级关系就清晰得多。对比度计算不是玄学按 WCAG 标准是可以用公式算的。相对亮度 L 的计算我没有必要在这里全部展开但有一个结论可以记住在深灰 #121212 背景上正文文本用 #E0E0E0 左右的浅灰色对比度能做到 12:1 以上超过 WCAG AAA 对于正文的要求而用纯白 #FFFFFF对比度会到 17:1 以上视觉刺激明显增强。我自己的经验是正文用接近但不到纯白的颜色比纯白舒服得多而且完全不影响可读性。2.3 工程实现从暴力反色到语义色方案早期的深色模式实现方式非常粗糙。很多开发者在代码里枚举所有颜色然后写一堆 if dark 分支。我一个人维护小型项目的时候也这么干过一个月后想改一个品牌色要翻遍所有分支这种方案注定走不远。现代主题系统的工程基础是语义色和设计令牌。所谓语义色就是不给颜色叫蓝色红色而是叫主色背景色文本主色边框色错误色。样式代码里不直接写色值而是引用语义令牌主题切换时只切换令牌对应的色值。这样一层抽象能带来非常大的灵活性你可以同时支持浅色、深色、高对比度甚至未来任何新主题。如果做 Web 端现在有非常成熟的方案。用 CSS 自定义属性和 light-dark() 函数可以只定义一次变量系统自动根据当前模式取色。下面的示例直接开箱即用:root { color-scheme: light dark; --bg-canvas: light-dark(#f7f8fa, #121212); --surface-card: light-dark(#ffffff, #1e1e1e); --text-primary: light-dark(#1a1a1a, #e6e6e6); --text-secondary: light-dark(#6b7280, #a0a0a0); --border-default: light-dark(#e5e7eb, #333333); }这套写法里浅色模式会取第一个值深色模式会取第二个值不再需要写两套完整的 CSS。原生端也是一样的思路iOS 用 UIColor 的动态 ProviderAndroid 用 values-night 资源目录本质上都是让系统在切主题时自动替换颜色资源。从工程上我认为最容易被忽略的一步是提前给整个 App 建立语义色体系而不是等到要上深色模式时才开始整理。如果你现在维护的项目里颜色还是散落各处我的建议是先花一个迭代梳理语义令牌哪怕暂时不做深色模式这个投入后面也会体现在换肤、品牌改版、无障碍适配里。3. 设计实务重灾区阴影失效、语义色、素材适配与可读性3.1 深色下阴影失效层级怎么表达浅色模式里卡片之间的层级关系靠阴影表现。阴影在白色背景上非常明显但在深色背景上尤其当卡片接近纯黑时阴影几乎不可见。你加大投影透明度结果往往不是层级清晰而是整片脏兮兮的灰雾。深色模式的层级体系需要从投影思维切换到亮度思维。用背景色的亮度梯度代替阴影是 Material Design 和 Fluent Design 都在用的思路最低层背景约 #0D0D0D默认背景约 #121212卡片层级约 #1E1E1E弹出浮层/抽屉约 #2A2A2A每升一层背景亮度就提高一点。肉眼感知到的不仅是这块更亮还有这块离我更近。除了亮度梯度适度使用 1px 描边也很有效深色背景下边缘线可以隔开容器。描边不要用纯白更不要用深灰推荐用低透明度白色比如 rgba(255,255,255,0.08)既保证存在感又不会太跳。3.2 语义色需要单独校准不能直接调亮度这是大多数深色模式翻车的重灾区。错误、警告、成功、信息这四类语义状态在浅色主题下通常直接用品牌化的红、橙、绿、蓝。到了深色背景上这些默认颜色会发生两件事饱和度高得刺眼同时对比度可能不足。比如浅色模式下常用的普通红色 #D93025放在深灰背景上视觉上会显得非常炸因为高饱和红色在暗背景上易产生色谱边缘效应。正确的做法是给深色模式重新定义一套语义色方向是提高明度、降低饱和度。举一个可参考的映射状态浅色模式色值深色模式色值错误#D93025#F28B82警告#F9AB00#FDD663成功#188038#81C995信息#1A73E8#8AB4F8你可能会注意到深色模式下的语义色整体变浅了。原因是深色背景下想让颜色与背景拉开对比提高明度比单纯提高饱和度更有效同时也能避免刺眼。这个原则同样适用于品牌色。如果你深色模式下直接沿用品牌色常常会感觉品牌色在深色背景上脏了其实大概率是饱和度太高或明度太低。另外警告色在深色模式下是一个非常特殊的存在。黄色系在浅背景上可以靠亮度差区分但在深背景上很容易糊成一团。测试时建议专门检查警告色是否满足正文级 4.5:1 的对比度不满足就换更亮的黄色。3.3 图片、图标和图表的适配才是真正的工作量文字颜色、卡片颜色调整完深色模式只完成了三分之一剩下的三分之二是内容适配。先说图片。大量站点和 App 的内容图是白底照片或白底商品图在深色模式下这些图片四周会形成明显的白色补丁。粗暴的做法是对所有图片加一层黑色半透明蒙层但这样会导致整张图灰蒙蒙的文字看不清。更稳妥的做法是对纯白底的图片用 CSS 的混合模式比如mix-blend-mode: multiply在白底上能一定程度让白色融入深色背景但这对彩色内容也有影响需要测试对 UI 里的小型图标和 Logo尽量使用 SVG 矢量格式并且用 currentColor 或者语义色变量让图标自动取前景色对图片较多的大流量页面可以考虑在深色模式下降低图片亮度比如filter: brightness(0.85)或者给图片容器加一圈低透明度边框从视觉上告诉用户这里有一张图片。再说图表。这个我踩过的坑特别深。图表库的默认配色几乎都是为浅色背景设计的坐标轴是浅灰网格线更浅文字是深灰。一换成深色背景网格线消失、坐标轴看不见、图例文字跟背景融为一体。给一个 ECharts 下的最小配置供参考const option { backgroundColor: transparent, textStyle: { color: #e6e6e6 }, legend: { textStyle: { color: #cccccc } }, xAxis: { axisLine: { lineStyle: { color: #555555 } }, axisLabel: { color: #bbbbbb }, splitLine: { lineStyle: { color: #333333 } } }, yAxis: { axisLine: { lineStyle: { color: #555555 } }, axisLabel: { color: #bbbbbb }, splitLine: { lineStyle: { color: #333333 } } } };核心思路是深色模式下图表文字用浅灰坐标轴用中等灰网格线用深灰。这组层次关系跟前面讲的颜色令牌是一致的。3.4 可读性细节字体渲染和系统辅助功能深色模式下文字可读性还有一个容易被忽略的技术细节字体渲染。LCD 屏幕上系统默认会开启亚像素抗锯齿让文字边缘更平滑。在浅色背景下这个效果很好但在深色背景下亚像素抗锯齿的彩色子像素会暴露出来导致文字边缘出现红绿蓝杂色像镀了一层彩边。Windows 上一些老版本应用在深色模式下文字发虚就是这个原因。处理方式根据平台有所不同。macOS 和 iOS 已经针对深色模式做了一定优化移动端基本都是像素级渲染问题相对少。Windows 则需要留意浏览器或应用是否启用了适合深色背景的灰度抗锯齿。如果你做的是桌面端应用建议在高 DPI 和普通 DPI 下分别测试一遍深色模式下的文字观感。同时要顾及系统辅助功能。用户在系统里开启降低透明度高对比度之后你的深色模式不应该毫无响应。特别是深色模式下大量使用半透明毛玻璃效果时叠加层会出现颜色错乱这在辅助功能环境下会被放大。如果产品短期做不了完整的无障碍适配也要确保深色模式下所有文本对比度至少满足 4.5:1这是底线。4. 省电和护眼到底有多少是真的实测数据与伪需求争议4.1 实测下来省电效果确实存在但你得分场景围绕 OLED 的深色模式省电效果我做过一轮相对粗粒度的测试拿同一台 OLED 屏手机分别在浅色和深色模式下跑同一批自动化流程包括刷信息流、阅读长文、看视频和玩游戏屏幕亮度固定在 50%流程时间半小时。结果跟上面物理模型推演的方向一致刷信息流和阅读长文时深色模式屏幕功耗有可感知的下降整机续航提升大概在 20% 左右看视频和玩游戏时深色模式的优势几乎消失。原因不复杂视频和游戏画面的亮度由内容本身决定跟 App 主题没有直接关系。还有一个发现如果深色模式下页面里仍有大片白色图片或广告整机省电效果会打折。这跟我在第二节里说的情况完全吻合——深色模式要省电得让整个画面真正暗下来。顺便说一句很多系统在省电模式里会自动把系统切到深色Android 上这个逻辑叫 Battery Saver 的 Force DarkiOS 也有类似的行为。这说明操作系统厂商已经认可了深色模式在 OLED 设备上的节能价值。4.2 护眼是个迷思深色模式只在特定场景下更舒适这是最容易被误解的一点。深色模式本身不是护眼模式这点必须说清楚。低光照环境下深色模式确实能减少屏幕发出的光通量降低眩光感眼睛不容易疲劳。但如果环境光照充足深色背景上的浅色文字对比度感知反而会下降长时间阅读可能比浅色模式更费眼。另外还有瞳孔的问题当你在暗光环境下看深色模式界面瞳孔会放大而瞳孔越大景深越小可能会让一些人觉得文字边缘有重影尤其对近视和散光人群更明显。夜间使用也不是深色模式单打独斗。最舒适的夜间阅读体验应该是深色模式加上较低的屏幕亮度再配合色温调节把蓝光压下来。深色模式只是减少总亮度并不能改变蓝光占比。很多用户以为开了深色就顺便防蓝光了这其实是两件事。我自己是近视加散光实战体验是暗光下把深色背景调到 #121212 而不是纯黑文字用浅灰比纯黑白搭配舒服很多。这又回到了前面说的对比度问题过高的对比度并不一定更护眼。4.3 哪些产品真的需要深色模式哪些只是跟风从需求角度讲不是所有产品都必须做深色模式。深色模式价值最高的场景有这些开发者工具和监控后台长时间盯屏是刚需社交和信息浏览类夜间使用频率高视频、音乐类适合沉浸式体验系统级应用要响应系统主题开关。反过来说有些产品做深色模式要谨慎。最典型的是设计类和颜色判断类工具比如设计师需要精确判断配色深色背景会对颜色感知产生偏差文档扫描类和以白底图片为主要内容的产品深色模式下内容本身不变界面黑不黑意义不大还有儿童教育类应用鲜艳明亮的风格更适合小朋友强制深色反而奇怪。如果一个产品的主要价值是内容本身而内容又大多数是白底图片那么与其花三周做一套深色主题不如把这三个迭代投入到内容加载速度和图片清晰度上。这是我在实际项目里给出的建议。深色模式不是越多越好它服务于使用场景而不是配合市场部的推广噱头。5. 下半场演进从跟随系统到真正的自适应主题5.1 系统主题不再是黑或白的单选题早期的系统级深色模式本质上是一个全局开关要么浅色要么深色。Android 12 之后Material You 把主题跟壁纸提取色绑定深色模式不再只是一个黑色主题而是一套从壁纸派生出来的暗色调色板。iOS 的 True Tone 和环境光传感器也在往这个方向走只是实现路径不同。这个变化的本质是主题开始从用户手动选择转为系统主动判断。未来的深色模式大概率不是深黑或深灰这种固定档位而是根据环境光、时间、用户习惯动态调整背景亮度和色温。举个例子深夜 2 点的深色模式和傍晚 6 点刚开的深色模式很可能应该不一样。前者需要极低的亮度后者需要保留一定的环境光适应空间。现在已经有浏览器和操作系统在做这种渐进式自适应只是还没形成统一标准。5.2 前端和客户端可以提前准备的几个技术点我推荐所有做前端的朋友即使现在还没有排期做深色模式也先做两个动作。第一个是给 HTML 根节点加color-scheme声明第二个是设置meta namecolor-scheme contentlight dark。加了这两行之后浏览器原生控件表单、日期选择器、滚动条就能跟随系统主题自动切换避免页面加载时出现白色闪烁也不容易出现页面主体是深的滚动条还是白的这种割裂感。CSS 层面比较值得关注的是light-dark()函数。以前做两套主题得把所有变量复制一份再用媒体查询覆盖。现在可以只写一套变量两个值并列:root { color-scheme: light dark; --bg: light-dark(#ffffff, #121212); --text: light-dark(#1a1a1a, #e6e6e6); } body { background: var(--bg); color: var(--text); }这个方案非常接近设计令牌的体系。目前主流现代浏览器已逐步支持生产环境使用前建议查一下你的用户群体覆盖率但方向是正确的。客户端开发同理。iOS 端可以更勇敢地使用 Dynamic Color 和 UITraitCollection而不是自己维护一套主题切换管理器Android 端可以尽早迁移到 Material You 提供的动态颜色系统因为在深色模式下动态色系统会自动生成合适的暗色版本省掉你重新调色这一整块工作。5.3 我做深色模式项目的个人落地经验最后分享一点非常个人化的经验。如果在团队里要推动一套深色模式最有效的第一步一定不是出一套完整设计方案而是先把现有页面的截图丢进对比度检查工具挑出几处明显不符合 WCAG 的界面拿给产品和技术负责人看。深色模式下文字对比度不足、点击区域分不清边界这些问题比看起来好不好看有说服力得多。第二件事是资源位要一次到位。如果决定做就一次性把语义色令牌、深色模式色板、图片适配策略、图表配置全部纳入规范而不是这周先做导航栏下周再做详情页。半成品的深色模式比没有更糟用户一旦发现你支持深色模式却有一半页面是刺眼的白色他对产品的好感度掉得比没有深色模式还要快。第三件事是测试矩阵一定要覆盖三类设备OLED 屏手机、LCD 屏中低端机、以及系统开启高对比度的设备。很多深色模式的问题在这三类设备上表现完全不同OLED 上很漂亮的深黑在 LCD 上可能变成发灰的暗色高对比度模式下自己调的深色主题可能被系统强制覆盖出现奇怪的配色。我见过太多项目发版前只在最好的 OLED 工程机上测一下上线之后被中低端机用户截图打脸的情况。所以Whither Dark Mode站在今天往回看深色模式早就不是要不要做的备选项而是主题系统的基础设施。它不再稀奇但真正把它做扎实的产品依然不多。接下来真正的分水岭不是谁能调出更黑的黑而是谁能让界面在正确的时间、正确的亮度、正确的内容类型下自动给出最合适的对比度。深色模式不是一个终点它是自适应界面时代的一个起点而我们应该早点把这些基础打牢。
返回列表