欢迎来到DIVCSS5查找CSS资料与学习DIV CSS布局技术!
您的位置:DIVCSS5首页 > CSS入门 >

CSS的设计模式

 

先了解一下什么是设计模式,设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性,设计模式使代码编制真正工程化,设计模式是软件工程的基石脉络。

CSS的设计模式当然就是设计CSS使用的模式,但深入研究的人不多,原因如下:

1、似乎没有太大必要性去强调它,有问题了改一下或者按团队规范来就行;

2、不去使用一些既有的模式也无伤大雅;

3、不少人所接触的业务量级还没有达到需要规划和组织的程度,光写布局,写特效,照顾兼容,就够喝一壶的了,没有意识去思考一些方法论的问题。

随着做更多、更大、更复杂的项目,这个时候就需要自上而下,全流程的去思考一些问题,比如前端风格的制定、色调、模块、布局方式、交互方式、逻辑等等,如果再加上团队合作,若再没有一个规划的话,

要不了多久,那些看起来没问题的代码,就会暴露出各种问题,模块命名、类的命名、文件的组织、共用模块的提取、代码的复用、可读性、扩展性、维护性。它们看起来只是一些简单的小动作,却需要你看得更远,避免将来出问题需要付出更大的代价,甚至被迫整个项目重构。

既然要对CSS进行设计,那么肯定是它本身存在一些问题或者缺陷,其中一个最明显的就是,它的任何一个规则,都是全局性的声明,会对引入它的页面当中所有相关元素起作用,不管那是不是你想要的。而独立及可组合的模块是一个可维护系统的关键所在。下就从多个层面来探讨一下,到底该怎样写CSS才是更科学的。


1、从需求出发

1.1、分

比如学习写字的时候,是不会去考虑写出来的某句话好不好,文章结构合适不合适,因为我们是意识不到的。写代码也一样,刚开始只是去定义规则,能用对了属性,语法正确,把页面实现出来了就好。慢慢地就会发现,页面也是有结构的,按照页面的结构去组织代码,会不会更好?比如分成头部、导航、侧边栏、banner区、主内容区、底部等。

这样貌似还是不够,因为还有一些东西,复用度是很高的,又不好把它归为任何一个固有模块,比如分页、弹窗等,它们不适合被放到某一个固有模块的代码中,就可以单独的分出一段专属的css和js,或许这就是组件化的由来。

1.2、拆

在分了之后,代码看起来已经比之前好很多了,组织清晰,维护性大幅提高,但是还不够,会发现另外一些东西,很细小,但复用度也很高,它们同样不适合被放到模块中去,比如边框、背景、图标、字体、边距、布局方式等等。如果我们在每个需要它们的地方,都定义一次,它们会被重复很多次,显然这背离好的实践,会造成代码冗余和维护困难。所以我们需要“拆”。拆过之后会怎样?我们想在哪里用可以直接加,需要改的时候统一改。

1.3、排

经过了“分”、“拆”,代码结构已经十分清晰,各个内容模块,功能模块,UI模块都乖巧的等待召唤,那么还差什么?还差有序的组织,分类清晰之后,还需要排列有序,从不同纬度去考量,我们总能精益求精,举例:

@import “mod_reset.css”;

@import “ico_sprite.css”;

@import “mod_btns.css”;

@import “header.css”;

@import “mod_tab.css”;

@import “footer.css”;

我们将不同的部分按照一定的顺序去摆放,能让我们的代码看起来更加有序,易于维护,同时有利于进行继承或层叠覆盖。不要小看这一步,看似可有可无,实际要求比较高的统筹规划能力,可以减少冗余代码和快速定位问题位置等,除此之外依然可以有其他的方法来帮助我们进行区分代码范围,比如:

  • 在文件头部建立一个简要的目录

CSS的设计模式

  • 使用区块注释

CSS的设计模式

在注释中,应该尽量详细的写清楚该段代码的目的,状态切换,调整原因,交互逻辑等等,这样不仅利于自己的维护,更加利于别人接手维护你的代码。


2、从结论出发

除了需求部分,另外一些也是需要注意,它们来源于我们的实践经验,比如以下。

2.1、层级嵌套不要太深

了解浏览器渲染原理的都知道,它在解析CSS规则的时候,是从右向左,一层层的去遍历寻找,如果层级太多,必然增加了渲染时间,影响渲染速度。另外如果选择器层级过多,也就间接反应了,你的HTML结构可能写得不够简洁。

那么具体多少层合适?一般建议是不超过4层,但话又说回来,超过4层会怎样吗?不会有多明显的影响,除非你写到很恐怖的数量,或者项目极其庞杂,可能能看出来影响,其实从我们日常需求来看,4层以内足可以解决绝大多数问题。

