1. Web Design
  2. HTML/CSS
  3. CSS

Sass, LESS, Stylus - какой лучше: перепроцессор Shootout

Использование действительной мощности препроцессора CSS - это приключение.  Есть бесчисленные языки, синтаксисы и функции, готовые к использованию прямо сейчас.
Scroll to top

Russian (Pусский) translation by Liliya (you can also view the original English article)

 Использование действительной мощности препроцессора CSS - это приключение.  Есть бесчисленные языки, синтаксисы и функции, готовые к использованию прямо сейчас.

 В этой статье мы рассмотрим различные функции и преимущества использования трех разных препроцессоров: Sass, LESS и Stylus.


Вступление

 Препроцессоры создают CSS, который работает во всех браузерах.

 Препроцессоры CSS3 - это языки, написанные с единственной целью добавления классных, изобретательных функций в CSS без нарушения совместимости браузера.  Они делают это, компилируя код, который мы пишем, в обычный CSS, который можно использовать в любом браузере, вплоть до возвращения в каменный век.  Есть тысячи функций, которые препроцессоры приносят в таблицу, и в этой статье мы рассмотрим некоторые известные и некоторые не известные. Давайте начнем.


Синтаксих

 Наиболее важной частью написания кода в препроцессоре CSS является понимание синтаксиса.  К счастью для нас, синтаксис (или может быть) идентичен регулярному CSS для всех трех препроцессоров.

Sass & LESS

 Sass и LESS используют стандартный синтаксис CSS.  Это упрощает преобразование существующего файла CSS в препроцессор.  Sass использует расширение .scss, а LESS использует расширение .less.  Базовый файл Sass или LESS можно настроить следующим образом:

1
/* style.scss or style.less */
2
h1 {
3
  color: #0982C1;
4
}

 Как вы могли заметить, это просто обычный CSS, который отлично компилируется как в Sass, так и в LESS.

 Важно отметить, что Sass также имеет более старый синтаксис, который пропускает точки с запятой и фигурные скобки.  Хотя это все еще используют, оно устарело, и мы не будем использовать его в этом примере.  Синтаксис использует расширение .sass и выглядит так:

1
/* style.sass */
2
h1
3
  color: #0982c1

Stylus

 Синтаксис для Stylus более подробный.  Используя расширение файла .styl, Stylus принимает стандартный синтаксис CSS, но также принимает некоторые другие варианты, в которых скобки, двоеточия и полуколоны являются необязательными. Пример:

1
/* style.styl */
2
h1 {
3
  color: #0982C1;
4
}
5
6
/* omit brackets */
7
h1
8
  color: #0982C1;
9
10
/* omit colons and semi-colons */
11
h1
12
  color #0982C1

 Использование разных вариаций в одной таблице стилей также является допустимым, поэтому следующее будет компилироваться без ошибок.

1
h1 {
2
  color #0982c1
3
}
4
h2
5
  font-size: 1.2em

Переменные

 Переменные могут быть объявлены и использованы во всей таблице стилей.  Они могут иметь любое значение, которое является значением CSS (например, цветами, числами [включенными единицами] или текстом.), и на них можно ссылаться везде в нашей таблице стилей.

Sass

 Переменные Sass добавляются с символом $, а значение и имя разделяются точкой с запятой, как и свойство CSS.

1
$mainColor: #0982c1;
2
$siteWidth: 1024px;
3
$borderStyle: dotted;
4
5
body {
6
  color: $mainColor;
7
  border: 1px $borderStyle $mainColor;
8
  max-width: $siteWidth;
9
}

LESS

 LESS переменные точно такие же, как переменные Sass, за исключением того, что имена переменных добавляются символом @

1
@mainColor: #0982c1;
2
@siteWidth: 1024px;
3
@borderStyle: dotted;
4
5
body {
6
  color: @mainColor;
7
  border: 1px @borderStyle @mainColor;
8
  max-width: @siteWidth;
9
}

Stylus

 Переменные Stylus не требуют, чтобы что-то было добавлено к ним, хотя оно допускает символ $.  Как всегда, конечная точка с запятой не требуется, но знак равенства между значением и переменной есть.  Следует отметить, что Stylus (0.22.4) компилируется, если мы добавим символ @ к имени переменной, но не будем применять значение при ссылке.  Другими словами, не делайте этого.

