如何骑彩虹:创造黑暗主题的故事


9月,我们发布了iOS官方VK应用程序的深色主题,而一周前,发布也发生在Android上。 此次发布的背后是开发人员和设计师的伟大合作。 在一起,我们不仅将VK切换到了黑暗的一面,而且还严重改变了在界面中使用颜色的方法,从而简化了它们的选择,并减少了出错的可能性并产生了不必要的样式。


我叫Mikhail Likhachev,我是VK的首席设计师。 我将告诉您一个小团队如何调整300个屏幕并使移动应用程序中存在的所有颜色系统化-为此,我们在平台之间同步了它们,并将它们与工作一起放入带有令牌的单个设计系统中。 我将分享我对现在的生活以及设计过程是否变得更加复杂的印象。


为什么我们需要一个黑暗的主题


降低的对比度和深色背景有助于在弱光下使用该应用程序,而不会导致眼睛疲劳。 Google 确认使用深色主题时,具有AMOLED屏幕的设备可以持续使用更长的时间而无需充电。 许多人喜欢黑色或想要新颖的设计主题(当然,无需重新设计)。


现在,不仅在流行的应用程序中实现了深色主题,还在Android启动器中的macOS,tvOS操作系统中实现了深色主题。 而且它在所有iOS和Android设备上的出现肯定不会很快。


对我们来说,这也是期待已久的功能的实现-用户经常问一个黑暗的话题。 事实证明确实有需求-现在,超过20%的观众经常在iOS和Android上使用深色主题。


色彩系统


在制作深色主题之前,我们需要重新组织应用程序的调色板。 目标如下:在代码和设计中,不应有固定调色板中没有的颜色。 对于少量颜色,匹配深色主题会更容易。


当我们检查整个应用程序并收集所有颜色时,我们有200多个唯一的十六进制值。 自从VK App的第一个版本在iOS上发布以来,已经过去了6年多的时间,该应用程序经历了多次重新设计。 直到现在,某个地方仍保留了未更新的屏幕,并且在某些地方,相同颜色的值差异非常小。 例如,HSB中的单一颜色在Photoshop和Sketch中可能具有不同的十六进制值。


我们的应用程序非常大。 我们可以说这些是一个应用程序中的几个应用程序:新闻,音乐,视频,故事,广播,整个Messenger以及许多其他同样重要的部分和服务。 我们计算了300-400个独特的屏幕,每个屏幕都有许多州。 仅新闻一项就有几种类型的记录显示和超过15种类型的附件。 对于这样的应用程序,需要一个更复杂的系统,在该系统中,颜色会被对比度级别分解,因此不仅为深色主题而且为新控件选择颜色都更加容易。


在组织色彩系统方面,我们最喜欢Material Design的方法 。 我们在类似的系统中准备了三个扩展的调色板:灰色,冷灰色和蓝色。 同时,我们将颜色除以常规值从0到1000的对比度,其中0是最亮的颜色,而1000是最暗的颜色。 这些数字与调色板的名称一起成为颜色的标识符-灰色100,蓝色300等。



选择颜色时,HSB颜色模型会有所帮助。 其中,色相是色调,饱和度是饱和度,亮度是亮度。 色相范围为0–360°,我们在界面中使用212°的固定值作为我们的品牌色调。 饱和度和亮度设置为0到100%。


由于我们将灰色调色板分为10个主要阴影,因此在“亮度”中,我们使用10%的步进。 然后,我们沿着一条小曲线将蓝色和“饱和度”混合在一起,同时调整“亮度”值以保留我们所需的对比度等级。


同样,我们拾取了冷的灰色和蓝色调色板。 在需要更饱和的阴影才能与蓝色结合使用的地方,需要使用冷灰色,并且强调,不同的按钮,文本和链接需要几种蓝色。



我们最常将灰色用于各种元素:背景,底材,分隔线,图标,不同级别的文本。 我们已经选择了大多数具有相同对比度差异的灰色阴影,并且在更新调色板时,我们将几种颜色的值略微偏移以匹配新逻辑。 并且还补充了深色光谱中缺少的颜色部分,以便将它们用于深色主题。


绝对将应用程序中使用的所有颜色添加到调色板中,包括在通知中表示不同事件的颜色,甚至是故事中涂鸦绘制模式的颜色。 一切都变得更加透明:现在,应用程序的所有颜色都集中在一个地方。 在为特定情况添加新颜色时,您需要仔细考虑并检查现有颜色是否适合该颜色。


准备好预定义的调色板后,必须将其应用到应用程序中,用超过50个的新集合替换200个以上可用的HEX值。 并将所有这些颜色以静态变量的形式放在一个文件中,其中调色板中的每种颜色都有唯一的名称。


来自iOS和Android的基础架构团队的开发人员着手处理此问题。 伙计们准备了一种算法,用新调色板中最接近的颜色替换颜色,从而大大加快了处理过程。 然后,我们使用测试仪检查了所有屏幕,以确保没有在任何地方应用错误的颜色,最后我们采用了深色主题。


在深色主题中匹配颜色


