大家好,我是Pitang。近期,由于业务调整,前端工程基础建设已在集团启动。我主要负责CSS技术的选型。我对目前业界的几种主流方案进行了比较完整的研究和比较,分享给大家。目前整个CSS工具链和工程领域的主要解决方案如下:我们的技术选择标准是:开发速度快、调试体验友好、可维护性友好、扩展性友好、协作友好、规模友好、最佳实践指导目前主要有三套方案需要对比:Less/Sass+PostCSS的纯CSSc端方案、styled-components/emotion的纯CSS-in-JS端方案、HTML端TailwindCSS解决方案,主要写辅助类,纯CSS端解决方案介绍及优势维护状态:一般星级数:16.7K支持框架:无框架限制项目地址:https://github.com/less/less.jsLess/Sass+PostCSS这个方案目前在主流的组件库和企业级项目中被广泛使用,比如ant-design等,它们的主要功能如下:给CSS添加类JS特性,也可以使用变量、mixins、写判断等引入模块化概念,可以在一个less文件中导入另一个less文件使用兼容标准,可以快速使用CSS新特性,兼容浏览器CSS差异等。这类工具可以和主流的工程工具一起使用,比如Webpack,并提供相应的loader比如sass-loader,然后你就可以在React/Vue项目中创建.scss文件,编写sass语法,并将它们导入到React组件中以使其生效。比如我写了一段Sass代码,在响应的每个断点下显示一个组件的情况:.component{width:300px;@media(最小宽度:768px){宽度:600px;@media(min-resolution:192dpi){背景图片:url(/img/retina2x.png);}}@media(最小宽度:1280px){宽度:800px;}}或者导入一些代码来标准化浏览器差异:@import"normalize.css";//与组件相关的其他代码不足这种解决方案的主要问题之一是它只是增强了CSS本身,而没有提供帮助开发人员如何编写更好的CSS、更高效和可维护的CSS的任何建议。你还是需要自己定义CSSclasses和ids,并思考如何组合这些classes和ids来描述HTML样式。你可能还会写很多冗余的Less/Sass代码,这会给项目造成负担。在可维护性方面优化也存在巨大问题。可引入CSS设计规范:BEM规范,协助用户在整个网页的HTML骨架和相应的类上进行设计。可以引入CSSModules来限制CSS文件的“范围”,以确保它们可以在以后维护,修改一个内容不会引起全局BEM规范中其他样式B(Block)、E(Element)、M(Modifier)的效果,具体通过blocks、elements、behaviors定义所有视觉功能。以设计一个Button为例:/*Block*/.btn{}/*ElementdependentbyBlock*/.btn__price{}/*Modifier修改Block样式*/.btn--orange{}.btn--big{}一个符合上述规范的真实Button:$3BIGBUTTON可以实现如下效果:CSSModulesCSSModules主要是给CSS添加局部作用域和模块依赖,让CSS也可以组件化。示例如下:importReactfrom'react';importstylefrom'./App.css';exportdefault()=>{return(HelloWorld);};.title{组成:className;color:red;}编译后,上面会变成如下hash字符串:HelloWorld._3zyde4l1yATCOkgn-DBWEL{color:red;}CSSModules可以和plain结合CSS、Less、Sass等。纯JS端解决方案介绍及优势维护状态:总星数:35.2K支持框架:React,通过社区支持Vue等框架项目地址:https://github.com/styled-com...使用JS模板字符串功能,用JS编写CSS代码,带来了两个认知上的变化:不再是基于HTML编写CSS,而是从组件设计的角度,为组件编写CSS,然后应用组件构建的组合思想大型应用程序自动提供类似于CSSModules的体验,无需担心样式的全局污染。同时带来了很多JS端独有的功能和特性,让开发者可以像开发JS一样开发CSS,比如编辑器自动补全Full、Lint、编译压缩等。就像我写的一个按钮:constButton=styled.button`/*根据主要道具调整颜色*/background:${props=>props.primary?“palevioletred”:“白色”};颜色:${props=>props.primary?“白色”:“palevioletred”};字体大小:1em;保证金:1em;填充:0.25em1em;border:2pxsolidpalevioletred;border-radius:3px;`;render(Primary
);可以获得如下效果:还可以扩展样式://TheButton从上一节开始,没有插值constButton=styled.button`color:palevioletred;字体大小:1em;保证金:1em;填充:0.25em1em;border:2pxsolidpalevioletred;border-radius:3px;`;//基于Button的新组件,但有一些覆盖样式constTomatoButton=styled(Button)`color:tomato;border-color:tomato;`;render(番茄按钮;
);可以获得如下效果:不足此类方案虽然提供了在JS中编写CSS,但充分利用了JS的插值、组合等特性,再将React组件等组合思想应用到细粒度组件和CSS中绑定允许CSS与组件一起开发,同时提供类似于组件的模块化特性。与Less/Sass相比,它可以复用JS社区的最佳实践等,但也有一些不足:它仍然是对CSS的增强,提供了很大的灵活性。开发人员仍然需要考虑如何组织自己的CSS。没有一套“观点”最佳实践。上层也缺乏基于styled-components的复用。素材库可用于参考设计和使用,导致初始化和使用时开发速度慢。用JS写CSS必然会带来一些属于JS的局限性。比如在TS下,Styled组件需要进行类型注解官方维护内容只兼容React框架,而Vue等框架是社区支持的。总体而言,它们不适合团队协作,需要手动总结最佳实践和规范。优化寻求一套编写CSS的最佳实践和团队合作规范能够拥有大量素材库或辅助类等,提高开发效率,快速完成应用开发更喜欢HTML端解决方案介绍和优势维护状态:活跃星号:48.9K支持Framework:React,Vue,Svelte等主流框架项目地址:https://github.com/tailwindla...典型的是TailwindCSS,一个辅助类优先的CSS框架,提供如flex,pt-4、text-center、rotate-90,从这些底层辅助类向上构建任何网站,只需要专注于为HTML设置类名。更形象的例子可以参考下面的代码:style类名设计,然后设计两个按钮,这两个类名类似于主流组件库中Button不同状态的设计,这两个类由更基础的TailwindCSS辅助类组成:.btn{@applytext-basefont-mediumrounded-lgp-3;}.btn--primary{@applybg-rose-500text-white;}.btn--secondary{@applybg-gray-100text-black;}以上辅助类包括以下几类:设置文字相关:text-base,font-medium,text-white,text-black设置背景相关:bg-rose-500,bg-gray-100设置间距相关:p-3corners相关的设置:rounded-lg使用Tailwind提供的@apply方法,将这些辅助类组合起来构建更高层的样式类。以上最终效果如下图:我们可以看到TailwindCSS将我们网站开发的过程抽象为使用Figma等设计软件设计界面的过程,同时提供了一套设计规范,相当于内置了最佳实践,比如color和shadow,字体相关的内容,一张很形象的图就可以说明这一点:TailwindCSS为我们规划了一个元素可以设置的属性,并给出了一组可以为每个属性设置的值。这些属性+属性值组合成一个有机的设计体系,非常方便团队协作和共识,让我们开发网站像设计一样简单快捷,同时又能保持整体风格的一致。TailwindCSS也可以与React、Vue、Svelte等主流组件库结合,融入基于组件的CSS设计思想,而只需要修改HTML上的类名,比如我们设计一个菜谱组件://Recipes。jsimportNavfrom'./Nav.js'importNavItemfrom'./NavItem.js'importListfrom'./List.js'importListItemfrom'./ListItem.js'exportdefaultfunctionRecipes({recipes}){返回(NavItemhref="/recent">Recent{recipes.map((recipe)=>())}