Pull to refresh

Почему стоит использовать препроцессоры

Reading time 5 min
Views 61K
У меня достаточно неплохой опыт в верстке — несколько лет.
За это время было многое — и табличная верстка, и собственные фреймворки, и IE6, и адаптивный дизайн, да что угодно — я всегда старался быть рядом с bleeding edge, как говорится.
Больше CSS-фреймворков (привет, бутстрап) и Emmet-а мне нравятся препроцессоры и я расскажу, почему. Возможно, покажется, что моя статья несколько устарела и сейчас все используют препроцессоры как само собой разумеющееся, но, увы, это не так. Недавно я встретил человека, который говорил о том, что ему быстрее писать CSS-код, нежели использовать препроцессоры. Мы долго спорили, на самом деле, ну очень долго, в итоге я решил выложить свои мысли здесь, в одном месте.

Less или Sass?


Ну, на самом деле, это дело каждого. Мне не нравился Sass из-за его медлительности — Less побыстрее выполнялся всегда, в итоге в один момент я решил перейти на Less, но через некоторое время оказалось, что мне не хватает его мощности! Увы, я так и не нашел, как реализовать банальный миксин уровня вот этого.
Но и медлительность Sass не устраивала, но именно в тот момент, когда я хотел обратно вернуться на Sass, но терзался сомнениями, мне посоветовали libsass, а т.к. я использую Grunt — мне было достаточно подключить только grunt-sass (и ничего больше, например, установка Ruby и гемов). Для меня выбор был ясен и с тех пор — только libsass. Мощность самого Sass и с скорость C — что еще нужно?
Stylus я пока не пробовал, как-нибудь потом.

Почему все-таки препроцессоры?


Я не скажу ничего нового, скорее всего, но я хочу показать, почему стоит использовать препроцессоры.

Переменные

Переменные — это нечто великолепное. Мне стали в упрек «препроцессоры были придуманы программистом, не верстальщиком», но как можно отказываться от переменных? Простой пример, который сильно облегчает жизнь — так как я в том числе еще и дизайнер, все цвета, настройки шрифтов и т.п. по проекту мне достаточно хранить в файле _variables.scss
_variables.scss
$white: rgb(255, 255, 255);
$lightgray: rgb(238, 238, 238);
$gray: rgb(153, 153, 153);
$asphalt: rgb(85, 85, 85);
$black: rgb(17, 17, 17);

$blue: rgb(85, 164, 242);
$lightblue: rgb(91, 192, 222);
$green: rgb(46, 204, 113);
$orange: rgb(230, 126, 34);
$magenta: rgb(228, 183, 240);
$red: rgb(231, 76, 60);

$bgBrand: linear-gradient(to left, rgba(26,214,253,1) 0%, rgba(85,164,242,0.72) 100%) no-repeat center center fixed;
$bgBlueLight: linear-gradient(rgb(26, 214, 253) 0%, rgb(29, 98, 240) 100%) no-repeat center center fixed;
$bgPinkViolet: linear-gradient(#EF4DB6 0%, #C643FC 100%) no-repeat center center fixed;
$bgWhiteGray: linear-gradient(#F7F7F7 0%, #D7D7D7 100%) no-repeat center center fixed;


Затем, когда мне это необходимо, я лишь указываю переменную, а не полное свойство. background: $bgBrand, а т.к. у меня бэкграунды используются во многих местах, мне проще отредактировать свойство переменной в одном месте, а не делать поиск по файлам или даже по одному файлу — все равно дольше, чем отредактировать в одном месте.

Вложенность

Что может быть лучше вложенности :hover, :after, :before, :nth-child в родительский элемент?
Простой, очень простой пример:
a {
  color: $blue;

  &:hover {
    color: darken($blue, 10%);
  }
}

В нем я использую переменные, внутреннюю функцию darken() и ту самую вложенность. Казалось бы, мелочь, но из таких мелочей и состоит верстка. В разы удобнее смотреть, что относится к конкретному блоку, следя за тем, что находится внутри него, а не за тем, что идет ниже. Да и писать каждый раз .my-super-class:hover все-таки бессмысленно. Сторонники БЭМ-подхода оценили бы такую возможность, но у них там свои инструменты.
Мне нужно было сделать таблицу, где отсутствовали заголовки (я использовал Bootstrap).
Пример
.table-information {
  tr {
    th {
      height: 0;
      padding: 0;
      border: 0;
    }

    td {
      border-top: 0;
      border-bottom: 1px solid $lightgray;
    }

    &:last-child {
      td {
        border-bottom: 0;
      }
    }
  }
}



Миксины, импорты и т.п.

Самый главный плюс препроцессоров — это в миксинах, экстендах и т.п. Это как функции в нормальном языке — можно использовать бесконечное количество раз, подключая когда необходимо. Лично я не так часто использую миксины, но т.к. я верстаю с подходом mobile first, мне очень сильно помогает один маленький миксин, о котором я уже упомянул:
@mixin responsive($media) {
  @if $media == sm {
    @media (min-width: 768px) { @content; }
  }
  @else if $media == md {
    @media (min-width: 992px) { @content; }
  }
  @else if $media == lg {
    @media (min-width: 1200px) { @content; }
  }
  @else if $media == xlg {
    @media (min-width: 1700px) { @content; }
  }
}

Используется достаточно просто, как @media-queries: @include responsive(sm) { background-color: red } и это вместе с вложенностью элементов.

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

«Я не могу разобраться в сгенерированном коде»

Когда я услышал этот аргумент, я не совсем понял, о чем шла речь. Затем мне разъяснили (человек работает на фрилансе) — к нему поступает проект с Sass или Less, но сгенерированный код ужасен, в нем нельзя разобраться. И это неправильный подход, потому что препроцессоры — для людей, для того, чтобы было удобно разрабатывать, держать архитектуру проекта в нормальном состоянии. Если человек пишет нормально, CSS на выходе получается оптимизированным, с этой стороны нет никакой разницы, на чем было написано — на CSS или Sass, Sass лишь помогает разработчику, а не браузеру. Для поддержки браузером есть Source maps, поддержка которых в нормальных инструментах типа Grunt есть из коробки.

Пример


Не так давно я разрабатывал один проект, в котором мне понадобились кнопки социальных сетей — не так много, штук 5, но именно тогда я задумался над тем, чтобы сделать библиотеку с использованием Sass, где хранилось бы огромное количество кнопок. Разумеется, делать это на CSS было бы неудобно, именно поэтому я решил использовать Sass. Тот человек, с которым мы спорили, в итоге отметил изящность решения.
Для того, чтобы сделать Brand Buttons, мне понадобилось совсем немного:

В итоге 3 файла, в которых я использовал небольшую, но мощную часть возможностей Sass: переменные, импорты, миксины, внутренние функции типа each/@for. Конечный CSS вышел на 687 строк.
Для того, чтобы добавить новую кнопку в этот проект, мне достаточно в _variables.scss вставить одну строчку brand: color и запустить grunt build, а не создавать новые классы вручную.

Препроцессоры — это история о том, как мелочи типа переменных способны сильно увеличить производительность. Препроцессоры, может быть, и написаны программистами, но при этом они не привносят ничего сложного, лишь улучшают жизнь: код остается читабельным, даже более того — его становится меньше, он становится более стройным. В этой статье я не рассказал о многих возможностях, но у меня было желание показать, почему я использую препроцессоры и какие плюсы они дают тем, кто все-таки решится.
Tags:
Hubs:
+24
Comments 44
Comments Comments 44

Articles