参考文章: 前端早读课
CSS预处理器
通常主流的CSS预编译器就这三种 (Sass,Less,Stylus) ,他们在功能方面非常相似,所以你不必担心选择哪一个会是错误的。
然而,有些人认为使用CSS预处理器开始变得越来越没必要,因为浏览器最终会慢慢实现这些功能(像变量和计算)。
此外,还有一种称为CSS后处理器的方法,有可能会让CSS预处理器过时(显然这存在些争议),我们在后面会详细介绍下。
注:预处理器比较常见,这里就不在每个进行详细的介绍了。
CSS后处理器
CSS后处理器与预处理器的区别
关键的不同点是CSS预处理器使用特殊的语法来标记需要转换的地方,而CSS后处理器可以解析转换标准的CSS,并 不需要任何特殊的语法
比如使用CSS3新增的属性–hyphens
Sass预处理器只能这样优雅的处理浏览器兼容问题
1 | @mixin hyphens($value) { |
这个地方使用了Sass的 mixin 功能,你可以定义一个CSS代码块然后在其他任何地方重用,当这个文件被编译成标准的CSS的时候,所有的@include语句都被替换成与之匹配的@mixin中的CSS。
总体来说,这个解决方案也不差,但是你仍然要为每个需要厂商前缀的的CSS属性定义一个mixin,这些mixin的定义将需要不断的维护,比如当浏览器支持了某个CSS属性后你就要在你的定义中移除掉该属性。
用css后处理器
比如使用 PostCSS 和 autoprefixer ,你就可以直接写正常的CSS并不需要指定浏览器厂商前缀,剩下的工作全交给后置处理器去处理:
1 | h1, h2, h3, h4, h5, h6 { |
当你使用CSS后处理器运行这段代码的时候hyphens: auto; 将被替换成包含所有浏览器厂商前缀的属性,这意味着你可以正常写CSS不用担心各种浏览器兼容性问题,岂不是很棒!
其他的后处理器
除了PostCSS的autoprefixer插件还有很多有意思的插件
cssnext 插件可以让你体验下一些实验性质的CSS新功能
CSS modules 可以自动改变class的名字避免名称冲突
stylelint 能检查出你CSS代码中一些定义错误和不符合规范的写法
cssnano 能像JS的tree shaking一样清理掉无用的css,并进行css优化和压缩
这些工具在过去一两年里开始流行起来,给开发者提供了从未有过的工程化流程。
后处理器的缺点
进程的发展总是有代价的,安装和使用CSS后处理比CSS预处理器更复杂。
你不仅要安装、执行命令行,还需要安装配置各个插件并且定义好各种复杂的规则(比如你的目标浏览器等)。
很多开发者不再直接使用命令行运行PostCSS了,而是通过配置一些构建系统,像Grunt 、Gulp 、webpack,他们可以帮助你管理前端开发工作中需要的各种构建工具。
css的设计模式
CSS预处理器和CSS后处理器让CSS开发体验有了巨大的提升,但是单靠这些工具还不足以解决维护大型项目CSS代码的问题。
为了解决这个问题,人们编写了一些关于如何写CSS的指导方针,通常被称为CSS规范。
在我们深入分析CSS规范前,首先要搞清楚是什么让CSS随着时间推移变得更加难维护:
关键点是CSS是全局性的——你定义的每个样式都会 全局应用 到页面的每个部分
用一个命名约定来保证class名称的唯一性或者有特殊的规则来决定指定样式应用到指定元素。
CSS规范提供了一个有组织性的方式来避免大量代码时出现的这些问题,让我们按照时间顺序来看看主流的一些规范吧
OOCSS
OOCSS(面向对象的CSS)是在2009年首次提出的,它是围绕两个原则建立的规范。
第一个原则是 结构和样式分离 ,这意味着定义结构(布局)的CSS不应该和定义样式(颜色、字体等)的CSS混杂在一起,这样我们就可以很简单的为一个应用定义新的皮肤了;
第二个原则是 容器和内容分离 ,把元素看成是一个可重用的对象,关键核心点是一个对象不管用在页面的任何位置都应该看起来是相同的。
OOCSS提供了成熟的指导规范,但是对于具体的执行规范并没有明确指出。后来出现的SMACSS采用了它的核心概念,并且添加了更多的细节,使用起来更简单了。
SMACSS
SMACSS(可扩展模块化架构的CSS)是在2011年出现的一种设计模式,
它将CSS分为5个不同的类别—— 基本规范、布局规范、模块、状态规范和样式规范 。
SMACSS也有一些推荐的命名规则,对于布局规范使用l-或者layout- 作为前缀;对于状态规范,使用is-hidden 或者is-collapsed 作为前缀。
相比OOCSS,SMACSS有了更多细节上的规范,但是CSS规则该划分为哪一类别的规范中,这是个需要仔细考虑的问题。后来出现的BEM对这一方面进行了改进,让它更易使用了。
BEM
BEM (块, 元素, 修饰符)是在2010年出现的规范,它的思想主要是围绕把用户界面切分成独立的块。
块是一个可重用的组件
举个例子像表单搜索,可以这样定义
1 | <form class="search-form"></form> |
元素是块的一部分不能单独重用
比如表单搜索中的button,
1 | <button class="search-form__button">Search</button> |
修饰符是定义了块或者元素外观、状态或者行为的实体
比如禁用搜索按钮,定义为
1 | <button class="search-form__button search-form__button--disabled">Search</button> |
BEM的规范很容易理解,对于新手来说命名规则上也很友好,缺点就是可能会导致class名字非常长,并且没有遵循传统的命名规范。后来出现的Atomic CSS又把这个非传统方式带到了一个新的高度。
Atomic CSS
Atomic CSS (也称为 功能性CSS)是2014年出现的一个规范,它的思想是基于可视化的方法创建小而功能单一化的class。
这种规范与OOCSS、SMACSS和BEM 完全相反 ——它并不是把页面上的元素看做是可重用的对象,Atomic CSS忽略掉了这些对象,每一个元素使用了可重用的单一功能的class样式集合。
因此像1
<button class="search-form__button">Search</button>
就被替换成这样的写法了1
<button class="f6 br3 ph3 pv2 white bg-purple hover-bg-light-purple">Search</button>
如果你看到这个例子第一反应是被吓的退缩了,没关系你并不是唯一有这想法的人——很多人认为这种方式完全违背了CSS的最佳实践,但是,关于这个有争议的规范在不同场景下的应用也产出了一系列精彩的讨论。
这篇文章很清晰的分析了传统的分离思想是 CSS依赖于HTML创建 (即使使用像BEM这类的规范)
而Atomic的方式是 HTML依赖于CSS创建 ,两者都没错,但是仔细想想你会发现CSS和HTML彻底分离的想法是实现不了的。
其他的CSS设计模式,像CSS in JS其实也包含了CSS和HTML相互依赖的思想,这也成为了一个饱受争议的设计规范之一。
CSS in JS
CSS in JS 是2014年推出的一种设计模式,它的核心思想是把 CSS直接写到各自组件中 ,而不是单独的样式文件里。
这种方式在React框架中引入的,最早是使用内联样式,后来又进化成了使用JavaScript生成CSS然后插入到页面的style标签中的方式。
CSS in JS再一次违背了CSS中关于分离的最佳实践,主要原因是web随着时间推移发生了很大的变化。
最初web大部分都是静态网站——这种情况下HTML内容和CSS表现分离是很有意义的,
但现在大部分应用都是动态web构建——这种情况下 可重用的组件 更加有意义了。
CSS in JS设计的目标是定义边界清晰包含自己HTML/CSS/JS的独立组件,并且不受其他组件的影响。
React是最早采用这种思想的框架,后续也影响到了其他框架像Angular、Ember和Vue.js。
需要注意的是CSS in JS的模式相对来说比较新的,开发人员正在不断的尝试开发web应用组件时的一些CSS最佳实践。
五花八门的设计模式很容易让你不知所措,最重要的记住一点—— 没有银弹
最后附上一句:
“任何一个说CSS简单的人可能只是对它一知半解吧!”
如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理