2.2、避免使用元素选择器

出于两点考虑:

  • 和上一段提到的相关,在HTML中有很多常用的高频元素,比如div、p、span、a、ul等,如果你在多层选择器的最内层使用了元素选择器,那么在开始寻找时,浏览器就会遍历HTML中的所有该元素,显然这是没有必要的。

  • 需求和代码结构都是存在着潜在变化的,今天写好了一个页面,明天可能就要再加进去一个按钮,再加进去一句话,再加进去一个图标。我们写好的一个结构,也随时可能被复用到别的结构中去,如果你使用了元素选择器去固定某个东西,不论是新加进来的东西,还是被复用的东西加到别的结构里去,都极有可能产生样式的冲突,这个时候你又不得不写多余的样式进行覆盖修正,或者重新定义类。

所以说在具体的代码模块中,尽量不要使用元素选择器,使用元素选择器的前提是你完全确定不会导致出现问题。

2.3、避免使用群组选择器

如图

CSS的设计模式

此处只是举个例子,这里写了三组选择器,用来定义不同地方的同一种样式,其明显的缺陷是,如果有第四个地方需要使用到,你不得不再往里加一组选择器,如果有10个不同的地方,你就写10个?这对于维护来说,是很痛苦的,怎能被如此繁复又不必要的劳动所困扰,故而不推荐此种做法,完全可以提取出来一个公用类,定义统一样式,然后哪里需要放哪里,复用和维护都会更加方便。

2.4、文件引入的数量和顺序

对于刚接触网页的朋友来说,这两点也是容易忽视的,因为它们看起来没什么大影响,多几次请求,样式是否已经加载,都没那么容易把人逼疯,但是出于对用户体验的极致追求,我们还是希望文件请求次数尽量少,内容的显示有个优先顺序,文件加载有个先后顺序,这样在实在难以缩减文件大小的时候,让用户先看到更重要的,正常展示的内容。


3、从矛盾出发

我们需要一个东西被定义为通用的,以便复用,比如模块标题、按钮、提示文字、图标等,最开始的时候,我们习惯去看视觉稿的内容,是“新闻”,我们就定义“new”,是“关于”,我们就定义“about”,是红色的按钮,我们就定义“red-btn”等,这样会导致一个问题,如果有另外一个跟新闻列表差不多的样式和结构,但不是新闻,怎么办?继续使用“new”显然不合适,这就告诉我们不能把目光局限于内容,就需要处理这些矛盾。

3.1、团队和个人的统一

一个团队当中,大家的经历不同,编码水平和习惯也不同,这样就会造成,一个人一个写法,你用中划线,我用下划线;我用英文全拼,你用简写等等。这些虽然没有什么对错之分,但对于团队成员之间的协作造成了不小的障碍,别人必须花时间去适应和读懂你是怎样组织和定义的,这就无形之中提高了成本。

所以就有了“团队规范”存在的必要,规范除了一些写法上的规定,让我们的代码更加统一,清晰,可读性更强,辨识度更高。还可以提取一些最佳实践和复用模块等,对于团队里每个人来说,都是有好处的。

当然对于人来说,最难的莫过于调整既有的习惯,这就会有进入一个团队之后“转型”的阵痛,其实这种痛也是成长的痛,你会学习到更好的编码方式,更好的实践方法,会从项目或者团队的整体去考量一件事的价值和意义。

3.2、CSS和预处理器

预处理器的语法和CSS完全兼容的,也就是说,你在LESS或者SASS文件中,直接写CSS代码是没有问题的。除此之外它能给我们提供很多便利,比如定义统一的变量;使用嵌套而不用一直重复着写一些选择器;可以提取公共的代码块然后很方便的复用等等。故而当我们已经把CSS组织和书写得很好了之后,预处理器就是再次为我们插上一双翅膀,能更灵活和高效的编码。


4、从现有模式出发

看看一些广为流传的模式。

4.1、OOCSS——Object Oriented CSS

接触过计算机的应该都知道,OOP——Object Oriented Programming,如果你是第一次接触OOCSS,你会很困惑,难道是“面向对象的CSS”吗?它不是一本真正的编程语言啊,如何面向对象?

OOCSS的两大原则是:separating structure from skin and container from content.

直译过来就是,结构和皮肤分离,容器和内容分离。即不要把结构和皮肤以及内容进行强耦合,而是相互独立,所要达到的目标是更易复用和组合,可以选择使用,选择引用等。

4.2、SMACSS——Scalable and Modular Architecture for CSS

从实践上说,OOCSS给出了一种值得借鉴的思想,但在代码的组织方面,它并未给出具体的实施方法,从这一点上来说,SMACSS更进一步。

