ホームページ  >  記事  >  ウェブフロントエンド  >  CSS プリプロセッサの比較 — Sass、Less、Stylus

CSS プリプロセッサの比較 — Sass、Less、Stylus

高洛峰
高洛峰オリジナル
2017-02-20 13:47:051568ブラウズ

CSS プリプロセッサの使用は非常に困難です。 CSS プリプロセッサにはさまざまな言語があり、構文や機能も異なります。

この記事では、sass、less、stylus という 3 つの異なる CSS プリプロセッサーの能力、機能、利点を紹介します。

はじめに

CSS プリプロセッサは、ブラウザの互換性の問題を考慮せずにいくつかの CSS 機能を記述するために使用される言語です。彼らはコードを通常の CSS にコンパイルし、もはや石器時代には留まりません。 CSS プリプロセッサには何千もの機能があり、この記事ではそれらを 1 つずつ紹介します。はじめましょう。

構文

CSS プリプロセッサを使用する前に最も重要なことは、構文を理解することです。幸いなことに、これら 3 つの CSS プリプロセッサの構文は CSS と似ています。

sassとless

sassとlessはどちらも標準のCSS構文を使用します。これは CSS プリプロセッサを使用して、プリプロセッサ コードを CSS コードに簡単に変換します。デフォルトでは、sass は .scss 拡張子を使用しますが、less は .less 拡張子を使用します。基本的な Sass と Less のセットアップは次のようになります: .scss扩展名,而less使用.less扩展名。sass和less基本设置可以像下面所示:

/* style.scss 或者 style.less */
h1 {
  color: #0982C1;
}

正如你所看到的,在sass和less样式中,这样的代码是在简单不过的了。

重要的一点是,sass也同时支持老的语法,就是不使用花括号和分号,而且文件使用.sass扩展名,他的语法类似于:

/* style.sass */
h1
  color: #0982c1

stylus

stylus的语法花样多一些,它使用.styl的扩展名,stylus也接受标准的CSS语法,但是他也接受不带花括号和分号的语法,如下所示:

/* style.styl */
h1 {
  color: #0982C1;
}

/* 省略花括号 */
h1
  color: #0982C1;

/* 省略花括号和分号 */
h1
  color #0982C1

你也可以在同一个样式单中使用不同的变量,例如下面的写法也不会报错:

h1 {
  color #0982c1
}
h2
  font-size: 1.2em

变量(Variables)

你可以在CSS预处理器中声明变量,并在整个样式表中使用。CSS预处理器支持任何变量(例如:颜色、数值(不管是否包括单位)、文本)。然后你可以在任意地方引用变量。

sass

sass声明变量必须是$开头,后面紧跟变量名和变量值,而且变量名和变量值需要使用冒号:隔开,就像CSS属性一样:

$mainColor: #0982c1;
$siteWidth: 1024px;
$borderStyle: dotted;
body {
  color: $mainColor;
  border: 1px $borderStyle $mainColor;
  max-width: $siteWidth;
}

less

less声明变量和sass声明变量一样,唯一区别是变量名前面使用是的@字符:

@mainColor: #0982c1;
@siteWidth: 1024px;
@borderStyle: dotted;
body {
  color: @mainColor;
  border: 1px @borderStyle @mainColor;
  max-width: @siteWidth;
}

stylus

stylus声明变量没有任何限定,你可以使用$符号开始,结尾的分号;可有可无,但变量名和变量值之间的等号=是需要的。有一点需要注意的是,如果我们使用@符号开头来声明(0.22.4)变量,stylus会进行编译,但其对应的值并不会赋值给变量。换句话说,在stylus中不要使用@符号开头声明变量。

mainColor = #0982c1
siteWidth = 1024px
$borderStyle = dotted
body
  color mainColor
  border 1px $borderStyle mainColor
  max-width siteWidth

转译出来的CSS