为了确定所使用的主要阴影,我们开始尝试在主屏幕的布局上使用深色主题的颜色。 对于背景,我们使用灰色900-颜色比黑色浅一色,以降低背景和文本之间的对比度。 出于相同的原因,选择的文本不是白色,而是灰色100。


黑暗主题的所有主要颜色均通过与灯光相同的渐变来标识。 样式在亮度上连续排列之后,我们选择了适当的值,将它们反转并将对比度水平调了一个音调。 然后,我们测试了版面上的颜色,确保所有元素都保持可读性。



使用的原色表


在深色主题中,我们使用的颜色更少:蓝色的帽子和蓝色的按钮变为单色,使用的灰色阴影范围缩小,冷灰色调色板变为常规的灰色,从而保持了对比度。 重音元素保持蓝色-对于深色主题,选择了较浅且较不饱和的阴影。



还有一些问题区域,例如模态窗口和卡片。 它们下面的调光不希望变成白色,并且如果在黑暗主题中没有其他措施,内容的通常背景将与环境融合。 为了避免这种情况,对于模式卡,我们为背景选择了比平时更浅的色调,并且还添加了笔触(到目前为止仅在Android上),以更好地将它们与底层分开。


这样的例子表明,当实现一个黑暗的话题时,我们需要一个更加灵活的系统。


技术实施


在为模型上的深色主题选择适当的颜色后,我们开始将此问题转移到代码中。


正如我们在模型中看到的那样,简单地将颜色主题从浅色主题引入深色主题并不是我们的选择。 白色并不总是被黑色代替:浅色主题中相同颜色的元素在深色中可以具有不同的颜色。 我们需要精确控制每个元素或一组通用样式如何在深色主题中重新绘制。 元素必须根据变量名称中嵌入的含义更改颜色。


我们决定采用以下方法,其中令牌是一个元素或一组元素的唯一名称(例如,background_content),其值只能是固定调色板中的颜色(例如,白色)。 我们制定了一个JSON格式的方案,在该方案中,所有标记都在每个主题中写入其值。


这种方案与具有元素标识符及其样式的CSS文件非常相似,但是格式为JSON。



带有background_content和text_primary标记的方案是什么样的?


我们拥有的一切都可以在GitHub上找到:


  • 具有所有颜色及其唯一名称的调色板
  • 包含所有标记及其在浅色和深色主题中的值的方案

通过JSON方案,所有平台上的开发人员都会以他们所需的格式生成代码。 您可以在Anton Spivak在CodeFest上的演讲中的iOS上的代码示例中阅读有关此内容的内容。 可以在此处查看来自Arseniy Vasiliev在AppConf上的演讲中有关Android实现的报告。


回想一下,我们决定创建一个严格的系统,在该系统中,您只能从内部调色板指定颜色,也就是说,您不能在令牌的值中注册任意十六进制颜色代码。 可以将alpha参数添加到标记值以指示其他颜色透明度。 我们计划使用此参数在触摸控件时添加禁用状态和状态,以免向调色板添加具有不同透明度的相同颜色。


目前,该方案已拥有150多个令牌。 存在全局变量,以及每个控件的完全绘制样式,以及无法使自己更合理组合的独特案例,例如,消息中的气泡样式。



常用令牌的示例


重要的一点是,有必要清楚,简短地命名令牌,以便轻松,快速地找到它们。 命名原则的选择如下-从大到小。 通过这种逻辑,在全局样式中,首先指示通用类型,并且这些组件依次具有名称,状态和最后的特定重绘元素。 如果可能,令牌应该是通用的-反映类型和语义,而不是在特定情况下反映其位置和内容。


电路的进一步工作


素描和齐柏林


下一步:您需要为开发人员提供有关布局中使用的令牌的易于理解的信息。 为此,我们以符号的形式可视化令牌,其中除了名称之外,还提供用于深色和浅色主题的颜色的预览以及调色板中颜色的名称。


组成大部分电路后,我们以符号形式生成了此类令牌,​​并且已经有很多令牌。 为了不手动编写它们,我们准备了一个小插件,该插件提取了当前版本的JSON方案,并以模板中的符号形式从中生成了令牌,并用那里的颜色库的常规样式替换了颜色。 使用相同的插件,我们生成一个库更新:添加新令牌,并更新现有令牌的值。 库中的符号在使用该符号的所有布局中都会更新。



这就是令牌看起来像符号的样子


我们将这些标记添加到布局旁边,并将所有内容一起发送给Zeplin。 如果不能立即按名称清除,或者您需要澄清标记所属的元素,请添加说明,并将标记划分为多个部分,以描述特定的元素。 使用Sketch Runner插件快速搜索符号名称,我们以布局注释的形式获得了深色主题描述构造函数。



添加所用令牌的描述


在如何将令牌嵌入布局并进一步发送给Zeplin方面,我们没有找到更原生,更简单,更直观的解决方案。 尽管Zeplin可以命名独特的颜色,但在我们的方案中,一种颜色可以同时用于多个标记中。


