一、前言
UI 组件库是现代 Web 应用程序开发中不可或缺的一部分。动态主题风格切换是一个非常重要的功能,它可以允许应用程序用户在不同的场景下选择自己喜欢的主题。这样的一个特性可以增加用户体验的个性化,并提高应用程序的可用性和易用性。
微盟移动端组件库 Titian 提供了动态主题切换的能力,并且延展了主题范围。
二、背景
在以前商户店铺的品牌视觉风格往往千篇一律,同时还因为需要逐个繁琐地配置界面中元素,导致的风格错乱等问题。针对上述的痛点,本次升级在确保商户品牌风格统一的前提下,基于品牌调性提炼了具有共性的视觉特征,分别为颜色、图标、圆角。并用这些特征组合为“通用”、“潮流”、“可爱”三套风格,能够让商家随心选择,让线上店铺更贴合自身的品牌调性,提高品牌识别度,维持 C 端用户的品牌心智。
微盟移动端组件库 Titian 的主题风格包括三个维度的风格变化:
1、主题颜色的风格切换,这里主题色可以设置任意一种色值。
2、字体图标风格的切换,组件库中的所有图标包含三种风格,具体分为通用型,超流型和可爱型。
3、所有组件的圆角的切换,组件库中所有圆角也分为三种风格,风格的分类和字体图标分类一致,通用型的圆角即为设计稿上的圆角,超流型的圆角则是所有的组件圆角都变成直角,可爱型的圆角则为在设计稿上的圆角的基础上加上8个像素。
我们要实现三种风格的切换是互相独立的,可以互相组合搭配。另外,图标风格的切换可以是全量一起切换,也可以是部分单独切换,而且需要运行时可以动态切换。
这些风格的切换都需要内置到组件库中,只需要给业务方提供一个变量来改变整体风格。
三、需求分析
对于主题色的风格配置,由于有些组件使用的的具有百分比透明度的主题色,所以采用 RGBA 色值更加方便。对于图标风格切换,从一种风格增加到三种风格,能不能尽量的不要增加代码体积,毕竟小程序对包体积有严格的要求。 对于圆角风格,有些需要将设计稿的圆角加8像素,有些需要变成直角,而有些又需要单独处理成大圆角。
这都该如何设计呢?这么多的风格切换,如何能尽量设计少的接口来让业务方写最少的代码,不去增加业务方的记忆负担呢?另外需要在运行时进行风格的切换,我决定使用 CSS 原生变量的方式。
CSS变量的好处包括:
代码重用: 可以在多个元素中使用同一个变量,避免了重复编写样式代码的问题。
简化维护: 当需要修改样式时,只需要修改变量的值,而不是每个元素的样式。
动态更新: CSS 变量可以通过 JavaScript 动态修改,使得样式在运行时可以动态变化。
提高可读性: 通过使用有意义的变量名,可以使样式表更易于理解和维护。
CSS 变量可以提高代码的可维护性、可读性和灵活性。
四、技术方案和实施
4.1 主题颜色切换方案
组件库内部定义三个 CSS 变量:--theme-r、--theme-g、--theme-b,这三个 CSS 变量也是对外暴露出去修改主题颜色的关键。组件内部的全局 less 文件使用这三个变量定义主题色,所有组件使用到主题色的地方都统一使用下面的 less 变量。
@theme-r: var(--theme-r, 250);
@theme-g: var(--theme-g, 44);
@theme-b: var(--theme-b, 25);
@brand-color: rgb(@theme-r, @theme-g, @theme-b);
@brand-color-fade-10: rgba(@theme-r, @theme-g, @theme-b, 0.1);
@brand-color-fade-20: rgba(@theme-r, @theme-g, @theme-b, 0.2);
@brand-color-fade-30: rgba(@theme-r, @theme-g, @theme-b, 0.3);
@brand-color-fade-40: rgba(@theme-r, @theme-g, @theme-b, 0.4);
@brand-color-fade-50: rgba(@theme-r, @theme-g, @theme-b, 0.5);
@brand-color-fade-60: rgba(@theme-r, @theme-g, @theme-b, 0.6);
@brand-color-fade-70: rgba(@theme-r, @theme-g, @theme-b, 0.7);
@brand-color-fade-80: rgba(@theme-r, @theme-g, @theme-b, 0.8);
@brand-color-fade-90: rgba(@theme-r, @theme-g, @theme-b, 0.9);
@brand-color-fade-100: rgba(@theme-r, @theme-g, @theme-b, 1);
4.2 圆角风格切换方案
三种圆角是对应三种圆角数值,默认的圆角是设计稿的圆角,怎样变成直角和大8像素的圆角呢?我采用设计圆角加上增量圆角来达到最终圆角的目的。
针对于所有增量圆角,我们定义一个css变量:--base-radius-size,另外在全局less变量中定义圆角变量,我们所有使用到圆角的地方都使用less变量;默认的增量为0。
潮流型风格需要将圆角变成直角,那么只需将增量圆角设置为一个较大负值比如-999px,那么最终也会得到一个负数圆角,因为圆角不存在负值,所以负值圆角表现就是圆角为0的直角效果。
可爱型风格需要将设计稿圆角增加8像素。那么这个增量圆角就设置为8px;而对于那些特殊需求,要单独设置成大圆角即半圆形的圆角,那么只需给一个较大的圆角即可。但是为了做区分,所以这里新增了一个css变量:--capsule-radius-size,这个是专供特殊需求圆角使用,比如button和search的圆角,他们在可爱风格下会直接变成胶囊型圆角。那么这里就把--capsule-radius-size设置为999px即可。
下图就是全局 less 变量中定义的圆角,在组件中统一使用如下圆角。目前只罗列了4px、8px、12px、16px和大圆角。如果有更多圆角,可以新增多个圆角数值。业务方在使用时,设置通用风格,只需设置--base-radius-size:0px;--capsule-radius-size:0px;这也是默认风格。设置成潮流型,只需设置--base-radius-size:-999px;--capsule-radius-size:-999px;设置成可爱型,只需设置--base-radius-size:8px;--capsule-radius-size:999px;
@radius-4: calc(var(--base-radius-size, 0px) + 4px);
@radius-8: calc(var(--base-radius-size, 0px) + 8px);
@radius-12: calc(var(--base-radius-size, 0px) + 12px);
@radius-16: calc(var(--base-radius-size, 0px) + 16px);
@radius-999: calc(var(--base-radius-size, 0px) + 999px);
// 圆角 (按钮button、搜索search)采用如下圆角;
// 可以自适应变成胶囊型
@special-radius-4: calc(var(--capsule-radius-size, 0px) + 4px);
@special-radius-8: calc(var(--capsule-radius-size, 0px) + 8px);
@special-radius-12: calc(var(,--capsule-radius-size 0px) + 12px);
@special-radius-16: calc(var(--capsule-radius-size, 0px) + 16px);
@special-radius-999: calc(var(--capsule-radius-size, 0px) + 999px);