# Препроцессоры CSS

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

Но что если есть более масштабная задача, например, написать интернет-магазин? С большим количеством страниц, а также с большим количеством элементов, которые повторяются много где в одном и том же виде?

Мы можем разбить CSS файлы на несколько штук и импортировать в один базовый. Но это не решает множества проблем, которые могли бы быть решены. Это существенно не облегчает чтение кода. Также это не решает проблему дублирования кода. И не дает полноценно использовать подход модульности, когда отдельные логично выделенные куски кода (например стили для nav-bar) лежат отдельно, и их очень легко найти.

Чтобы решить все эти вопросы, на помощь приходят препроцессоры CSS.

**Препроцессор — это программа, которая берёт один тип данных и преобразует (компилирует) его в другой тип данных.**

Что это значит с точки зрения практики и применимо к CSS?

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

![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors.jpg)

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

Препроцессоров CSS на сегодняшний момент достаточно много. Самые часто используемые препроцессоры - это Sass, Less, Stylus, Compass.

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

**Так какой же выбрать?**

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

![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors1.jpg)

в Sass выглядел вот так:

![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors2.jpg)

Потом на выходе все преобразовывалось в CSS и все было круто.

Вроде красиво и еще даже как-то более-менее читаемо.

Но это породило несколько проблем.

1. При увеличении количества кода очень легко запутаться и сделать ошибку с пробелами. Можно минут 10 искать ошибку, где именно был неверно выставлен пробел.
2. Оказалось, что для многих людей отказ от знаков препинания не очень-то и облегчает чтение кода. Особенно когда этого кода много.
3. Для того, чтобы грамотно использовать Sass в таком виде, нужно было действительно подробно его изучать, что понижало порог входа в технологию.

Разработчики Sass решили эти проблемы с выпуском нового синтаксиса языка. Этот синтаксис и является на данный момент наиболее часто используемым на многих проектах. Он называется SCSS. Основной подход SCSS - синтаксис такой же, как в CSS, только с возможностями препроцессоров.

На примере SCSS и рассмотрим основные возможности препроцессоров и решим несколько возникающих в верстке проблем.

**Переменные**

**Проблема 1**. Мы больше не хотим копировать из макетов цвета и постоянно их вставлять где надо. Также мы хотим предусмотреть тот факт, что в один прекрасный момент цветовая палитра всего нашего сайта может поменяться, и нужно будет сменить все цвета в тех местах, где они были использованы.

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

Для того, чтобы объявить переменную в SCSS, нужно написать знак `$` и без пробела название переменной. Потом двоеточие, и присвоить нужное нам свойство.

![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors3.jpg)

Используем созданную переменную в коде:

![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors4.jpg)

Теперь каждый раз, когда нужно будет использовать зеленый цвет, мы можем использовать переменную `$text-color`.

В итоге после компиляции в CSS код будет выглядеть вот так:

![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors5.jpg)

При изменении значения переменной `$text-color` это новое значение подставится во всех местах, где мы ее использовали.

**Миксины**

**Проблема 2**. Есть определенные свойства, которые повторяются из раза в раз в элементах. Как бы их не писать везде, а что-то такое сделать, чтоб они все равно применялись, но не приходилось их постоянно прописывать?

Данную проблему можно решить такой вещью, как миксины.

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

Есть вот такие свойства для флексов, и они много где повторяются.

![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors6.jpg)

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

Для того, чтобы создать миксин, нужно так и написать - `@mixin` (это т.н директива для создания миксинов). После этой директивы написать название миксина, которое в дальнейшем будет использоваться в коде для вызова миксина.

И далее в фигурных скобках написать те свойства, которые мы будем хранить в миксине.

![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors7.jpg)

Миксин создан, и называется он `flex-center`.

Для того, чтобы теперь использовать его в коде, вернемся к нашему коду и заменим соответствующие свойства на `@include flex-center`. Директива `@include` используется для того, чтобы подключить миксин.

![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors8.jpg)

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

**Импорт файлов**

**Проблема 3**. Проект растет и увеличивается количество кода. Как бы так организовать код так, чтоб было легко и понятно ориентироваться в нем?

Для этого, в Sass мы можем создавать такую структуру папок и файлов, какая нам удобна.

