刚接触到原子样式时,absolute / top-10 / m-10 / mx-10 / text-primary / text-red-100 都会让我们觉得语义简单,使用方便。但从样式治理的角度来说,这类命名在组件或者即时编译技术中使用时,相对零散,使用繁琐,具有改进的空间。原子样式的分组和简化工作也有诸多开发者尝试。

基于样式分组和组合,如果要使样式名具有统一的范式,那么必须修改现有的原子样式的惯用命名方式。

【原子样式实践】第11篇 基于分类的原子样式名称重构_原子CSS

样式名规则

​[mediaType]-[propertyExpression]​


1 mediaType 设备类型

​[Media][Width]​

mediaType 表示适用设备类型,最长两位,左侧是高位,右侧是低位。

高位表示设备类型,有效值包括 ​​s​​​ - screen, ​​p​​ - printer,可缺省,默认无值,可使用_表示

低位表示设备宽度,有效值包括 ​​s​​​ - small, ​​m​​​ - medium, ​​l​​​ - large, ​​x​​​ - extra large(xl), ​​y​​​ - extra extra large(xxl), ​​z​​​- extra extra extra large(xxxl),可缺省,默认无值,可使用 ​​_​​ 表示

当 mediaType 仅有一位时,表示低位。


2 propertyExpression 属性表达式

2.1 定义

[propertyGroupName](-[value])+​

propertyGroupName 属性类名,必须为字母

constraint 属性约束,比如方向,可缺省,必须为字母

value 属性值,必须为数字或者字母

valueOrder 如果值为数组,表示值的序号,可缺省,必须为数字

extraValue 附加定义,可缺省,必须为数字或者字母


2.2 数值定义

​[property][constraint][valueSign][decimalValue][valueUnit]​

property 属性名称,可缺省,必须为字母

constraint 属性约束,比如方向,可缺省,必须为字母

valueSign 属性值符号,_表示负数,缺省为非负数

decimalValue 属性值,必须为数字或者小数点

valueUnit 属性计量单位,必须为字母,可缺省,p - 百分号


2.3 主色彩定义

​(primary|white|black)[alpha]​

value 属性值,必须为数字或者字母

alpha 附加透明度定义,可缺省,必须为数字


2.4 其他色彩定义

​[colorValue][valueOrder][alpha]​

value 属性值,必须为数字或者字母

valueOrder 如果值为数组,表示值的序号,最多1位,可缺省,必须为数字

alpha 附加透明度定义,可缺省,必须为数字


2.5 字符串定义

​[stringValue]​

表示属性值,必须为字母,比如对齐


3 属性

3.1 layout 布局

(1) 浮动布局

pos-abs-rel-fix-stick-static-z1-t_.5-b10-l10-r_10-x0-y0-0

其中 t_0.5 = { top: -0.5rpx }

x0 = { left:0; right:0 }

0 = { left:0; right:0; top:0; bottom: 0 }

(2) 弹性布局

flex-row-wor-col-loc-wrap-as-ac-ae--js-jc-je-ja-jb-jev-g5-gx5-gy5

其中 g5 = { grid-gap: 5rpx }

(3) 网格布局

grid-cols5--rows5-1v3-g5-gx5-gy5

其中 1v3 = { grid: 1fr 3fr  }


3.2 spacing 空间

(4) 外部空间 margin 

m-5-x5-y5-t5-b5-l5-r5-x-y0

其中

m-x= { margin-left: auto; margin-right: auto }

m-y0= { margin-top:0; margin-bottom: 0 }

(5) 内部空间 padding

p-10-x32-y20-t20-b20-l20-r20-x-y0


3.3 sizing 尺寸

(6) 高宽度 widthxheight

size-60-100p-x100-y50

(7) 宽度 width

w-100-100p-.5-m100-x200-33.3p

(8) 高度 height

h-80-20p-d5-m60-x100


3.4 text 文本

(9) 文本 text

text-number-8-red6-bold-normal-line-break-left-center-right-height28-space5-uppercase-lowercase-ellipsis-indent8-underline


3.5 background-color 背景色

(10) 背景色

bg-primary / bg-black30 / bg-red630 


3.6 decoration 装饰

(11)圆角

round-10-x10-y10-t10-b10-l10-r10-tr10-tl10-bl10-br10-w2-red630-solid-dashed-dotted

(12)透明度

opacity-30

(13)阴影

shadow / shadow-1


3.7 transform 变换

(14)变换

t-rotate90-scale2


3 属性信息提取

基于 javascript 语言的有效样式名检测正则表达式为

((?<media>[s|p]?)((?<width>[smlxyz])-))?(?<propGroupName>[a-z]{1,7})(?<propGroupValue>-[a-z0-9-\\._]+)?

对于具体的属性值,检测正则表达式为

^(((?<mainColor>primary|black|white)(?<mainAlpha>\d{0,2}))
|((?<color>red|blue|yellow|cyan|lime|mengacy)(?<order>\d)(?<alpha>\d{0,2}))
|(?<stringValue>[a-z]+)
|((?<prop>[a-z]{0,8})?(?<constraint>[xytblrm]{0,2}))(?<numberValue>_?([0-9\\.]+p?))(v(?<compare>\d+))?)$

属性信息提取:

<script>

const p = (obj) => Object.keys(obj).filter(m => obj[m] !== undefined).reduce((dict, key) => {
dict[key] = obj[key];
return dict
}, {})


const items = ["pos-abs-rel-fix-stick-static-z1-t_.5-b10-l10-r_10-x0-y0-0",
"flex-row-wor-col-loc-wrap-as-ac-ae--js-jc-je-ja-jb-jev",
"grid-cols5-rows5-1v3",
"gap-5-x5-y5",
"m-5-x5-y5-t5-b5-l5-r5-x",
"p-10-x32-y20-t20-b20-l20-r20-x",
"size-60-100p-x100-y50",
"w-100-100p-.5-m100-x200-33.3p",
"h-80-20p-.5-m60-x100",
"text-number-8-red6-bold-normal-line-break-left-center-right-height28-space5-uppercase-lowercase-ellipsis-indent8-underline",
"bg-primary-black30-red630",
"round-10-x10-y10-t10-b10-l10-r10-tr10-tl10-bl10-br10-w2-red630-solid-dashed-dotted",
"opacity-30",
"shadow",
"shadow-1",
"t-rotate90-scale2"].map(m => {
const c = m.match(/((?<media>[s|p]?)((?<width>[smlxyz])-))?(?<propGroupName>[a-z]{1,7})(?<propGroupValue>-[a-z0-9-\\._]+)?/)
return c && c.groups ? {
media: c.groups["media"], width: c.groups["width"], propGroupName: c.groups["propGroupName"],
propGroupValue: c.groups["propGroupValue"],
prop: !c.groups["propGroupValue"] ? {stringValue: c.groups["propGroupName"]} : c.groups["propGroupValue"].split("-").filter(m => m)
.map(s => {
let props = s.match(/^(((?<mainColor>primary|black|white)(?<mainAlpha>\d{0,2}))|((?<color>red|blue|yellow|cyan|lime|mengacy)(?<order>\d)(?<alpha>\d{0,2}))|(?<stringValue>[a-z]+)|((?<prop>[a-z]{0,8})?(?<constraint>[xytblrm]{0,2}))(?<numberValue>_?([0-9\\.]+p?))(v(?<compare>\d+))?)$/)
return props && props.groups ? p(props.groups) : []
})
} : {}
})
console.log(items)

</script>


4 小结

通过 pos/flex/grid 等14个属性组关键词进行了样式名称重建,灵活易记。