1
mainColor = #0982c1
2
siteWidth = 1024px
3
$borderStyle = dotted
4
5
body
6
  color mainColor
7
  border 1px $borderStyle mainColor
8
  max-width siteWidth

 Скомпилированный CSS

 Каждый из вышеуказанных файлов будет скомпилирован с тем же CSS.  Вы можете использовать свое воображение, чтобы узнать, насколько полезны переменные.  Нам больше не нужно будет менять один цвет и повторить его двадцать раз, или мы хотим изменить ширину нашего сайта и вынуждены его искать, чтобы найти его.  Вот CSS после компиляции:

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

Nesting

 Если нам нужно ссылаться на несколько элементов с одним и тем же источником в нашем CSS, это может быть утомительно писать его снова и снова.

1
section { 
2
  margin: 10px;
3
}
4
section nav { 
5
  height: 25px;
6
}
7
section nav a { 
8
  color: #0982C1;
9
}
10
section nav a:hover {
11
  text-decoration: underline;
12
}

 Вместо этого, используя препроцессор, мы можем записать дочерние селекторы внутри скобок родителя.  Кроме того, символ & обозначает родительский селектор.

Sass, LESS, и Stylus

 Все три препроцессора имеют одинаковый синтаксис для селекторов вложенности.

1
section {
2
  margin: 10px;
3
4
  nav {
5
    height: 25px;
6
7
    a {
8
      color: #0982C1;
9
  
10
      &:hover {
11
        text-decoration: underline;
12
      }
13
    }
14
  }
15
}

Скомпилированный CSS

 Это скомпилированный CSS из приведенного выше кода.  Это точно так же, как то когда мы начали то что удобно!

1
section {
2
  margin: 10px;
3
}
4
section nav {
5
  height: 25px;
6
}
7
section nav a {
8
  color: #0982C1;
9
}
10
section nav a:hover {
11
  text-decoration: underline;
12
}

Mixins

 Mixins - это функции, которые позволяют повторно использовать свойства во всей нашей таблице стилей.  Вместо того, чтобы идти по всей нашей таблице стилей и менять свойство несколько раз, теперь мы можем просто изменить его внутри нашего mixin.  Это может быть действительно полезно для конкретного стиля элементов и префиксов поставщиков.  Когда mixins вызывается из селектора CSS, аргументы mixin распознаются, а стили внутри mixin применяются к селектору.

Sass

1
/* Sass mixin error with (optional) argument $borderWidth which defaults to 2px if not specified */
2
@mixin error($borderWidth: 2px) {
3
  border: $borderWidth solid #F00;
4
  color: #F00;
5
}
6
7
.generic-error {
8
  padding: 20px;
9
  margin: 4px;
10
  @include error(); /* Applies styles from mixin error */
11
}
12
.login-error {
13
  left: 12px;
14
  position: absolute;
15
  top: 20px;
16
  @include error(5px); /* Applies styles from mixin error with argument $borderWidth equal to 5px*/
17
}

LESS

1
/* LESS mixin error with (optional) argument @borderWidth which defaults to 2px if not specified */
2
.error(@borderWidth: 2px) {
3
  border: @borderWidth solid #F00;
4
  color: #F00;
5
}
6
7
.generic-error {
8
  padding: 20px;
9
  margin: 4px;
10
  .error(); /* Applies styles from mixin error */
11
}
12
.login-error {
13
  left: 12px;
14
  position: absolute;
15
  top: 20px;
16
  .error(5px); /* Applies styles from mixin error with argument @borderWidth equal to 5px */
17
}

Stylus

1
/* Stylus mixin error with (optional) argument borderWidth which defaults to 2px if not specified */
2
error(borderWidth= 2px) {
3
  border: borderWidth solid #F00;
4
  color: #F00;
5
}
6
7
.generic-error {
8
  padding: 20px;
9
  margin: 4px;
10
  error(); /* Applies styles from mixin error */
11
}
12
.login-error {
13
  left: 12px;
14
  position: absolute;
15
  top: 20px;
16
  error(5px); /* Applies styles from mixin error with argument borderWidth equal to 5px */
17
}

Скомпилированный CSS

 Все препроцессоры составляют один и тот же код:

1
.generic-error {
2
  padding: 20px;
3
  margin: 4px;
4
  border: 2px solid #f00;
5
  color: #f00;
6
}
7
.login-error {
8
  left: 12px;
9
  position: absolute;
10
  top: 20px;
11
  border: 5px solid #f00;
12
  color: #f00;
13
}

Наследственность

 При написании CSS старомодным способом мы могли бы использовать следующий код для одновременного применения одних и тех же стилей к нескольким элементам:

1
p,
2
ul,
3
ol {
4
  /* styles here */
5
}

 Это отлично работает, но если нам нужно дополнительно стилизовать элементы по отдельности, для каждого из них должен быть создан другой селектор, и он может быстро стать более беспорядочным и сложным в обслуживании.  Чтобы противостоять этому, можно использовать наследие.  Наследие - это способность других селекторов CSS наследовать свойства другого селектора.

Sass & Stylus

1
.block {
2
  margin: 10px 5px;
3
  padding: 2px;
4
}
5
6
p {
7
  @extend .block; /* Inherit styles from '.block' */
8
  border: 1px solid #EEE;
9
}
10
ul, ol {
11
  @extend .block; /* Inherit styles from '.block' */
12
  color: #333;
13
  text-transform: uppercase;
14
}

Скомпилированный CSS (Sass & Stylus)

1
.block, p, ul, ol {
2
  margin: 10px 5px;
3
  padding: 2px;
4
}
5
p {
6
  border: 1px solid #EEE;
7
}
8
ul, ol {
9
  color: #333;
10
  text-transform: uppercase;
11
}

LESS

 LESS действительно не  наследует стили Sass и Stylus. Вместо добавления нескольких селекторов к одному набору свойств он рассматривает наследование как mixin без аргументов и импортирует стили в свои собственные селекторы. Недостатком этого является то, что свойства повторяются в вашей скомпилированной таблице стилей. Вот как вы его настроили:

1
.block {
2
  margin: 10px 5px;
3
  padding: 2px;
4
}
5
6
p {
7
  .block; /* Inherit styles from '.block' */
8
  border: 1px solid #EEE;
9
}
10
ul, ol {
11
  .block; /* Inherit styles from '.block' */
12
  color: #333;
13
  text-transform: uppercase;
14
}

Скомпилированный CSS (LESS)

1
.block {
2
  margin: 10px 5px;
3
  padding: 2px;
4
}
5
p {
6
  margin: 10px 5px;
7
  padding: 2px;
8
  border: 1px solid #EEE;
9
}
10
ul,
11
ol {
12
  margin: 10px 5px;
13
  padding: 2px;
14
  color: #333;
15
  text-transform: uppercase;
16
}

 Как вы можете видеть, стили из .block были вставлены в селектора, которые мы хотели бы наследовать. Важно отметить, что приоритет может стать проблемой здесь, поэтому будьте осторожны.


Импортирующий

В сообществе CSS импорт CSS не одобряется, поскольку ему требуется несколько HTTP-запросов.  Однако импорт с препроцессором работает по-разному.  Если вы импортируете файл из любого из трех препроцессоров, он будет буквально включать импорт во время компиляции, создавая только один файл. Имейте в виду, что импортирование обычных файлов .css компилируется по умолчанию с помощью  @import «file.css»; code.  Кроме того, mixins и переменные могут быть импортированы и использованы в вашей основной таблице стилей.  Импорт делает создание отдельных файлов для организации очень хорошо.

Sass, LESS, и Stylus

1
/* file.{type} */
2
body {
3
  background: #EEE;
4
}
1
@import "reset.css";
2
@import "file.{type}";
3
4
p {
5
  background: #0982C1;
6
}

Скомпилированный CSS

1
@import "reset.css";
2
body {
3
  background: #EEE;
4
}
5
p {
6
  background: #0982C1;
7
}

Цветовые возможности

 Цветовые функции встроены в функции, которые преобразуют цвет при компиляции. Это может быть чрезвычайно полезно для создания градиентов, более темных цветов и многое другое.

Sass

