Sass 与 Less

Avatar of Chris Coyier
Chris Coyier on

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 免费积分!

“我应该选择哪个 CSS 预处理器语言?” 近期成为热门话题。 我被亲自问过几次,而且似乎每隔几天就会出现一次在线辩论。 很高兴讨论已经从是否预处理是一个好主意转变为哪种语言是最好的。 让我们开始吧。

非常简短的答案:Sass

稍长一些的答案:Sass 在许多方面都更好,但是如果您已经习惯使用 Less,那就很酷了,至少您通过预处理对自己有所帮助。

更长的答案:继续阅读。

更长的答案

使用 Ruby、命令行等的学习曲线

唯一的学习曲线是语法。 您应该使用 CodeKitLiveReloadMixture 等应用程序来监视和编译您创作的文件。 您不需要了解有关 Ruby、命令行或其他任何内容的任何信息。 也许您应该知道,但您不必知道,所以这里不是一个因素。 Sass 使用 Ruby 以及 Less 使用 JavaScript 对于大多数潜在用户来说意义不大。

获胜者:没有

帮助使用 CSS3

使用任何一种语言,您都可以编写自己的 mixin 来帮助使用供应商前缀。 那里没有获胜者。 但是您知道您不会返回并更新您在所有项目中使用的前缀吗?(您不会。)您也不会更新手工制作的 mixin 文件。(可能不会。)

在 Sass 中,您可以使用 Compass,而 Compass 保持自身更新,因此前缀情况将为您处理。 Bourbon 也不错。 这些项目中哪个“领先”将有一些来回。

在 Less 中,也有一些 mixin 库 在争夺最佳位置。 它们如今比过去看起来好多了。 尽管它们有营销支持图表,但我认为它们不如 Sass 版本健壮。 我过去了解到 Less 本身的语言无法在它之上构建同样健壮的库。 我们将在下一部分中讨论其中一些内容。

在这两种情况下,您都需要负责保持预处理器软件本身以及这些库的更新。 我也发现 Sass 通常更容易。 例如,Compass 更新将自动出现在 CodeKit 中,或者您使用易于更新的 Gem,而对于 Less mixin,您需要手动更新文件。

获胜者:勉强 Sass

语言能力:逻辑/循环

Less 能够执行“受保护的 mixin”。 这些 mixin 仅在某个条件为真时才生效。 也许您想根据模块中当前的文本颜色设置背景颜色。 如果文本颜色为“很浅”,则可能需要深色背景。 如果它为“很深”,则可能需要浅色背景。 因此,您有一个分成两部分的 mixin,这些 mixin 带有保护程序,以确保其中只有一个生效。

.set-bg-color (@text-color) when (lightness(@text-color) >= 50%) { 
  background: black;
}
.set-bg-color (@text-color) when (lightness(@text-color) < 50%) { 
  background: #ccc;
}

因此,当您使用它时,您将获得正确的背景