我们没有为数百个屏幕中的每个屏幕绘制深色版本,而只是以标记形式描述所有内容,从而节省了设计人员的时间。 组件的所有可用令牌值都已经过测试,您只需要替换正确的令牌值即可。 唯一的事实是UI Kit –在其中,您不仅可以找到组件的当前状态,还可以找到其使用的标记。


在检查屏幕截图时,在测试阶段就已经可以发现暗主题实现的错误。 测试人员自己可以注意到明显错误的颜色,并向设计者寻求帮助-要纠正缺陷,您只需要正确令牌的名称即可。


架构更新


当您需要更新方案,替换现有令牌的值或创建新令牌时,只需编辑JSON文件。 为此,我们上拉该方案的当前版本并在文本编辑器中进行更改,而不会在添加令牌时忘记为所有主题添加值。 计划是为自己创建一个应用程序,允许您以更简单的方式来编辑方案,但是现在就足够了。


准备好更新后的方案后,我们将拉取请求发送到GitHub(更改文件的请求),该请求已得到开发人员的检查和批准。 合并更改后,开发人员需要加强UI库的更新,然后在15分钟内下一个开发程序集中将出现新的颜色。


要重命名或删除方案中的令牌,我们通过在GitHub上提高版本来创建主要更新。 这意味着不能自动应用这样的版本,并且在更新UI库的版本之前,开发人员需要支持所有更改:更新令牌名称,并且如果在某处使用了已删除的令牌,那么您需要按照更改列表中的注释指示需要哪个令牌使用代替。


我们可以在重构方案时发布此类更新:了解了命名令牌的最佳方法是什么,或者事实证明是将多个令牌组合为一个,同时又保留了逻辑。


跨平台和VKUI


iOS和Android应用程序中的颜色几乎相同,因此在使用iOS时创建的配色方案适用于Android。 如果存在平台差异,则始终可以使用平台后缀创建令牌。


除了本机应用程序,我们还有VKUI 。 这是一组React组件,您可以使用它们创建与我们的应用程序没有区别的接口。 我们使用VKUI在VK内部创建测试产品,以及在不更新应用程序的情况下从服务器控制的屏幕。 此外,该库还用于创建第三方VK Apps服务


VKUI是根据与本机应用程序相同的设计和相同的组件集构建的,因此应用该方案并支持深色主题不需要新的布局。 对我们来说,这是我们支持的另一个平台,仅包含iOS和Android之间的切换。


您可以在VKUI样式指南上以React组件的形式查看VK设计系统的实现。 最有趣的是,在此页面上,您可以实时查看我们使用的具有切换主题和平台功能的组件。


在不久的将来,我们将更新VKUI的文档,并收集有关我们设计团队工作的更多信息-将会有很多有趣的事情️


信使的单独主题


到目前为止,仅在哈萨克斯坦接受测试的VK Me是一个单独的Messenger,可以通过电话号码进行注册。 在其中,我们不仅简化了功能,只保留了通信,还简化了设计。


主题为浅色的帽子变成白色以专注于交流,而蓝色则变得更明亮,更饱和。



该Messenger基于主应用程序中的消息模块,这意味着它使用相同的组件和相同的方案来描述所有颜色。 例如,要重新绘制标头并进行搜索,有必要替换相应标记的值:header_background,header_tint,header_text,search_bar_background,search_bar_field_background search_bar_field_tint等。


通过一种相当简单的方法,我们能够在短时间内重新绘制整个应用程序,从而创建了一个新的设计主题。


处理图形


应用程序中使用的整个图标集都被切成白色,并且可以使用电路中的令牌轻松地重新绘制。


出现了两种颜色的图标带来了困难:将以徽章形式叠加在头像上方并需要白色笔划的图标切成两种颜色。 重新粉刷并不容易。 我们将这些图标分为正面和背景两层,用作遮罩并切出必要的形状。



Android还具有9补丁图形,例如,用于绘制带有阴影的卡片。 它们中的阴影为黑色,卡片的填充为白色。 为了不将此处的图形分为两层,开发人员使用了乘以颜色混合模式-这样就不会重新绘制黑色阴影,并且仅将颜色应用于图片的白色部分,这对我们来说是必需的。


总结


当实施一个黑暗的话题时,我们认真地推动了流程,将设计与开发之间的关系提升到了一个新的高度。


单一方案将所有工作与应用程序中的颜色结合在一起,已成为设计人员功能强大但价格合理的工具,并简化了未来的设计更新。 在创建样式和添加颜色方面的责任感和有意义程度有所提高。


当出现清晰的名称以反映颜色的对比度时,使用它们导航比使用十六进制值容易得多。 同样适用于令牌-由于其内含的含义而被记住,并且在多个平台和应用程序上使用的样式中的逻辑坚持成为流程中必不可少的一部分。


这个过程不仅对于设计人员,而且对于开发人员和测试人员来说都是耗时的。 但这是值得的-黑暗主题获得了用户的积极评价,“黑暗主题”的评论遍及整个VK,甚至超越了它,最终成为了一个模因。

Source: https://habr.com/ru/post/zh-CN449720/


All Articles