1
lighten($color, 10%); /* returns a color 10% lighter than $color */
2
darken($color, 10%);  /* returns a color 10% darker than $color */
3
4
saturate($color, 10%);   /* returns a color 10% more saturated than $color */
5
desaturate($color, 10%); /* returns a color 10% less saturated than $color */
6
7
grayscale($color);  /* returns grayscale of $color */
8
complement($color); /* returns complement color of $color */
9
invert($color);     /* returns inverted color of $color */
10
11
mix($color1, $color2, 50%); /* mix $color1 with $color2 with a weight of 50% */

Это всего лишь короткий список доступных цветовых функций в Sass, полный список доступных цветовых функций Sass можно найти, прочитав документацию Sass.

Цветовые функции можно использовать в любом месте, где используется цвет. Вот пример:

1
$color: #0982C1;
2
3
h1 {
4
  background: $color;
5
  border: 3px solid darken($color, 50%);
6
}

LESS

1
lighten(@color, 10%); /* returns a color 10% lighter than @color */
2
darken(@color, 10%);  /* returns a color 10% darker than @color */
3
4
saturate(@color, 10%);   /* returns a color 10% more saturated than @color */
5
desaturate(@color, 10%); /* returns a color 10% less saturated than @color */
6
7
spin(@color, 10);  /* returns a color with a 10 degree larger in hue than @color */
8
spin(@color, -10); /* returns a color with a 10 degree smaller hue than @color */
9
10
mix(@color1, @color2); /* return a mix of @color1 and @color2 */

Список всех функций LESS можно найти, прочитав LESS Документацию.

Вот пример использования цветовой функции в LESS:

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

Stylus

1
lighten(color, 10%); /* returns a color 10% lighter than 'color' */
2
darken(color, 10%);  /* returns a color 10% darker than 'color' */
3
4
saturate(color, 10%);   /* returns a color 10% more saturated than 'color' */
5
desaturate(color, 10%); /* returns a color 10% less saturated than 'color' */

Полный список всех функций цвета Stylus можно найти, прочитав Документацию Stylus.

Вот пример использования цветовых функций Stylus:

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

Эксплуатация

Выполнение математики в CSS очень полезно и теперь вполне возможно.  Это просто, и вот как это сделать:

Sass, LESS, и Stylus

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

Практическое применение

Мы рассмотрели множество возможностей и новых возможностей, которые могут выполнять препроцессоры, но мы не затронули практику. Вот краткий список приложений реального мира, где использование препроцессора - спасатель.

Приставка поставщиков

Это одна из раздутых причин использовать препроцессор и по очень веской причине - это экономит массу времени и слез. Создание mixin для обработки префиксов поставщиков это легко и экономит много повторений и болезненного редактирования. Вот как это сделать:

Sass

1
@mixin border-radius($values) {
2
  -webkit-border-radius: $values;
3
     -moz-border-radius: $values;
4
          border-radius: $values;
5
}
6
7
div {
8
  @include border-radius(10px);
9
}

LESS

1
.border-radius(@values) {
2
  -webkit-border-radius: @values;
3
     -moz-border-radius: @values;
4
          border-radius: @values;
5
}
6
7
div {
8
  .border-radius(10px);
9
}

Stylus

1
border-radius(values) {
2
  -webkit-border-radius: values;
3
     -moz-border-radius: values;
4
          border-radius: values;
5
}
6
7
div {
8
  border-radius(10px);
9
}

Скомпилированный CSS

1
div {
2
  -webkit-border-radius: 10px;
3
     -moz-border-radius: 10px;
4
          border-radius: 10px;
5
}

3D-текст

Подделка 3D-текста с использованием нескольких текстовых теней - умная идея. Единственная проблема  в изменении цвета когда факт трудный и громоздкий. Используя mixins и цветовые функции, мы можем создавать 3D-текст и менять цвет «на лету»!

Sass

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

LESS

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

Stylus

1
text3d(color)
2
  color: color
3
  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
4
span
5
  font-size: 32pt