上面的代码都将转译成相同的CSS。你可以想像一下,变量的作用有多大。我们不需要为了修改一个颜色而输入许多次,也不需要为了修改一个宽度去到处寻找他。(我们只需要修改定义好的变量,修改一次就足够。下面是转译过来的CSS代码:

 body {
  color: #0982c1;
  border: 1px dotted #0982c1;
  max-width: 1024px;
}

嵌套(Nesting)

如果我们在CSS中多个元素有一个相同的父元素,那么写样式会变得很乏味,我们需要一遍一遍的在每个元素前写这个父元素。

section {
  margin: 10px;
}
section nav {
  height: 25px;
}
section nav a {
  color: #0982C1;
}
section nav a:hover {
  text-decoration: underline;
}

相反,使用CSS预处理器,我们可以在父元素的花括号{}写这些元素,同时可以使用&

section {
  margin: 10px;
  nav {
    height: 25px;
    a {
      color: #0982C1;
      &:hover {
        text-decoration: underline;
      }
    }
  }
}

ご覧のとおり、Sass と Less スタイルでは、このようなコードはこれ以上に単純です。

重要なことは、sass は古い構文もサポートしていることです。つまり、中括弧とセミコロンは使用されず、ファイルは .sass 拡張子を使用します。その構文は

section {
  margin: 10px;
}
section nav {
  height: 25px;
}
section nav a {
  color: #0982C1;
}
section nav a:hover {
  text-decoration: underline;
}
に似ています。

stylus

stylus には、.styl の拡張子が使用されますが、以下に示すように、中括弧やセミコロンを含まない構文も受け入れられます。同じスタイルシート内で異なる変数を使用することもできます。たとえば、次の記述方法ではエラーが報告されません。

 /* Sass定义了一个名叫error的mixin,这个error设置了一个参数“$borderWidth”,在没特别定义外,这个参数的值是默认值2px*/
@mixin error($borderWidth: 2px) {
  border: $borderWidth solid #F00;
  color: #F00;
}
.generic-error {
  padding: 20px;
  margin: 4px;
  @include error(); /* 调用error mixins */
}
.login-error {
  left: 12px;
  position: absolute;
  top: 20px;
  @include error(5px); /* 调用error mixins,并将参数$borderWidth的值指定为5px*/
}

変数

CSS プリプロセッサで変数を宣言し、使用されるスタイルシート全体でそれらを使用できます。 CSS プリプロセッサは、任意の変数 (色、数値 (単位の有無にかかわらず)、テキストなど) をサポートします。そうすれば、どこでも変数を参照できるようになります。

sass

sass 変数は $ で始まり、その後に変数名と変数値が続き、変数名と変数値はコロン : で区切る必要があります。 、CSS と同じです。属性は同じです:

 /* LESS 定义了一个名叫error的mixin,这个error设置了一个参数“$borderWidth”,在没特别定义外,这个参数的值是默认值2px */
.error(@borderWidth: 2px) {
  border: @borderWidth solid #F00;
  color: #F00;
}
.generic-error {
  padding: 20px;
  margin: 4px;
  .error(); /* 调用error mixins */
}
.login-error {
  left: 12px;
  position: absolute;
  top: 20px;
  .error(5px); /* 调用error mixins,并将参数$borderWidth的值指定为5px */
}

less

less。変数の宣言は、sass での変数の宣言と同じです。唯一の違いは、@ 文字が前に使用されることです。変数名:

 /* Stylus 定义了一个名叫error的mixin,这个error设置了一个参数“$borderWidth”,在没特别定义外,这个参数的值是默认值2px */
error(borderWidth= 2px) {
  border: borderWidth solid #F00;
  color: #F00;
}
.generic-error {
  padding: 20px;
  margin: 4px;
  error(); /* 调用error mixins */
}
.login-error {
  left: 12px;
  position: absolute;
  top: 20px;
  error(5px); /* 调用error mixins,并将参数$borderWidth的值指定为5px */
}

stylus

stylus は、制限なしで変数を宣言します。 $ 記号で始めることができ、末尾のセミコロン ; はオプションですが、等号は省略可能です。変数名と変数値の間の = が必要です。注意すべき点の 1 つは、@ シンボルを使用して (0.22.4) 変数を宣言すると、スタイラスはコンパイルされますが、対応する値が変数に割り当てられないことです。つまり、スタイラスで変数を宣言するために @ 記号を使用しないでください。
.generic-error {
  padding: 20px;
  margin: 4px;
  border: 2px solid #f00;
  color: #f00;
}
.login-error {
  left: 12px;
  position: absolute;
  top: 20px;
  border: 5px solid #f00;
  color: #f00;
}

CSSの翻訳

上記のコードは同じCSSに翻訳されます。変数がいかに強力であるか想像できるでしょう。色を変更するために何度も入力する必要はありませんし、幅を変更するためにあらゆる場所を検索する必要もありません。 (定義した変数を変更するだけでよく、一度変更すれば十分です。以下は翻訳された CSS コードです:
p,
ul,
ol {
  /* 样式写在这 */
}
    Nesting (入れ子)
  • CSS 内に同じ親要素を持つ複数の要素がある場合は、次のように記述します。スタイル設定が面倒になり、この親要素を各要素の前に何度も何度も記述する必要があります

    .block {
      margin: 10px 5px;
      padding: 2px;
    }
    p {
      @extend .block; /* 继承.block所有样式 */
      border: 1px solid #EEE;
    }
    ul, ol {
      @extend .block; /* 继承.block所有样式 */
      color: #333;
      text-transform: uppercase;
    }
    🎜 代わりに、CSS プリプロセッサを使用して、親要素の中括弧 {} を使用できます。これらの要素を記述するときは、& 表記を使用して親セレクターを参照できます。🎜🎜sass、less、stylus🎜 ネストされたセレクターの場合、3 つの CSS プリプロセッサーはすべて同じ構文を持ちます。 🎜翻訳されたCSS🎜🎜上記のプリプロセッサによって翻訳されたCSSコードは、最初に示したCSSコードと同じです! 🎜
    .block, p, ul, ol {
      margin: 10px 5px;
      padding: 2px;
    }
    p {
      border: 1px solid #EEE;
    }
    ul, ol {
      color: #333;
      text-transform: uppercase;
    }
    🎜Mixins🎜🎜Mixinsは、スタイルを作成するときに遭遇したはずです。特定の CSS スタイルは複数の要素で使用されることが多いため、CSS プリプロセッサでこれを複数回記述する必要があり、これを行うことで、CSS が使用する必要がある場所で定義した Mixin を直接呼び出すことができます。これらのスタイルは認識されたセレクターであり、変数は Mixins で定義することもできます。 CSS プリプロセッサは同じです🎜
     .block {
      margin: 10px 5px;
      padding: 2px;
    }
    p {
      .block; /* 继承 '.block'中的样式 */
      border: 1px solid #EEE;
    }
    ul, ol {
      .block; /*继承'.block' 中的样式*/
      color: #333;
      text-transform: uppercase;
    }
    🎜🎜 3 つのプリプロセッサの Mixins はすべてのプロセッサで異なります: 🎜🎜🎜🎜🎜🎜sass: sass の Mixins の定義は、less や stylus の定義とは異なります。 「@mixin」に続いてミックスインの名前を使用する場合、パラメータを定義してこのパラメータのデフォルト値を設定することもできますが、パラメータ名は「$」記号で始まり、パラメータ値と区切る必要があります。さらに、Sass で Mixins を呼び出す場合は、「@include」を使用し、その後に呼び出す Mixin の名前を指定する必要があります。
  • less:less中声明Mixins和CSS定义样式非常类似,可以将Mixins看成是一个选择器,当然Mixins也可以设置参数,并给参数设置默认值。不过设置参数的变量名是使用“@”开始,同样参数和默认参数值之间需要使用冒号(:)分开。

  • stylus:stylus和前两者也略有不同,他可以不使用任何符号,就是直接定义Mixins名,然后在定义参数和默认值之间用等号(=)来连接。

上面只是Mixins在三个CSS预处器的简单区别,详细的还可以进入他们的官网了解,或者对比一下上面的三段代码。

继承(Inheritance)

在多个元素应用相同的样式时,我们在CSS通常都是这样写:

p,
ul,
ol {
  /* 样式写在这 */
}

这样做非常的好,但往往我们需要给单独元素添加另外的样式,这个时候我们就需要把其中选择器单独出来写样式,这样一回来我们维护样式就相当的麻烦。为了应对这个问题,CSS预处理器可以从一个选择继承另一个选择器下的所有样式。

sass和stylus

.block {
  margin: 10px 5px;
  padding: 2px;
}
p {
  @extend .block; /* 继承.block所有样式 */
  border: 1px solid #EEE;
}
ul, ol {
  @extend .block; /* 继承.block所有样式 */
  color: #333;
  text-transform: uppercase;
}

转译出来的CSS

.block, p, ul, ol {
  margin: 10px 5px;
  padding: 2px;
}
p {
  border: 1px solid #EEE;
}
ul, ol {
  color: #333;
  text-transform: uppercase;
}

less

less支持的继承和sass与stylus不一样,他不是在选择器上继承,而是将Mixins中的样式嵌套到每个选择器里面。这种方法的缺点就是在每个选择器中会有重复的样式产生。

 .block {
  margin: 10px 5px;
  padding: 2px;
}
p {
  .block; /* 继承 '.block'中的样式 */
  border: 1px solid #EEE;
}
ul, ol {
  .block; /*继承'.block' 中的样式*/
  color: #333;
  text-transform: uppercase;
}

转译出来的CSS

.block {
  margin: 10px 5px;
  padding: 2px;
}
p {
  margin: 10px 5px;
  padding: 2px;
  /* 继承 '.block'中的样式 */
  border: 1px solid #EEE;
}
ul,
ol {
  margin: 10px 5px;
  padding: 2px;
  /*继承'.block' 中的样式*/
  color: #333;
  text-transform: uppercase;
}

正如所看到的,上面的代码.block的样式将会被插入到相应的你要继承的选择器中,但需要注意是的优先级的问题。

导入(import)

在CSS中,并不喜欢用@import来导入样式,因为这样的做法会增加HTTP的请求。但是在CSS预处理器中的导入@import规则和CSS的有所不同,它只是在语义上导入不同的文件,但最终结果是生成一个CSS文件。如果你是通过@import 'file.css'导入file.css样式文件,那效果跟普通CSS导入样式文件一样。注意:导入文件中定义了变量、混合等信息也将会被引入到主样式文件中,因此需要避免他们的相互冲突。

sass、less和stylus

/* file.{type} */
body {
  background: #EEE;
}
@import "reset.css";
@import "file.{type}";
p {
  background: #0982C1;
}

转译出来的CSS

@import "reset.css";
body {
  background: #EEE;
}
p {
  background: #0982C1;
}

颜色函数

颜色函数是CSS预处里器中内置的颜色函数功能,这些功能可以对颜色值进行处理,例如颜色的变亮、变暗、渐变颜色等处理十分的方便。

sass

lighten($color, 10%); /* 返回的颜色在$color基础上变亮10% */
darken($color, 10%);  /* 返回的颜色在$color基础上变暗10% */
saturate($color, 10%);   /* 返回的颜色在$color基础上饱和度增加10% */
desaturate($color, 10%); /* 返回的颜色在$color基础上饱和度减少10% */
grayscale($color);  /* 返回$color的灰度色*/
complement($color); /* returns complement color of $color */
invert($color);     /* 返回$color的反相色 */
mix($color1, $color2, 50%); /* mix $color1 with $color2 with a weight of 50% */

这只是sass中颜色函数的一个简单列表,更多详细的介绍你可以阅读 sass文档 。

颜色函数何以运用到任何一个元素上都是一个有颜色的CSS属性,下面是一个简单的例子:

$color: #0982C1;
h1 {
  background: $color;
  border: 3px solid darken($color, 50%);/*边框颜色在$color的基础上变暗50%*/
}

less

lighten(@color, 10%); /* 返回的颜色在@color基础上变亮10% */
darken(@color, 10%);  /* 返回的颜色在@color基础上变暗10%*/
saturate(@color, 10%);   /* 返回的颜色在@color基础上饱和度增加10% */
desaturate(@color, 10%); /* 返回的颜色在@color基础上饱和度降低10%*/
spin(@color, 10);  /* 返回的颜色在@color基础上色调增加10 */
spin(@color, -10); /* 返回的颜色在@color基础上色调减少10 */
mix(@color1, @color2); /* 返回的颜色是@color1和@color2两者的混合色 */

less的完整颜色函数功能,请阅读 less 文档。

下面是less中如何使用一个颜色函数的简单例子

@color: #0982C1;
h1 {
  background: @color;
  border: 3px solid darken(@color, 50%);
}

stylus

lighten(color, 10%); /* 返回的颜色在'color'基础上变亮10% */
darken(color, 10%);  /* 返回的颜色在'color'基础上变暗10% */
saturate(color, 10%);   /* 返回的颜色在'color'基础上饱和度增加10% */
desaturate(color, 10%); /* 返回的颜色在'color'基础上饱和度降低10% */

有关于stylus的颜色函数介绍,请阅读 stylus文档。

下面是stylus颜色函数的一个简单实例

color = #0982C1
h1
  background color
  border 3px solid darken(color, 50%)

运算符(Operations)

我们都向往在CSS做一些运算,但是无法实现。但是在CSS预处器中对样式做一些运算是一点问题都没有了,例如:

sass、less和stylus

body {
  margin: (14px/2);
  top: 50px + 100px;
  right: 100px - 50px;
  left: 10 * 10;
}

实际运用

我们介绍了CSS预处理器各方面的特性,但我们还没有实战过。下面是CSS预处理器应用的一些例子。

属性前缀

这是宣传CSS预处理器的原因之一,并且是一个很好的理由,这样可以节省大量的时间和汗水。创建一个minxin来处理浏览器的前缀问题是一个很简单的,并且能节省大量的重复工作和痛苦的代码编辑,我们来看一个例子。

sass

@mixin border-radius($values) {
  -webkit-border-radius: $values;
     -moz-border-radius: $values;
          border-radius: $values;
}
p {
  @include border-radius(10px);
}

less

.border-radius(@values) {
  -webkit-border-radius: @values;
     -moz-border-radius: @values;
          border-radius: @values;
}
p {
  .border-radius(10px);
}

stylus

border-radius(values) {
  -webkit-border-radius: values;
     -moz-border-radius: values;
          border-radius: values;
}
p {
  border-radius(10px);
}

转译出来的CSS

p {
  -webkit-border-radius: 10px;
     -moz-border-radius: 10px;
          border-radius: 10px;
}

浏览器前缀的问题,主要是针对于CSS3属性的运用,众所周知,CSS3的属性有并不是所有浏览器都支持属性的标准语法,因此在实际运用中时,不得不加上各浏览器的前缀来识别,这对于我们前端人员来说是多么苦逼的一件事情。虽然有prefix这样的js脚本帮我们解决,但对于怎么说也需要额外添加一个脚本文件,这对于追求完美的同学来说可能完法接受。
现在多了一种解决方案,就是使用CSS预处理器,如上面圆角的实现方法,这样减轻了我们很多工作量。如果你对这一部分实现方法感兴趣,不仿花时间阅读一下以下源码:

  • cssmixins :由 Matthew Wagerfield 整理的CSS3属性在三种预处理器中的Mixins的定义:less 、 sass (还有 SCSS )和 stylus

  • less-Prefixer

  • Custom User @mixins

3D文本

使用text-shadow的多重属性制作3D文本效果是一个很好的方法。唯一麻烦的问题就是修改文本阴影的颜色。如果我们使用Mixin和颜色函数的话,实现3D文本效果就非常的轻松了,我们来尝试一下。

sass

@mixin text3d($color) {
  color: $color;
  text-shadow: 1px 1px 0px darken($color, 5%),
               2px 2px 0px darken($color, 10%),
               3px 3px 0px darken($color, 15%),
               4px 4px 0px darken($color, 20%),
               4px 4px 2px #000;
}
h1 {
  font-size: 32pt;
  @include text3d(#0982c1);
}

less

.text3d(@color) {
  color: @color;
  text-shadow: 1px 1px 0px darken(@color, 5%),
               2px 2px 0px darken(@color, 10%),
               3px 3px 0px darken(@color, 15%),
               4px 4px 0px darken(@color, 20%),
               4px 4px 2px #000;
}
span {
  font-size: 32pt;
  .text3d(#0982c1);
}

stylus

text3d(color)
  color: color
  text-shadow: 1px 1px 0px darken(color, 5%), 2px 2px 0px darken(color, 10%), 3px 3px 0px darken(color, 15%), 4px 4px 0px darken(color, 20%), 4px 4px 2px #000
span
  font-size: 32pt
  text3d(#0982c1)

在stylus中text-shadow的样式写在一行,是因为stylus中省略了花括号{}和分号;
上面三种方法实现的效果都是一样的:

CSS预处理器的对比 — Sass、Less和Stylus

列(Columns)

我第一次接触CSS预处理器的时候,我就想着使用数字或者变量进行运算。使用数值和变量运算,可以很方便的实现适应屏幕大小的布局处理。只需要定义宽度的变量,我们就可以很方便的根据需求实现布局。下面的例子就是这么做的。

sass

$siteWidth: 1024px;
$gutterWidth: 20px;
$sidebarWidth: 300px;
body {
  margin: 0 auto;
  width: $siteWidth;
}
.content {
  float: left;
  width: $siteWidth - ($sidebarWidth+$gutterWidth);
}
.sidebar {
  float: left;
  margin-left: $gutterWidth;
  width: $sidebarWidth;
}

less

@siteWidth: 1024px;
@gutterWidth: 20px;
@sidebarWidth: 300px;
body {
  margin: 0 auto;
  width: @siteWidth;
}
.content {
  float: left;
  width: @siteWidth - (@sidebarWidth+@gutterWidth);
}
.sidebar {
  float: left;
  margin-left: @gutterWidth;
  width: @sidebarWidth;
}

stylus

siteWidth = 1024px;
gutterWidth = 20px;
sidebarWidth = 300px;
body {
  margin: 0 auto;
  width: siteWidth;
}
.content {
  float: left;
  width: siteWidth - (sidebarWidth+gutterWidth);
}
.sidebar {
  float: left;
  margin-left: gutterWidth;
  width: sidebarWidth;
}

转译出来的CSS

body {
  margin: 0 auto;
  width: 1024px;
}
.content {
  float: left;
  width: 704px;
}
.sidebar {
  float: left;
  margin-left: 20px;
  width: 300px;
}

错误报告

如果你经常使用CSS,你会发现很难找到CSS中出错的地方。也许你也会像我一样,花一下午的时间,发了疯的注解每行样式代码来寻找这个CSS错误。

CSS预处理器就轻松多了,他会给你报告错误。你可以阅读这篇文章,学习如何让CSS预处理器报告错误。

注释(Comments)

CSS预处理器支持/* */这样的多行注释方式(类似于CSS的注释方式),也支持//单行注释方式(类似于Javascript的注释方式)。

需要注意,如果你要压缩文件,你需要把所有注释都删除。

总结

三个预处理器我们都覆盖了(sass、less和stylus),都以他们独特的特性完成了相同的效果。这样让开发人员更好的选择适合自己的CSS预处理器,从而更好的维护自己的代码,提高开发效率。

虽然不是开发的要求,但CSS预处理器可以节省大量的时间,并且有一些非常有用的功能。

我鼓励大家尽可能的尝试使用CSS预处理器,这样就可以有效的让你选择一个你最喜欢的和知道他为什么是受人青睐的。如果你还没有尝试过使用CSS预处理器来写你的CSS样式,我强烈建议你尝试一下。
如果你有最喜欢的CSS预处理器的功能,我并没有提到的,希望在下面的评论中与我们分享。

译者手语: 整个翻译依照原文线路进行,并在翻译过程略加了个人对技术的理解。如果翻译有不对之处,还烦请同行朋友指点。谢谢!

更多CSS预处理器的对比 — Sass、Less和Stylus 相关文章请关注PHP中文网!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。