核心是:

  • Base(基础):基础的样式,就是一些需要最先定义好,针对于某一类元素的通用固定样式。

  • Layout(布局):布局样式,是跟页面整体结构相关,譬如,列表,主内容,侧边栏的位置、宽高、布局方式等。

  • Module(模块):模块样式,就是我们在对页面进行拆的过程中,所抽取分类的模块,这类的样式分别写到一起。

  • State(状态):页面中的某些元素会需要响应不同的状态,比如,可用、不可用、已用、过期、警告等等。将这类样式可以组织到一起。

  • Theme(主题):主题是指版面整个的颜色、风格之类,一般网站不会有频繁的较大的改动,给我们印象比较深的是QQ空间,其他应用的不是很多,所以这个一般不会用到,但有这样一个意识是好的,需要用到的时候,就知道该怎样规划。

有了以上5点分类策略,把代码组织起来,思路就会很清晰,会安排的很有序,另外的好处是可以解决命名难和混乱,之所以有这个问题,原因是我们不知道以怎样的标准去定义元素的所属和特点,有了分类之后,我们不会很随意和混乱的去命名,有了依据,就能更轻松,也不易冲突。

4.3、Meta CSS

样式和结构、内容无关,预先定义好这么一组规则,在需要的地方加上即可,我每个人第一次看到这种写法的时候,都会想:还能这样写啊?!是的总有一些人,一些新的思想和方法会涌现出来,它就是其中之一,当然并不是在称赞其本身有多么好,而是说这种现象和过程是好的,它本身经常被人吐槽,比如:“这样写和直接内联有区别吗?”、“如果要调整样式,就要去改HTML,维护更加麻烦,也有违样式和结构分离的初衷”等等,如果你要把这些抽离出来,那么还有什么抽不出来的呢?而且这些属性,在项目之间,页面之间,模块之间,并没有太大的通用性,把这些抽出来,只不过是稍微懒省劲儿些,但为了照顾到更多情况,你必须写入冗余代码。

CSS的设计模式

4.4、BEM

严格说来BEM不是一套有骨有肉的模式,也不仅仅局限你在CSS的层面去规划,它是一种怎样去组织、编写代码的思想,而且看似简单的它,对前端界的影响却是巨大的。

CSS的设计模式

它的核心如下:

Block(块)、Element(元素)、Modifier(修饰符)

它的出现曾给不少人带来启发,但是也有另一部分人仍然抱着挑剔的态度,譬如:

  • 风格不统一,显得代码不够整洁美观

  • 可能会导致类名过长

你可以不去直接用它,但要清楚它的优点:能够使得我们仅通过类名就知道哪些代码是属于一个模块内,以及在模块中所起的作用。然后借鉴之。当然BEM集聚了很多人的心血,也得到了很多的赞誉,其中就包括OOCSS的作者。所以它肯定不是这么简单,它还会告诉你,怎样配合着js来写,你的文件怎样组织更好,项目该怎么构建等。


5、从实际出发

到底怎样使用设计模式?虽然已经有成熟的设计模式,但在实际当中,你可能觉得哪个跟自己的项目都不能完全吻合,或者你要去为了使用它们而调整,成本很高。其实我们不需要去迎合模式,你需要去了解它们背后的原理,要知道它们用什么方式解决了什么问题,然后借鉴之,用它的方式解决我们的问题就可以了。

前端开发的三驾马车——html、css、js,不要孤立的去谈那样好或者这样好,我们极少会有只用一次的代码或者模块,也不会只写一种语言,三驾马车都是在一起协作的,都是会有复用、扩展和团队合作多方面的因素在里面,故而不能抱着这样的想法:我现在就在做这个,它就是唯一的,就是固定的,没问题。其实很多问题都是潜在的,要带着发展眼光去看待。项目的文件之间,项目之间,团队成员之间,不论你的分工是哪块,都要考虑到前后的影响和可能给合作带来的不便。

有“实践”,才有“最佳”,脱离实际情况谈最佳,就是空中楼阁。那么最好的模式,不是哪个经典的模式,而是在项目进行中,不断的磨合调整而出的。

 

如需转载,请注明文章出处和来源网址:http://www.divcss5.com/rumen/r50573.shtml

我要分享到:

必备CSS教程 Essential CSS Tutorials

必备HTML基础教程 Essential HTML Tutorials

如对文章有任何疑问请提交到DIV CSS论坛,或有任何网页制作CSS问题立即到CSS论坛发贴求解 或 直接DIVCSS5网页顶部搜索遇到DIVCSS疑问。
CSS教程文章修订日期:2018-06-28 15:57 原创:DIVCSS5
本文www.divcss5.com DIVCSS5版权所有。