6
  text3d(#0982c1)

Я решил написать текстовые тени Stylus на одной строке, потому что я опустил фигурные скобки.

Скомпилированный CSS

1
span {
2
  font-size: 32pt;
3
  color: #0982c1;
4
  text-shadow: 1px 1px 0px #097bb7, 
5
               2px 2px 0px #0875ae, 
6
               3px 3px 0px #086fa4, 
7
               4px 4px 0px #07689a, 
8
               4px 4px 2px #000;
9
}

Конечный результат

Столбец

Использование числовых операций и переменных для столбцов - это идея, которую я придумал, когда я впервые играл с препроцессорами CSS. Объявив желаемую ширину в переменной, мы можем легко изменить ее в течении работы без какой-либо сложной математики. Вот как это делается:

Sass

1
$siteWidth: 1024px;
2
$gutterWidth: 20px;
3
$sidebarWidth: 300px;
4
5
body {
6
  margin: 0 auto;
7
  width: $siteWidth;
8
}
9
.content {
10
  float: left;
11
  width: $siteWidth - ($sidebarWidth+$gutterWidth);
12
}
13
.sidebar {
14
  float: left;
15
  margin-left: $gutterWidth;
16
  width: $sidebarWidth;
17
}

LESS

1
@siteWidth: 1024px;
2
@gutterWidth: 20px;
3
@sidebarWidth: 300px;
4
5
body {
6
  margin: 0 auto;
7
  width: @siteWidth;
8
}
9
.content {
10
  float: left;
11
  width: @siteWidth - (@sidebarWidth+@gutterWidth);
12
}
13
.sidebar {
14
  float: left;
15
  margin-left: @gutterWidth;
16
  width: @sidebarWidth;
17
}

Stylus

1
siteWidth = 1024px;
2
gutterWidth = 20px;
3
sidebarWidth = 300px;
4
5
body {
6
  margin: 0 auto;
7
  width: siteWidth;
8
}
9
.content {
10
  float: left;
11
  width: siteWidth - (sidebarWidth+gutterWidth);
12
}
13
.sidebar {
14
  float: left;
15
  margin-left: gutterWidth;
16
  width: sidebarWidth;
17
}

Скомпилированный CSS

1
body {
2
  margin: 0 auto;
3
  width: 1024px;
4
}
5
.content {
6
  float: left;
7
  width: 704px;
8
}
9
.sidebar {
10
  float: left;
11
  margin-left: 20px;
12
  width: 300px;
13
}

Известные причуды

Существует несколько приколов к использованию препроцессора CSS. Я собираюсь перечислить некоторые причуды, но если вам действительно интересно узнать все, я рекомендую вам изучать документацию или, еще лучше, просто начните использовать препроцессор в ежедневной кодировке.

Отчет об ошибках

Если вы написали CSS за какое-то приличное время, я уверен, что вы достигли точки, где вы где-то ошиблись, и просто не могли ее найти. Если вы похожи на меня, вы, вероятно, провели день, дергая свои волосы и комментируя различные вещи, чтобы найти ошибку.

Препроцессоры CSS сообщают об ошибках. Все просто. Если что-то не так с вашим кодом, он сообщает вам, где именно ошибка, и если вам повезло: почему. Ваш перевод будет отображаться на этом посте. Используйте левую сторону, чтобы ввести его.

Комментарии

При компиляции с препроцессором CSS любой комментарий с двойной косой чертой удаляется (например, // комментарий) и сохраняется любой комментарий косой черты (например, /* comment */). При этом используйте двойную косую черту для комментариев, которые вы хотите на не скомпилированной стороне, и слэш-звездочкой для комментариев, которые вы хотите видеть после компиляции.

 Просто примечание: если вы компилируете minified, все комментарии удаляются.


Заключение

Каждый препроцессор CSS, который мы рассмотрели (Sass, LESS и Stylus), имеет свой собственный уникальный способ выполнения той же задачи, предоставляя разработчикам возможность использовать полезные неподдерживаемые функции, сохраняя при этом совместимость браузера и чистоту кода.

Хотя это не требование для разработки, препроцессоры могут сэкономить много времени и иметь некоторые очень полезные функции.

Я призываю всех вас попробовать как можно больше препроцессоров, чтобы вы могли эффективно выбирать фаворита и знать, почему его предпочитают другие. Если вы еще не пытались использовать препроцессор для написания CSS, я настоятельно рекомендую вам попробовать.

У вас есть любимая функция препроцессора CSS, о которой я не упоминал? Есть ли что-то, что можно сделать иначе? Дайте нам знать в комментариях ниже!

Особая благодарность Karissa Smith, супер-талантливому другу, которая создала миниатюру для этой статьи.