我们好,很开心又碰面了,我是”web 后端撷取”,由我带着我们一同关注后端最前沿、深入细致后端下层技术,我们一同不断进步,也热烈欢迎我们关注、点赞、珍藏、转贴!
1 结语
前段时间读了一则杯葛 css-in-js 的该文,虽然绝大部分看法都有规矩,但部分存有可深究含意,让我们分析呵呵这首诗,介绍 css 还做了什么样不懈努力,和 css-in-js 会怎样发展。
2 文本概述 2.1 内部结构/犯罪行为 vs 式样
译者指出,模块化 jsx 让 html 内部结构与犯罪行为谐振在一同是很有用的,不过式样却不应该与模块谐振起来,即使式样是一种自上而下犯罪行为。很多时候需要对中文网站进行自上而下的结构设计,将式样零散到模块中会引致更多的认知生产成本。
2.2 松谐振与紧谐振
将式样与模块松谐振,控制系统会获得Villamblard的分量与开拓性。假如式样与内部结构松谐振,两套貌似相近的的原素,可能保有完全不同的下层内部结构。不过可视化必须与内部结构紧谐振,即使可视化倚赖内部结构。
2.3 听觉连续性难题
局部性式样会妨碍听觉连续性,只有自上而下化式样就可以确保听觉连续性。
2.4 标识符F83E43Se难题
假如每一模块保护自己的式样,那么会存有很多式样标识符分页的难题,分页的标识符可移植性较低。
3 自修
不论是 css-in-js 还是 css 预校对的试著,各别都具有强悍缺点,责任编辑对 css-in-js 明确提出的批评我指出是不以为然当的,上面聊聊 css-in-js 怎样化解译者明确提出的难题,和单纯如是说 OOCSS, SMACSS, BEM, ITCSS, 和 ECSS 的路子。
3.1 css-in-js 依然具备听觉连续性
文中明确提出,中文网站式样要从自上而下考虑,模块化式样犯罪行为的缺点是化解了式样冲突难题,但因此也削弱了对自上而下样式的把控。
开发单个模块的式样分为两种情况,分别是明确风格的模块与式样独立的模块,在式样独立模块中,由于不确定会被什么样主题的中文网站所引用,因此不论是自上而下 css 还是局部性 css,都无法控制式样。在明确风格的情况下,可以先把此风格的基色确定下来,不论是抽成 sass 变量还是 js 变量,都具有可F83E43Se性。
自上而下 css 的开发,适合自上而下控制,模块通过定义 class 而不需要关心具体式样,通过自上而下 class 统一调控整体风格。而css-in-js 是自下而上的,但需要预先抽出整体风格的式样模块,其效果与自上而下 css 是等价的。
自上而下 css 控制风格:
css-in-js 风格:
const CommonContainer = styled.div“ const CommonListItem = styled.div“ const CommonSubmitButton = css“ export const Container = styled(CommonContainer)“ export const ListItem = styled(CommonListItem)“ export const CommonSubmitButton = styled.div` ${CommonSubmitButton} `
而 css-in-js 运行时的式样解析,让我们更轻易的切换主题。比如我们抽出一个公共式样包,业务标识符中的色值都从此式样包中引用,那么在不同的环境下,公共式样包可能通过所在宿主环境的判断,返回给业务标识符不同的色值,甚至与宿主环境配合,从宿主环境拿到注入的颜色,实现两套标识符在运行时轻松换肤。
3.2 css-in-js 仍具备标识符F83E43Se性
文中看法明确提出,css-in-js 这种局部性式样犯罪行为,会引致公共式样、方法难以F83E43Se,引致各个模块参杂着大量重复标识符。即使 sass 通过定义自上而下变量、mixins 方法让式样更具有F83E43Se性。
我觉得这是一种误解,在 css-in-js 模式中,通过自上而下合理的结构设计,使用 js 文件存放颜色变量、公共方法、可能会F83E43Se的 css 标识符块,其F83E43Se能力远大于 sass。
3.3 OOCSS
OOCSS 成为 css 的面向对象加强版,每一 class 只处理一件事:
.size {width: 25%;} .bgBlue {background:blue} .g-bd2{margin:0 0 10px;}
网易 NEC 就大量使用了这种思想。
这样的好处在于避免了 class 之间的冗余,让我们更容易创建可F83E43Se的 class,也不会在命名上纠结。
不过,先不说 oocss 带来的巨大零散 class 引致的保护生产成本,和修改 class 引致的巨大风险,class 的本意是语义化,假如让 class 使用一堆对象描述堆砌,我们将很难定位一个原素,也很难描述这个原素的含义。
3.4 SMACSS 为 css 分类
SMACSS 指出 css 有 5 个类别:
Base 基础式样Layout 布局式样Module 模块式样State 状态式样Theme 主题式样我们通过这 5 种类别来拼凑出完整的 class,我感觉就是对 OOCSS 的进一步规范和约束。
命名规则
对这 5 种类别,在命名时要加上对应前缀,分别是:
Base 属于基础原素,比如 div p,不需要命名Layout 使用 .l- 或 .layout-前缀Module 使用模块名命名,比如该文区块就叫 .articleState 使用 .is- 前缀,比如 .is-showTheme 使用 .theme- 前缀我觉得这样在语义化的基础上,拆分了状态、主题、布局,着实增强了 css 可读性。
最小化适配深度
尽可能减少适配层级,虽然增加适配层级会减少冲突发生率,但是会增加额外的阅读负担,以及一些 bug(旧版 ie 层级超过 255 引致式样失效)。
像 css-modules 这种化解方案恰恰反其道而行之,通过层级避免冲突,通过预校对化解阅读负担,不过在没有预校对的情况下,最小化适配深度原则依然是最有效的。
3.5 BEM
BEM 规范更像是 SMACSS 分类的加强版,通过 __element 表述后代,–modifier 表述状态,比如:
.article {} .article__label {} /* label 原素 */ .article__label–selected {} /* label 原素处于被选中状态 */ 3.6 ITCSS
类似 SMACSS 对 css 原素进行了分层:
Settings – 与预处理器一同使用,包含颜色、字体等定义Tools – 工具与方法,比如 mixins,Settings 与 Tools 都不会产生任何 css 标识符,仅仅是辅助函数与变量Generic – 通用层,比如 reset html、body 的式样Elements – 对通用原素的式样重置,比如 a p div 等原素的式样重置Objects – 类似 OOCSS 中的对象,描述一些常用的基础状态Components – 对模块式样的定义,一个 UI 原素基本由 Objects 与 Components 组成Utilities – 工具类,比如 .hiddenITCSS 的分层是非常有借鉴意义的,即便在 css-in-js 结构设计中,也可以参考此模式定义内部结构。
3.7 ECSS
ECSS 的规范是这样的:.nsp-Component_ChildNode-variant
nsp 一个尽量简短的命名空间Component 文件名ChildNode 子原素名variant 额外文本例子:
@BF 14 minutes ago
更多细节可以看此 PPT
4 总结
虽然我指出这首诗明确提出的 css-in-js 缺点绝大部分存有漏洞,但它警示了我们,css 结构设计的初衷是自上而下化控制式样,即便产生了式样冲突、混乱的难题,但我们仍要记住,在模块化开发的今天,仍要保持中文网站风格的整体性,即便使用了 css-in-js 的开发方式。
虽然译者呼吁我们不要只顾着 css-in-js,要放眼看看 OOCSS, SMACSS, BEM, ITCSS, 和 ECSS 等基于原生 css 的化解方案,但我觉得把这些思想运用到 css-in-js 是个不错的选择 :p
参考资料
原文链接:https://github.com/ascoders/weekly/blob/master/%E5%89%8D%E6%B2%BF%E6%8A%80%E6%9C%AF/27.%E7%B2%BE%E8%AF%BB%E3%80%8Acss-in-js%20%E6%9D%80%E9%B8%A1%E7%94%A8%E7%89%9B%E5%88%80%E3%80%8B.md