在最近的一个 CSS 见面会上,我向与会者提问,“有人会在平常的工做流中使用 Sass 吗?”回答结果压倒性的表示确定——保守谨慎地使用 Sass 已经成为过去式。Sass 正迅速成长为编写 CSS 的标准方式。css
这真是可贵的好消息!Sass 包含了诸多 CSS 规范未定义的特性,好比变量、控制指令、混合宏等。这些特性赋予了开发者强有力的工具,以应对复杂和持续更迭的样式表。Sass 的灵活性和健壮性,足以实现开发者任何天马行空的创意思惟。html
使人遗憾的是,虽然 Sass 的使用规模在持续扩大,但生成的 CSS 质量却在不断下降。合理的解释是:Sass 在开发者和样式表之间引入了一层抽象层。过去,咱们曾经反复修正 web 标准,如今,咱们须要一种方式将其融合入新的开发环境中。目前的问题是,Sass 规范扩展了太多东西,以致于须要持续修正以应对任何 web 标准的改变。实际上,咱们须要一种指导思想——适用且独立于 Sass,指导开发者的编程方式。前端
为了更深刻的探讨问题,咱们有必要再回顾一次当下面临的困境。web
对于 Sass 的诸多特性,最多见的滥用方式就是——选择器的过分嵌套。这里请不要误解个人意思:嵌套选择器确实是很是有用的编程方式,它组织起了局部的代码,使之更易于管理;可是,过分嵌套就是一种灾难了。sql
举例来讲,有时候嵌套会生成冗长的选择器列表,而这会严重影响渲染性能:编程
body #main .content .left-col .box .heading { font-size: 2em; }
使用如此详细的选择器弊大于利。当将来须要重写级联样式时,开发者就必须使用权值更高的选择器列表。甚至,最终须要借助 !important
的权值 —— 这种写法,上帝都看不下去,严重影响后续的可维护性。浏览器
body #main .content .left-col .box .heading [0,1,4,1] .box .heading [0,0,2,0]
最后,因为选择器依赖于 HTML 文档结构,那么如此冗长的嵌套就会下降样式的可维护性和可移植性。将来,若是咱们想要给一个父级不是 leftcol
的 box
,一样设置 heading
样式,咱们就须要再写一条样式来实现(合理的开发方案应该是复用这条样式的)。sass
生成的 CSS 代码质量低下,最大的缘由就应该归罪于过分嵌套。其余存在的问题,还包括代码的重复和耦合——有必要再次指出,这些都是使用 Sass 的不合理方式所引发的。那么,咱们应该如何更缜密的使用 Sass 呢?ruby
一种方式是建立一些规则,限制和掌控那些存在风险的特性。好比,Mario Ricalde 使用 Inception-inspired 准则限制嵌套:“嵌套永远不要超过四层”。bash
这些规则每每很是适用于新手,为他们制定了明确的使用权限。可是,一方面这种公认的规则少之又少,另外一方面 Sass 规范又在持续扩展。对于每一次新版本发布,都会带来诸多新的特性,而且使用起来会束缚开发者的创造力。单独的几条规则是没法掀起革命性影响的。
咱们应该高度重视开发过程当中的最佳实践,而不是去整理收集零散的规则。这种最佳实践的核心内容以下所示:
每一个方面各有所长:
每一个方面也各有难点:
不幸的是,虽然这些方法指出了一些使用 Sass 的技巧,但没有解决咱们的实际问题。咱们使用 Sass 的难点并非源于语法规范自己,而是咱们使用 Sass 的方式。归根结底,Sass 只是一个 CSS 预处理器;因此咱们的问题其实是,处理过程。
那么,咱们又该如何处理?
每一份工做都或多或少受到人为因素的影响,当咱们将工做投入实际生产以后,问题就会被放大出来。咱们须要认清,Sass 帮助了咱们构建 CSS,但这并非咱们奋斗的终点。实际上,若是 CSS 中引入了变量,那么大多数的事情都要改写,而 Sass 和 CSS 规范也将逐渐融合为一体——这也意味着 Sass 的消亡。
咱们实际上所须要的解决方案,并不该该针对代码自己,而应该针对做为开发者的咱们。该解决方案须要包含技术准则,以辅助开发者使用 Sass,同时还要深思熟虑放眼将来。因此,咱们须要一份了包含了相关意图和目标的公开声明,换言之,一份宣言。
当我学会 Sass 以后,我就创建了一些我的准则。时间匆匆,它们造成了宣言的雏形,经常被我用来评估新的特性和技巧——以判断它们是否适用于个人工做流程。当 Sass 羽翼丰满频频被用于个人团队时,这些信条就变得举足轻重了。
个人 Sass 宣言包含了六个信条,或者说是条款,详列以下:
虽然每一个信条均可能逐步发展为规范建议的条款,但固定不变的运用它们显然是没有意义的。接下来,让咱们进一步解析每一个信条背后的深层次思考。
最终生成的 CSS 的质量和完整性,显然要比预编前的代码更重要。
该信条是其余信条的根本。有必要认清,Sass 只是整个流程的一个处理过程,它转换为 CSS 文件,还要通过浏览器的解析。这可不是说 CSS 须要优雅的格式和极高的可读性(这每每不是关注的重点,尤为是在开发者遵循最佳实践使用压缩的 CSS),但你必须时刻警戒最终的渲染性能。
当你使用了 Sass 规范最新的特性,有必要扪心自问,“这种方式输出的 CSS 是怎样的?” 若是疑惑不清,那么就要看一看源码——能够查看生成的 CSS 代码。深度理解 Sass 和 CSS 相互之间的关系,将有助于你发现潜在的性能瓶颈,并拿出相应的对策优化 Sass 结构。
举例来讲,使用 @extend
指令继承选择器中的每一个样式。Sass 代码以下:
.box {
background: #eee; border: 1px solid #ccc; .heading { font-size: 2em; } } .box2 { @extend .box; padding: 10px; }
编译结果:
.box, .box2 { background: #eee; border: 1px solid #ccc; } .box .heading, .box2 .heading { font-size: 2em; } .box2 { padding: 10px; }
如你所见,.box2
不只仅继承了 .box
的样式,还像 .box
同样成为了 .heading
的父级选择器。虽然这只是一个小例子,但若是你不理解 Sass 的生成方式,那么就会生成意想不到的结果。
项目应该具备可移植性,远离对外部的过分依赖。
只要你使用 Sass,那么你就须要引入相关的依赖。最简单的例子就是 Sass 的安装和编译依赖于 Ruby 和 Sass gem。须要牢记的是,使用的依赖越多,作出的妥协越多,就会逐渐丧失了使用 Sass 的带来的收益:团队协做不因噎废食。
举例来讲,使用 Sass gem 能够安装不少额外的软件包——它们每每能够完成大量的工做。最经常使用的框架就要属 Compass 了,此外你还能够安装编写栅格的 gems,以及 Bootstrap 之类的框架。这些 gems 对完成大量的细碎工做很是有用,好比建立一个调色板,或是添加阴影等。
这些 gems 内建了一系列的混合宏,能够被开发者引用到本身的 Sass 文件中。不一样于开发者在项目内编写的混合宏,gem 中的混合宏存放在安装目录。gems 在外部被引用的方式,很是相似 Sass 核心功能的使用方式,并且只能经过 @include
指令调用。
这就是 gem 棘手的地方。如今咱们假设一种场景,有一支团队正致力于某个项目:团队成员之一,John,决定安装一个 gem 来辅助管理栅格。他安装后就将 gem 引入了项目,并在开发者中使用它。与此同时,另外一个团队成员,Mary,下载了项目的最新版本,想要更改一下网站的字体。她下载以后尝试进行编译,却忽然编译中断抛出了错误。因为 John 在项目中引入了额外的依赖,而 Mary 的文件中缺乏相关的依赖,致使她必须调试错误并下载相关的依赖。
在大型团队中,这种问题家常便饭。若是再算上错综复杂的版本和 gem 的内部依赖,处理起来使人崩溃。对于 Ruby 项目,维护统一的开发环境,其最佳实践就是追踪和安装确实须要的 gems 和版本。但最简单的方法,仍是尽可能避免使用额外的 gems。
免责声明:我最近正在实用 Compass 框架,并且也感受利大于弊。不过,因为 Sass 规范的建议,我已经开始考虑适时和 Compass 说拜拜了。
编写 Sass,代码结构要清晰易懂,方便后续开发者的维护工做。
Sass 能够输出严格压缩的 CSS,因此无需手动优化编译前的代码。不一样于 CSS 的注释,Sass 中的行内注释并不会出如今最终的 CSS 中。
这对于书写混合宏的文档很是有用,以下所示的注释不会被输出到最终的 CSS 中:
// Force overly long spans of text to truncate, e.g.: // @include truncate(100%); // Where $truncation-boundary is a united measurement. @mixin truncate($truncation-boundary){ max-width:$truncation-boundary; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
不管怎样,必定要考虑 Sass 中的哪些部分须要导入到最终的 CSS 文件中。
不要重复。认清并合理编写复用模式。
在开始任意项目前,明确且尝试定义既定设计中全部不一样的模块,是很是明智的作法。这也是编写面向对象的 CSS 的第一步。固然,有一些模式可能没法预测,直到编写了三四遍重复的代码以后才会意识到。
尽快抽象出这些模式,并运用到你的 Sass 中去。
将复用的值设为变量:
$base-font-size: 16px; $gutter: 1.5em;
将复用的视觉样式设为占位符:
%dotted-border { border: 1px dotted #eee; }
为须要传参的模式编写混合宏:
//transparency for image features @mixin transparent($color, $alpha) { $rgba: rgba($color, $alpha); $ie-hex-str: ie-hex-str($rgba); background-color: transparent; background-color: $rgba; filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#{$ie-hex-str},endColorstr=#{$ie-hex-str}); zoom: 1; }
若是拟采用了这一方法,就会发现,Sass 文件和生成的 CSS 文件,都会更小且易于管理。
命名约定,要专一于 HTML 的功能,而不是视觉表现。
使用 Sass 的变量,能够很是简单的主题化网站。然而,我经常会看到这样的代码:
$red-color: #cc3939; //red $green-color: #2f6b49; //green
将变量与表现效果联系在一块儿,只有一时的成效。若是设计效果改变了,红色被替换为了其余颜色,就会混淆变量和值的关系。
$red-color: #b32293; //magenta $green-color: #2f6b49; //green
更好的方式是基于特定的功能来命名这些颜色变量:
$primary-color: #b32293; //magenta $secondary-color: #2f6b49; //green
当咱们不能将视觉样式和功能性类名联系起来的时候,又该如何作呢?假设一个站点中有两个 box,分别是 “Contact” 和 “References”。设计师将两个 box 都设置为了蓝色的边框和背景。咱们想最大程度的保持灵活性,但又要尽可能缩减冗余的代码。
咱们能够在 HTML 中串联这些类名,但须要严格限制:
<div class=“contact-box blue-box”> <div class=“references-box blue-box”>
牢记,咱们要专一于功能而不是表现效果。幸运的是,使用 Sass 的 @extend
指令和占位符,将会使这种方式变得很是简单。
%blue-box { background: #bac3d6; border: 1px solid #3f2adf; } .contact-box { @extend %blue-box; … } .references-box { @extend %blue-box; … }
生成结果以下所示,其中并无 %blue-box 的代码,只有确实须要的代码被实现了。
.contact-box, .references-box { background: #bac3d6; border: 1px solid #3f2adf; }
这种方式切断了与 HTML 中描述性类名的联系,但在 Sass 文件中仍然能够被理解。为通用样式设计功能性类名,好比 base-box
,将会更有意义。
避免向编译后的 CSS 引入没必要要的改动。
若是你但愿将 Sass 引入本身的工做流中,且没有新项目的话,你可能会疑问,如何在已有代码库中使用 Sass。Sass 彻底支持 CSS,因此最基本的转变就像是将扩展名从 .css
变为 .scss
同样简单。
一旦完成了这种转换,你也许会尝试深刻理解代码,或者重构整个文件,化整为零,将选择器嵌套,引入变量和混合宏。对于接替后续开发的人来讲,前面的转变必定会带来诸多问题。虽然重构不会影响网站的显式效果,但会生成彻底不一样的 CSS 文件,并且任何改动的影响都不是孤立的。
转换为 Sass 工做流的最佳方法是按需更新文件。若是你须要改变导航的样式,能够在使用前将其分离为部件。这有助于保护现有的级联样式,而且后续的改动也会很是容易。
最近,我喜欢思考使用 Sass 的难点。这些都是咱们使用新的工做方式,所要面临和亟待解决的症结。随着对 Sass 理解的深刻,咱们最终将会找到合理的答案。
这就是个人愿景,相信这份宣言将有助于调整咱们的姿态,继续向前:使用它,改变它,甚至书写本身的宣言。要以专一于书写代码的方式为始,而不是书写的内容。
http://www.jianshu.com/p/aa1be52204a7
本文翻译自 ALISTAPART 的 A Vision for Our Sass,很是感谢 Felicity Evans 的杰出工做。