与UI设计师约定颜色命名规则
配置color变量
color.scss
sass$colors: ( ( #ffffff, #f8f8f8, #ebebeb, #dbdbdb, #cccccc, #999999, #666666, #333333, #000000 ), (#daf6ef, #b4ecde, #08c193, #228f73, #43d7b2), (#f62f3b, #edc9c9, #f0e2e2, #ffecea, #f78185), (#f2f5f8, #e3e8eb, #c3cace, #a0a6a9), (#ffb739, #dc9e40, #fff5e4), (#fffaf7, #f3cfb9, #debca1, #bd835e, #6b2d00) ); @function pad-zero($number) { @if $number < 10 { @return "0#{$number}"; } @else { @return $number; } } // 生成ui设计师颜色命名规则: c-xx-xx @function generate-colors() { $color-map: (); @for $i from 1 through length($colors) { @for $j from 1 through length(nth($colors, $i)) { $var-name: --c-#{pad-zero($i)}-#{pad-zero($j)}; $var-value: nth(nth($colors, $i), $j); $color-map: map-merge( $color-map, ( $var-name: $var-value, ) ); } } @return $color-map; }
var.scss
tsx@use "./color.scss" as *; :root { ... @each $key, $value in generate-colors() { #{$key}: $value; } }
配置unocss rule规则
uno.config.ts
tsx// uno.config.ts import { defineConfig, presetAttributify, presetIcons, presetTypography, presetUno, presetWebFonts, transformerDirectives, transformerVariantGroup } from 'unocss' import { processCss } from "./utils"; export default defineConfig({ presets: [ presetUno(), presetAttributify(), presetIcons(), presetTypography(), presetWebFonts({ fonts: { // ... } }) ], shortcuts: [ ... //layout { "full-screen-w": "w-100vw ml-[calc(-50vw+50%)]", }, //position { "absolute-h-center": "absolute left-50% -translate-x-50%", "absolute-v-center": "absolute top-50% -translate-y-50%", "absolute-vh-center": "absolute-h-center absolute-v-center" }, //pop { "pop-layer": "fixed top-0 left-0 size-auto" } ], rules: [ [/^(text|bg|border)(-.+)?-c-(\d+)-(\d+)$/, ([val, type, g1, g2, g3]) => { switch (type) { case 'text': { return { color: `var(--c-${g2}-${g3})` }; } case 'bg': { return { 'background-color': `var(--c-${g2}-${g3})` }; } case 'border': { return { 'border-color': `var(--c-${g2}-${g3})` }; } default: { return {} } } }], ], theme: { breakpoints: { sm: '640px', md: '768px', lg: '1024px', xl: '1200px', xxl: '1680px', }, colors: { primary: { DEFAULT: 'var(--c-primary)', active: 'var(--c-primary-active)', }, minor: { DEFAULT: "var(--c-minor)", active: "var(--c-minor-active)" } }, }, //! 说明:由于unocss无法识别动态class,所以需要配置出来 safelist: [ ...Array.from({ length: 1920 }, (_, i) => `w-${i + 1}px`), ...Array.from({ length: 1080 }, (_, i) => `h-${i + 1}px`), ], transformers: [ transformerDirectives(), transformerVariantGroup() ], postprocess: [ (util) => { util.entries.forEach((entry) => { entry[1] = processCss(entry[1]?.toString()); }); } ] })
如何使用
tsx
<div class="bg-c-01-02 border-c-03-01 text-c-01-02"></div>
存在的问题
tsx
<div class="bg-c-01-02/.5"></div>
// 如果要给背景色添加一个透明度,这种情况是不支持的,那么如何变得支持呢?
说明:你可能会想到改unocss的规则,那么我们来试下
tsx
rules: [
[/^(text|bg|border)(-.+)?-c-(\d+)-(\d+)\/?(.+)?$/, ([val, type, g1, g2, g3, g4]) => {
switch (type) {
case 'text': {
return { color: `var(--c-${g2}-${g3})` };
}
case 'bg': {
return { 'background-color': `rgba(var(--c-${g2}-${g3}),${g4})` };
}
case 'border': {
return { 'border-color': `var(--c-${g2}-${g3})` };
}
default: {
return {}
}
}
}],
],
说明:好些还可以,我们看下真是效果
看到这个你发现问题了,由于我们颜色变量引用的是16进制颜色值,然后rgba的参数是4个,而且是用逗号隔开。可能你会想编译后改样式,类似webpack的css loader一样,但是我们会失去unocss的提示,在开发的时候还是很不方便。所以我想到一个办法,就是把颜色变量变成red,green,blue 最后在规则中拼一个,alpha 值。
sass
$colors: (
(
255,255,255,
)
);
//这个弄是有问题的,因为逗号sass会把数字分割成3个变量,可能你会想成这样
$colors: (
(
"255,255,255",
)
);
//说明:这样最终使用的也不符合rgba参数, 最终改成这样就可以了。unquote 函数会自动把引号去掉
$colors: (
(
unquote('255,255,255'),
)
);
最后的unocss.config.ts 的规则
tsx
...
rules: [
[/^(text|bg|border)(-.+)?-c-(\d+)-(\d+)\/?(.+)?$/, ([val, type, g1, g2, g3, g4]) => {
switch (type) {
case 'text': {
return { color: `rgba(var(--c-${g2}-${g3}))` };
}
case 'bg': {
return {
'background-color': g4 ? `rgba(var(--c-${g2}-${g3}),${g4})` : `rgba(var(--c-${g2}-${g3}))`
};
}
case 'border': {
return { 'border-color': `rgba(var(--c-${g2}-${g3}))` };
}
default: {
return {}
}
}
}],
],
...
测试最终效果
完美实现我们想要的效果,这样就可以更开心的写样式了。