当前位置: 首页 > 科技观察

如何编写可维护的CSS库?

时间:2023-03-17 22:18:43 科技观察

前言如何编写一个可维护的CSS库?不妨谈谈CSS的设计模式/架构。下面给大家介绍三种主流的CSS设计思想和最近的一种通用CSS设计思想:OOCSS、SMACSS、BEMCSS、METACSS。OOCSSOOCSS,字面意思是面向对象的CSS,是由NicoleSullivan提出的css理论。虽然是理论,但更像是程序员之间约定的规范:Separatestructureandskin(分离结构和主题)减少对HTML结构的需求RelyonSeparatecontainerandcontent(分离容器和内容)增加样式的可重用性.在OOCSS的概念中,强调类的复用,应该避免使用id作为CSS选择器。OOCSS追求组件的复用,它的类名比较抽象,一般不反映具体的东西,而是侧重于表现层的抽取。SMACSSsmacss使用灵活的思维过程来检查你的设计过程和方法是否符合你的架构设计的主要规范。主要有三点:CategorizingCSSRules(对css进行分类)NamingRules(命名约定)MinimizingtheDepthofApplicability(最小化适用性匹配深度)CategorizingCSSRules是SMACSS的核心。SMACSS认为css有5类,即:1Base2Layout3Module4State5ThemeorSkinBaseRules基本规范描述了页面元素在任何场合下的默认外观。它的定义不使用类和ID。CSS重置也属于这一类。常见的布局规范如normalize.css和CSSToolsLayoutRules,元素是分层次的,LayoutRules属于较高层次,可以作为较低层次ModuleRules元素的容器。左右栏目、网格系统等都是布局规范。布局是一个网站的基础,无论是左还是右,居中,甚至是其他任何布局,要实现页面的基本浏览功能,布局是必不可少的。SMACSS还同意使用前缀l-/layout-来标识布局的类。举一个最常见的例子。.layout-header{}.layout-container{}.layout-sidebar{}.layout-content{}.layout-footer{}Module规则模块规范,模块是SMACSS最基本的思想,也是CSS最基础的理论基本上,模块化样式可以达到可重用和可维护的目的,但是SMACSS提出了更具体的模块化解决方案。SMACSS中的模块有自己的名字,模块下的类都是以模块为前缀。示例如下:.todolist{}.todolist-title{}.todolist-image{}.todolist-article{}可以看做是一个模块,todolist包含title、image、article等组件。在同时,还可以添加装饰类,如.它变得更易于使用并提高了可扩展性和灵活性。如果只是为了装饰而编写大量的类而没有任何可重用性,那是一种弄巧成拙的做法。StateRules状态规范,很多前端开发者应该都很好理解,它描述了任何元素在特定状态下的外观。例如,消息框可能具有成功和错误等状态。不同于OOCSS抽取修改类的方式,SMACSS抽取更高层次的样式类以获得更强的复用性,比如隐藏元素的方式:.is-hidden{display:none;}ThemeRulesthemespecification,描述外观的外观页面主题,一般是指颜色和背景图片。ThemeRules可以修改前4类的样式,并且应该和前4类分开(方便切换,即“换肤”)。SMACSS的ThemeRules不需要使用单独的类名,即可以在ModuleRules中定义.header{}然后使用.Stylecontent)NamingRules命名规则按照前五种划分:BaseRules(Pass)LayoutRules使用前缀l-或layout-,例如:.l-header,.l-sidebar。模块规则使用模块本身的名称,例如图文排列的.media和.media-image。状态规则以is-为前缀,例如:.is-active、.is-hidden。如果将ThemeRules作为单独的类使用,则使用theme-前缀,例如.theme-a-background、.theme-a-shadow。MinimizingDepthofApplicability最小适配深度原则,简单例子:/*depth1*/.sidebarulh3{}/*depth2*/.sub-title{}两段css的区别在于html之间的耦合度而css(这一点与OOCSS的容器和内容分离的原则不谋而合)。可以想象,由于上述样式规则使用了继承选择器,实际上对HTML的结构有一定的依赖性。如果重构了html,很可能就没有这些样式了。相应的,下面的样式规则只有一个选择器,所以不依赖于具体的HTML结构,只要给元素添加一个class,就可以得到对应的样式。当然,继承选择器是有用的,可以减少相同命名带来的样式冲突(多人协作开发中经常出现)。但是我们也不要过度使用,在不引起样式冲突的允许范围内,尽量使用不限制html结构的短选择器。这就是SMACSS的最小适配深度的意思。BEMCSSBEM全称:Block(块)、Element(元素/子块/组件)、Modifier(修饰符),是一种组件化的CSS命名方式和规范,由俄罗斯Yandex团队提出。其目的是将用户界面划分为独立的(模块)模块,使开发更加简单快捷,便于团队协作开发。特性组件/模块化开发思想。写法的解耦不会造成namespace的污染,比如.xxxulli的写法带来的潜在嵌套风险。命名方式扁平化,避免样式层次过多导致解析效率降低和渲染开销增加。组件结构独立,减少样式冲突,完成的组件可以快速应用于新项目。具有良好的可维护性、易读性和灵活性。规则BEM的命名方式在社区中有不同的方式。以下是Yandex团队提出的命名规则(本文代码采用此规则):.[Block块]__[Element元素]_[Modifier修饰符]不同的命名方式,区别在于BEM之间的连接符号各不相同,因人而异:.[blockblock]__[Elementelement]--[Modifiermodifier]任何规范都是根据实际需要,方便团队开发和维护扩展,每一个规范都是一个“idea”合理评价得出的“推荐”。块(block)是一个独立的实体,通常被称为模块或组件。示例:页眉、菜单、搜索规则块名称必须能够清楚地表达其用途、功能或含义,并且是唯一的。块名称与-连接。每个块名前面应该有一个前缀,在CSS中有一个命名空间(例如:m-,u-,分别代表:mod模块,ui元素)。每个块在逻辑上和功能上都相互独立。由于块是独立的,所以在应用开发中可以重复使用,从而减少代码重复,提高开发效率。块可以放置在页面上的任何位置,并且可以相互嵌套。同一类型的块在显示上可能会有一定差异,所以不要定义过多的外观显示样式,主要负责结构的展示。当块被重用并嵌套在不同的地方时,这确保了更高的可扩展性。综上所述,我们最终可以将BEM规则定义为:.[Namespace]-[ComponentName/Block]__[ElementName/Element]--[Modifier]Scenario需要构建一个搜索组件。写法.m-search{}结构如果你打算开发一个框架,你可以使用有代表性的缩写来表示命名空间:ElementUI(el-)、AntDesign(ant-)、iView(ivu-)。元素(element)是块中的一个组件,对应块中的一个子元素/子节点。示例:标题标题、菜单项、列表项规则元素名称需要能够简单地描述其结构、布局或含义,并在语义上与块相关联。块和元素通过__连接。不能与方块分开使用。块的内部元素被认为是块的子元素。块中元素的类名必须以父块的名称为前缀,因此不能写成:block__elem1__elem2。上下文搜索组件包含输入和按钮,它是列表中的子元素。写.m-search{}.m-search__input{}.m-search__button{}结构搜索写的时候原则上不会出现两层以上的嵌套,所有样式都是扁平化的,嵌套只出现在.m-block_active,状态处于活动状态时的情况。修饰符定义块和元素的外观、状态或类型。示例:颜色、禁用、大小规则修饰符需要直观且易于表达,它们的外观、状态或行为。修饰符使用_连接块和元素。修饰符不能单独使用。必要时可以扩展,写成:block__elem_modifier_modifier,第一个修饰符代表它的命名空间。场景假设搜索组件有多个皮肤,我们选择其中一个。并且当用户没有打字时,该按钮以禁用的样式显示。写的.m-search{}.m-search_dark{}.m-search__input{}.m-search__button{}.m-search__button_disabled{}结构搜索总结很多人觉得BEM很丑。》的东西。刚接触的时候可能会觉得有点陌生,但凡事都有一个适应的过程。如果只是为了好看而规避它的优点,我觉得是得不偿失的。我个人的建议是尝试使用BEM规范写代码,BEM命名会使类名变长,但经过GZIP等压缩后,文件大小并没有太大影响。就像早年提出的CSS的语义一样,不要不能为了语义而失去语义,语义本身的作用就是帮助大家更好的识别代码,所有的规范都是基于项目开发和团队协作,团队可以根据成员的意愿选择最合适的方式。一些通用的METACSS全局写的方法是SMACSS中通用方法思想的分支,一般以css属性和想要的效果来命名,通常以一个css属性为单位来表示属性:.df{display:flex;}Copy代码代表功能:.tcut{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;}复制代码等,封装好放到全局使用,并快速添加属性来开发页面。我的个人总结:smacss涵盖了所有细节;bemcss专注于CSS命名和语义;oocss注重可重用性,把每一个dom节点都当成一个对象,这是回归CSS基础的思想;metacss专注于快速开发,快速添加属性,粒度更细,通过添加类别来添加属性,不需要修改css来修改样式。