.box-1 {
  color: #BADA55;
  .set-bg-color(#BADA55);
}

这过于简单化,但您可能明白了。 您可以使用它完成一些花哨的事情。 Less 还可以执行自引用递归,其中 mixin 可以使用更新的值调用自身,从而创建一个循环。

.loop (@index) when (@index > 0) {
  .myclass {
    z-index: @index;
  }
  // Call itself
  .loopingClass(@index - 1);
}
// Stop loop
.loopingClass (0) {}

// Outputs stuff
.loopingClass (10);

但 Less 的逻辑/循环能力到此为止。 Sass 在语言中具有实际的逻辑和循环运算符。 if/then/else 语句、for 循环、while 循环和 each 循环。 没有技巧,只有适当的编程。 虽然受保护的 mixin 是一个非常酷的自然概念,但语言健壮性归功于 Sass。 这种语言健壮性是 Compass 成为可能的根本原因。

例如,Compass 有一个名为 background 的 mixin。 它非常健壮,您可以将几乎任何内容传递给它,它都会输出您需要的内容。 图像、渐变以及它们以逗号分隔的任何组合,您将获得您需要的内容(包括供应商前缀)。

此简洁易懂的代码

.bam {
  @include background(
    image-url("foo.png"),
    linear-gradient(top left, #333, #0c0),
    radial-gradient(#c00, #fff 100px)
  );
}

转变为这个怪物(不幸的是,我们需要它才能与尽可能好的浏览器支持一起使用)

.bam {
  background: url('/foo.png'), -webkit-gradient(linear, 0% 0%, 100% 100%, color-stop(0%, #333333), color-stop(100%, #00cc00)), -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 100, color-stop(0%, #cc0000), color-stop(100%, #ffffff));
  background: url('/foo.png'), -webkit-linear-gradient(top left, #333333, #00cc00), -webkit-radial-gradient(#cc0000, #ffffff 100px);
  background: url('/foo.png'), -moz-linear-gradient(top left, #333333, #00cc00), -moz-radial-gradient(#cc0000, #ffffff 100px);
  background: url('/foo.png'), -o-linear-gradient(top left, #333333, #00cc00), -o-radial-gradient(#cc0000, #ffffff 100px);
  background: url('/foo.png'), -ms-linear-gradient(top left, #333333, #00cc00), -ms-radial-gradient(#cc0000, #ffffff 100px);
  background: url('/foo.png'), linear-gradient(top left, #333333, #00cc00), radial-gradient(#cc0000, #ffffff 100px);
}

获胜者:Sass

网站友好度

Less 拥有一个更友好、更易于使用的网站Sass 文档 并不糟糕。 它很完整,您可以找到您需要的内容。 但在争夺前端人员的关注时,Less 占有优势。 我毫不怀疑,这在 Less 目前赢得人气竞赛中发挥了重要作用。

我知道 Sass 网站正在进行重大改革,并且许多优秀的人员正在努力完成它。 但在我看来,进展非常缓慢。

获胜者:LESS

@extend 概念

假设您声明一个具有少量样式的类。 然后您希望另一个类几乎做同样的事情,只是有一些额外的内容。 在 Less 中,您可能

.module-b {
   .module-a(); /* Copies everything from .module-a down here */
   border: 1px solid red;
}

这实质上是一个“包含”。 在两种语言中都是 mixin。 您也可以使用包含在 Sass 中执行此操作,但最好使用 @extend。 使用 @extend.module-a 中的样式不会仅仅在 .mobule-b 中复制(这可能被视为膨胀),而是 .module-a 的选择器在编译的 CSS 中被更改为 .module-a, .module-b(这更有效)。

.module-a {
   /* A bunch of stuff */
}
.module-b {
   /* Some unique styling */
   @extend .module-a;
}

编译为

.module-a, .module-b {
  /* A bunch of stuff */
}
.module-b {
  /* Some unique styling */
}

看到了吗? 它重写了选择器,效率更高。

在 Less 中,每个类也是一个 mixin,在编程方面会混淆水域,但在开始时更容易理解。

从 Less 1.4 开始,它也支持 extend。 您可以查看 升级到它时在 CodePen 上的一些示例。 它有点奇怪,因为它不会扩展嵌套在原始类中的选择器,除非您使用额外的 all 关键字。 对我来说,拥有两种方式似乎实际上更强大,但也担心幕后发生的事情。

Sass 还有扩展“占位符”类别的能力。 实质上是不可见的类别,格式为 %placeholder { }。 这对于使用内部命名很有用,这些命名在那里有意义,但在实际类名中却没有意义。

获胜者:Sass

变量处理

Less 使用 @,Sass 使用 $。 美元符号在 CSS 中没有内在含义,而 @ 符号有。 它用于声明 @keyframes@media 查询块。 您可能会认为这只是一个个人喜好问题,无关紧要,但我认为 Sass 占优势,因为它不会混淆现有的概念。

Sass 在变量作用域方面有一些奇怪之处。 如果您在“本地”覆盖“全局”变量,“全局”变量将采用本地值。 这感觉有点奇怪。

$color: black;           
.scoped { 
  $color: white;
  color: $color;        
}                        
.unscoped {     
  // LESS = black (global)
  // Sass = white (overwritten by local)
  color: $color;          
}

我听说它可能有用,但它不直观,特别是如果您编写 JavaScript。

获胜者:平局

使用媒体查询

我们大多数人开始使用 @media 查询的方式是在主样式表底部添加它们的块。 这可行,但会导致原始样式与响应式样式之间的脱节。 比如

.some-class {
   /* Default styling */
}

/* Hundreds of lines of CSS */

@media (max-width: 800px) {
  .some-class {
    /* Responsive styles */
  }
}

使用 Sass 或 Less,我们可以通过嵌套将这些样式整合在一起。

.some-class {
  /* Default styling */
  @media (max-width: 800px) {
    /* Responsive styles */
  }
}

您可以使用 Sass 获取更酷炫的功能。 有一个非常酷的“respond-to”技术(请查看 Chris EppsteinBen SchwarzJeff Croft 编写的代码)用于命名/使用断点。

=respond-to($name)

  @if $name == small-screen
    @media only screen and (min-width: 320px)
      @content

  @if $name == large-screen
    @media only screen and (min-width: 800px)
      @content

然后,您可以简洁、语义化地使用它们

.column
    width: 25%
    +respond-to(small-screen)
      width: 100%

嵌套媒体查询是一种很棒的工作方式。有传言说 Sass 3.3 将拥有更多功能来使它更加有用,包括一种在媒体查询中使用 extend 的方法,这在 Less 和 Sass 中目前都是不可能的。

获胜者:Sass

数学

在大多数情况下,数学是相似的,但单位的处理方式有一些奇怪之处。例如,Less 会假设你使用的第一个单位是你想要的单位,忽略其他的单位。

div {
   width: 100px + 2em; // == 102px (weird)
}

在 Sass 中,你会得到一个明确的错误:不兼容的单位:’em’ 和 ‘px’。我想,是否应该报错还是错误,这可能是有争议的,但我个人更倾向于报错。特别是当你处理的是变量而不是直接的单位时,更难追踪。

Sass 还允许你在“未知”单位上进行数学运算,这使得它在未来更具可扩展性,如果在他们能够更新之前出现了一些新的单位,Sass 可以处理。Less 则不行。还有一些更奇怪的差异,比如 Sass 如何处理同时具有单位的两个值的乘法,但这已经很深奥了,不值得一提。

获胜者:勉强 Sass

积极开发

我将更新这些数字,因为自这篇文章最初写作以来已经过去了足够长的时间。
05/16/12 01/12/13 06/25/13
LESS 上的开放问题数量 392 112 142
Sass 上的开放问题数量 84 83 110
LESS 上的待处理拉取请求 86 10 5
Sass 上的待处理拉取请求 3 7 11
LESS 上过去一个月内的提交数量 11 84 2
Sass 上过去一个月内的提交数量 35 14 14

这些数据都不能证明哪个项目更活跃,但查看这些统计数据还是很有趣的。据我所知,这两个项目的主导者都在他们的空闲时间里维护着这些语言,因为他们都有其他正在进行的大型新项目。

Less 最近一直很活跃,但现在 Sass 也变得更加活跃,因为有一位核心成员可以直接专注于它。

获胜者:平局

更多阅读