Обычно принято делить проект на мелкие компоненты, и стили для этих компонентов хранить в отдельных файлах Scss. Также в отдельных файлах принято хранить миксины, переменные, функции и прочие вспомогательные вещи, которые предлагает Scss.

Например, вот так может выглядеть структура Scss небольшого лендинга.

![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors9.jpg)

Разберемся что тут происходит.

Есть основной файл - `styles.scss`.

С помощью директивы `@import` (это работает так же, как и в обычном CSS) - подгружаем сюда наши основные файлы.

![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors10.jpg)

Если с reset (это файл для кода - `reset.css`), переменными и миксинами, понятно, они лежат рядом с главным файлом и подгружаются сюда, то почему на 6 и 7 строке импортируются только 2 файла?

Взглянем на них подробнее.

![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors11.jpg)

Файл `components` содержит в себе тоже только импорты.

Логика такая - есть главный файл, в данном случае, он называется `components.scss`. И есть файлы отдельные для каждого компонента (в данном случае - `buttons.scss` - тут содержатся стили для кнопок, `header-menu.scss` - тут содержатся стили для меню сайта и др.). Мы импортируем файлы, касающиеся компонентов, в соответствующий файл, а потом уже этот файл импортируем в главный файл - `styles.scss`.

Получается такая себе древовидная структура, удобная в использовании.

Файлы, названия которых начинается с нижнего подчеркивания, называются фрагментами. Нижнее подчеркивание в имени Sass-файла говорит компилятору о том, что это только фрагмент, и он не должен самостоятельно компилироваться в отдельный CSS файл. Фрагменты Sass подключаются при помощи директивы `@import`.

Какие еще есть интересные штуки в препроцессорах, о которых стоит знать?

1.  **Вложенность**. Вот такой код

    ![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors16.jpg)

    с помощью препроцессора можно превратить в более читаемую древовидную структуру.

    ![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors17.jpg)
2.  **`@extend`** - данная директива позволяет одному классу наследовать свойства другого. На примере это выглядит так:

    ![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors12.jpg)

    Тут написано, что класс `.footer` будет иметь такие же свойства, как класс `.header`. И еще - `margin-right: 26px`.

    Итоговый css после компиляции будет выглядеть так:

    ![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors13.jpg)
3.  **Амперсанд.** Представим себе что у нас в проекте используется БЭМ. Вот такой код:

    ![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors14.jpg)

    с помощью знака `&` мы можем легко превратить в такой:

    ![препроцессоры](https://dan-it.gitlab.io/fe-book/advanced_frontend/lesson10_preprocessors/img/preprocessors15.jpg)

    Амперсанд говорит - примени предыдущее название селектора в этом названии. То есть в данном случае амперсанд будет при компиляции заменен на класс `.header`, и итоговый CSS будет выглядеть так, как на первой картинке. Но вариант записи на второй картинке намного более читаемый и структурированный. Амперсанд незаменим, если на проекте есть БЭМ.

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

**Пару советов по работе с SCSS**

1. Переменные чаще всего используются для цветов и для каких-то значений в пикселях. Но в целом любое свойство CSS, которое будет использоваться в многих местах и может в перспективе быть изменено, можно хранить в переменных.
2. Для переменных и миксинов обычно выделяются отдельные файлы с названием `variables` и `mixins`.
3. Лучше всего называть переменные и миксины по смыслу их значений и цели. Например, если это цвет текста, то лучше назвать переменную, как `$text-color`, а не `$color-black`.
4. Не нужно увлекаться со вложенностью. Несмотря на то, что препроцессоры превращают ее в более читаемый вид, они не облегчают поддержку. Чем больше вложенностей на проекте - тем он в последствии будет более тяжело поддерживаемым.

**Полезные ссылки**

[Документация Sass на русском языке](https://sass-scss.ru/documentation/)

[Препроцессор Sass. Полное руководство и зачем он нужен](https://medium.com/@stasonmars/%D0%BF%D1%80%D0%B5%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80-sass-%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B5-%D1%80%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE-%D0%B8-%D0%B7%D0%B0%D1%87%D0%B5%D0%BC-%D0%BE%D0%BD-%D0%BD%D1%83%D0%B6%D0%B5%D0%BD-20fb638e29e3)

[Руководство по написанию разумного, поддерживаемого и масштабируемого Sass.](https://sass-guidelin.es/ru/)
