大家好,很高兴又见面了,我是web前端分享,由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!1引言 最近读了一篇抵制cssinjs的文章,虽然大部分观点都有道理,但部分存在可商榷之处,让我们分析一下这篇文章,了解css还做了哪些努力,以及cssinjs会如何发展。2内容概要2。1结构行为vs样式 作者认为,模块化jsx让html结构与行为耦合在一起是很有价值的,然而样式却不应该与模块耦合起来,因为样式是一种全局行为。许多时候需要对网站进行全局的设计,将样式分散到模块中会导致更多的理解成本。2。2松耦合与紧耦合 将样式与模块松耦合,系统会获得更大的自由度与拓展性。如果样式与结构松耦合,一套看似相似的的元素,可能拥有完全不同的底层结构。然而交互必须与结构紧耦合,因为交互依赖于结构。2。3视觉一致性问题 局部样式会阻碍视觉一致性,只有全局化样式才能保证视觉一致性。2。4代码复用问题 如果每个组件维护自己的样式,那么会存在许多样式代码复制粘贴的问题,复制粘贴的代码可维护性极低。3精读 无论是cssinjs还是css预编译的尝试,各自都具有强大优点,本文对cssinjs提出的质疑我认为是欠妥当的,下面谈谈cssinjs如何解决作者提出的问题,以及简单介绍OOCSS,SMACSS,BEM,ITCSS,和ECSS的思路。3。1cssinjs依然具备视觉一致性 文中提出,网站样式要从全局考虑,模块化样式行为的优点是解决了样式冲突问题,但因此也削弱了对全局样式的把控。 开发单个组件的样式分为两种情况,分别是明确风格的组件与样式独立的组件,在样式独立组件中,由于不确定会被哪些主题的网站所引用,因此无论是全局css还是局部css,都无法控制样式。在明确风格的情况下,可以先把此风格的基色确定下来,无论是抽成sass变量还是js变量,都具有可复用性。 全局css的开发,适合自上而下控制,组件通过定义class而不需要关心具体样式,通过全局class统一调控整体风格。而cssinjs是自下而上的,但需要预先抽出整体风格的样式模块,其效果与全局css是等价的。 全局css控制风格:style。container{}。listitem{}。submitbutton{}style cssinjs风格:constCommonContainerstyled。pconstCommonListItemstyled。pconstCommonSubmitButtoncssexportconstContainerstyled(CommonContainer)exportconstListItemstyled(CommonListItem)exportconstCommonSubmitButtonstyled。p{CommonSubmitButton} 而cssinjs运行时的样式解析,让我们更轻易的切换主题。比如我们抽出一个公共样式包,业务代码中的色值都从此样式包中引用,那么在不同的环境下,公共样式包可能通过所在宿主环境的判断,返回给业务代码不同的色值,甚至与宿主环境配合,从宿主环境拿到注入的颜色,实现一套代码在运行时轻松换肤。3。2cssinjs仍具备代码复用性 文中观点提出,cssinjs这种局部样式行为,会导致公共样式、方法难以复用,导致各个模块参杂着大量重复代码。因为sass通过定义全局变量、mixins方法让样式更具有复用性。 我觉得这是一种误解,在cssinjs模式中,通过全局合理的设计,使用js文件存放颜色变量、公共方法、可能会复用的css代码块,其复用能力远大于sass。3。3OOCSS OOCSS成为css的面向对象加强版,每个class只处理一件事:。size{width:25;}。bgBlue{background:blue}。gbd2{margin:0010} 网易NEC就大量使用了这种思想。 这样的好处在于避免了class之间的冗余,让我们更容易创建可复用的class,也不会在命名上纠结。 然而,先不说oocss带来的巨大零散class导致的维护成本,以及修改class导致的巨大风险,class的本意是语义化,如果让class使用一堆对象描述堆砌,我们将很难定位一个元素,也很难描述这个元素的含义。3。4SMACSS为css分类 SMACSS认为css有5个类别:Base基础样式Layout布局样式Module模块样式State状态样式Theme主题样式 我们通过这5种类别来拼凑出完整的class,我感觉就是对OOCSS的进一步规范和约束。命名规则 对这5种类别,在命名时要加上对应前缀,分别是:Base属于基础元素,比如pp,不需要命名Layout使用。l或。layout前缀Module使用模块名命名,比如文章区块就叫。articleState使用。is前缀,比如。isshowTheme使用。theme前缀 我觉得这样在语义化的基础上,拆分了状态、主题、布局,着实增强了css可读性。最小化适配深度 尽可能减少适配层级,虽然增加适配层级会减少冲突发生率,但是会增加额外的阅读负担,以及一些bug(旧版ie层级超过255导致样式失效)。 像cssmodules这种解决方案恰恰反其道而行之,通过层级避免冲突,通过预编译解决阅读负担,然而在没有预编译的情况下,最小化适配深度原则依然是最有效的。3。5BEM BEM规范更像是SMACSS分类的加强版,通过element表述后代,modifier表述状态,比如:。article{}。articlelabel{}label元素。articlelabelselected{}label元素处于被选中状态3。6ITCSS 类似SMACSS对css元素进行了分层: Settings与预处理器一起使用,包含颜色、字体等定义Tools工具与方法,比如mixins,Settings与Tools都不会产生任何css代码,仅仅是辅助函数与变量Generic通用层,比如resethtml、body的样式Elements对通用元素的样式重置,比如app等元素的样式重置Objects类似OOCSS中的对象,描述一些常用的基础状态Components对组件样式的定义,一个UI元素基本由Objects与Components组成Utilities工具类,比如。hidden ITCSS的分层是非常有借鉴意义的,即便在cssinjs设计中,也可以参考此模式定义结构。3。7ECSS ECSS的规范是这样的:。nspComponentChildNodevariantnsp一个尽量简短的命名空间Component文件名ChildNode子元素名variant额外内容 例子:imgclasstlMediaObjectMediasrcc2021imgdataimg。jpgdatasrcimgq01。71396。combl3h5d63e6b44181af3d。jpgaltUserBF14minutesago 更多细节可以看此PPT4总结 虽然我认为这篇文章提出的cssinjs缺点大部分存在漏洞,但它警示了我们,css设计的初衷是全局化控制样式,即便产生了样式冲突、混乱的问题,但我们仍要记住,在模块化开发的今天,仍要保持网站风格的整体性,即便使用了cssinjs的开发方式。 虽然作者呼吁我们不要只顾着cssinjs,要放眼看看OOCSS,SMACSS,BEM,ITCSS,和ECSS等基于原生css的解决方案,但我觉得把这些思想运用到cssinjs是个不错的选择:p参考资料 原文链接:https:github。comascodersweeklyblobmasterE5898DE6B2BFE68A80E69CAF27。E7B2BEE8AFBBE3808Acssinjs20E69D80E9B8A1E794A8E7899BE58880E3808B。md