品牌色功能迭代方案

Heero.Luo发表于13天前,已被查看11次

最近产品经理希望在 B 端后台系统中增加品牌色功能,突显客户的企业特色。从技术上说,整个流程是非常简单的:

  1. 在配置中心为某个客户配置品牌色(十六进制颜色值)。
  2. 后台系统初始化时,通过后端接口读取配置的品牌色。
  3. 把品牌色写入为根元素的 CSS 变量

核心流程代码如下:

const response = await fetch('/api/get-brand-info');
const data = await response.json();
document.documentElement.style.setProperty(
  '--brand-primary-color',
  data.primaryColor
);

颜色替换

接下来要把项目中样式代码的颜色值改为 CSS 变量。颜色值的使用,一般有两种情况:

  • 使用了 SCSS 等 CSS 扩展语言中的变量,所有颜色值都从变量取值;
  • 直接用颜色值。

实际情况更有可能是这两种的混合——虽然使用了 SCSS 变量,但由于部分开发人员没有完全遵循规范,所以项目中既有颜色变量,也有颜色值

$primary-color: #3F76FC;

.logo {
  background: #3F76FC;
}
.selected {
  color: $primary-color;
  border: 1px solid $primary-color;
  background: rgba($primary-color, 0.1);
}

不过,不管是哪种情况,似乎都是把颜色值替换成 CSS 变量就可以了。以上述代码为例,即把「#3F76FC」替换为「var(--brand-primary-color, #3F76FC)」:

$primary-color: var(--brand-primary-color, #3F76FC);

.logo {
  background: var(--brand-primary-color, #3F76FC);
}
.selected {
  color: $primary-color;
  border: 1px solid $primary-color;
  background: rgba($primary-color, 0.1);
}

替换后,马上发现问题——.selected 元素的背景色没了。通过浏览器开发工具可以发现,背景属性的值变成了:

background: rgba(var(--brand-primary-color, #3F76FC), 0.1);

属于无效写法。造成这种情况,是因为「background: rgba($primary-color, 0.1)」中的「$primary-color」被编译成该变量的值了。

在 SCSS 中,可以用「rgba(#3F76FC, 0.1)」这种写法。编译过程中,编译器会把十六进制颜色值转成 RGB 颜色值,也就是编译成「rgba(63, 118, 252, 0.1)」。然而,把颜色值替换成 CSS 变量后,由于编译器也不知道颜色值是什么,所以无法进行转换。因此,这里必须用 RGB 颜色值

对核心流程代码稍作修改,设置两个 CSS 变量,分别是 RGB 颜色值和十六进制颜色值:

import { hexToRGB } from '@polyv/utils/es/color';

const response = await fetch('/api/get-theme');
const data = await response.json();
document.documentElement.style.setProperty(
  '--brand-primary-color-hex',
  data.primaryColor
);
document.documentElement.style.setProperty(
  '--brand-primary-color-rgb',
  hexToRGB(data.primaryColor).join(',')
);

接下来设置两个 SCSS 变量,分别是品牌色的十六进制表示和 RGB 表示:

$--primary-color-hex: var(--brand-primary-color-hex, #3F76FC);
$--primary-color-rgb: var(--brand-primary-color-rgb, 63, 118, 252);

做两次替换操作:

  1. 把「rgba($--primary-color」以及「rgba(#3F76FC」替换为「rgba($--primary-color-rgb」。
  2. 把剩余的「$--primary-color」以及「#3F76FC」替换为「$--primary-color-hex」。

最终能正常运行的代码为:

$--primary-color-hex: var(--brand-primary-color-hex, #3F76FC);
$--primary-color-rgb: var(--brand-primary-color-rgb, 63, 118, 252);

.logo {
  background: $--primary-color-hex;
}
.selected {
  color: $--primary-color-hex;
  border: 1px solid $--primary-color-hex;
  background: rgba($--primary-color-rgb, 0.1);
}

颜色计算

设计师希望后台系统左侧导航栏的底色是通过 25% 不透明度的品牌色叠加黑色得出。

导航栏

虽说通过两个 HTML 元素叠加,就能做到这个效果,但是 HTML 结构和样式代码都会稍显复杂。通过 JavaScript 去计算出这个颜色值就方便多了:

export function mixWithBlack(color, opacity) {
  const r = parseInt(hex.slice(0, 2), 16) * opacity;
  const g = parseInt(hex.slice(2, 4), 16) * opacity;
  const b = parseInt(hex.slice(4, 6), 16) * opacity;
  const toHex = (c) => c.toString(16).padStart(2, '0');
  return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}

document.documentElement.style.setProperty(
  '--brand-nav-bg-color',
  mixWithBlack(data.primaryColor, 0.25)
);

如果还有更复杂的颜色计算,也可以使用专业的第三方库,如 tinycolor

最终效果

整页效果

评论 (0条)

发表评论

(必填)

(选填,不公开)

(选填,不公开)

(必填)