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

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

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

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

Архитектура

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

Подробнее эта директива описана в документации.

Существует много подходов к архитектуре проектов, у каждого есть свои плюсы и минусы. Самое главное здесь — следовать выбранной архитектуре. В нашей статье мы будем следовать паттерну 7-1, предложенному Хьюго Жираделем. В этом паттерне применяются 7 каталогов и один файл main.scss на выходе:

  • base/ — включает глобальные стили, такие как сброс стилей, типография, цвета и т.д.
  • components/ — содержит отдельные компоненты с отдельным файлом .scss для каждого из них.
  • layout/ — содержит стили для основных компонентов макета, таких как хедер, футер, навигация и т.д.
  • pages/ — содержит стили, специфичные для отдельных страниц, если это необходимо.
  • themes/ — стили для разных тем.
  • utils/ — глобальные миксины, функции, вспомогательные селекторы и т.д.
  • vendors/ — стили, миксины и прочее от третьих сторон
  • main.scss — выходной файл, в котором объединяются все стили.

В каждом каталоге должен быть файл .scss, объединяющий все остальные файлы из этого каталога - он может называться _module.scss или _glob.scss, например. И на каждый из этих файлов должна быть ссылка в основном файле main.scss:

// main.scss
@import 'base/module';
@import 'components/module';
@import 'layout/module';
@import 'pages/module';
@import 'themes/module';
@import 'utils/module';
@import 'vendors/module';

Стилизация компонентов с SCSS

Все основные архитектуры CSS, включая SMACSS, OOCSS и Atomic Design акцентируют важность модульности и подхода к пользовательскому интерфейсу как к набору компонентов.

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

Как было сказано, мы можем использовать Sass для организации стилей, как общих так и компонентных. Для демонстрации этого создадим простой компонент — кнопку, не используя при этом какую-либо архитектурную или организационную систему:

.button {
    display: inline-block;
    padding: 8px 16px;
    font-size: 12px;
    font-weight: bold;
    color: #d9534f;
    text-transform: uppercase;
    background-color: transparent;
    border: 1px solid #d9534f;
    transition: all 0.3s ease-in-out;

    &:hover {
        background-color: #d9534f;
        color: #fcfcfc;
    }
}

button

Кнопка должна выглядеть именно так, как мы хотим, но в представленном коде есть некоторые проблемы:

  • Слишком много магических чисел, таких как 8px, 12px, 16px, #d9534f, #fcfcfc, 0.3s и т.д.
  • Негибкая тема — нет простого способа создания аналогичной кнопки с другим цветом.
  • Явный селектор — если изменится содержимое .button это отразится на всех экземплярах .button в проекте.
  • Потенциальная несвязанность — нет гарантий, что стиль кнопки будет соответствовать стилю проекта.

Попробуем смягчить эти проблемы с помощью SCSS.

Организация стилей компонентов

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

  • Variables (переменные) —- для соотнесения значений, специфичных для компонента с общим стилем сайта и во избежание использования магических чисел.
  • Mixins (миксины) —- для динамически-генерируемых вариаций компонента (не обязательны, если несколько вариаций уже есть).
  • Structure (структура) —- структура или макет компонента, все остальное типа цветов сюда не относится.
  • Relationships (отношения) —- любые CSS, которые отвечают за отношения с другими компонентами.
  • Themes (темы) —- CSS, не относящиеся к макету: фоны, цвета, тени и т.д.
  • Exported Selectors (экспортируемые селекторы) —- используемые классы и селекторы CSS

Нашу кнопку из предыдущего примера имеет смысл переделать в соответствии с этой методикой.

Переменные

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

  1. Что это такое?
  2. Как это соотносится со стилем всего проекта?

Исходя из этого, мы извлечем из кода нашей кнопки следующие переменные:

$button-padding: 0.5rem 1rem;
$font-size: 12px;             // 1 factor below base 16px in modular type scale
$button-bgcolor: #d9534f;     // the primary brand color
$button-border-width: 1px;    // border width for all form inputs
$button-color-hover: #fcfcfc; // the light/white brand color

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

// Pseudocode, for this example
$button-padding: 0.5rem 1rem;
$font-size: type-scale(-1);                // utility function
$button-bgcolor: $color-primary;           // from 'base/_colors.scss'
$button-border-width: $input-border-width; // from 'component/_input.scss'
$button-color-hover: $color-light;         // from 'base/_colors.scss'

Миксины

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

Основная структура нашей кнопки-образца должна оставаться стабильной, но цвет ее можно изменять:

@mixin scotch-button-theme($color, $color-text-hover: $color-light) {
    color: $color;
    border-color: $color;
    background-color: transparent;

    &:hover {
        color: $color-text-hover;
        background-color: $color;
    }
}

Теперь мы с легкостью можем создавать различные цветовые варианты нашей кнопки, просто @include scotch-button-theme(blue).

Структура

Структура компонентов состоит из правил, которые не могут темизироваться, то есть относящихся к макету компонента. Гибким паттерном для этого является создание %placeholder, расширяемого единственным селектором. Если со временем вы захотите удалить компонент из стилей, просто удалите селектор и это не повлечет каких-либо побочных эффектов для остальных компонентов. Также эта методика позволяет определять нужный селектор лишь один раз, упрощая последствия в случае его переименования.

Вот структура нашего компонента-кнопки. Заметьте, насколько меньше в ней стало темизируемых правил:

%button {
    display: inline-block;
    padding: $button-padding;
    font-size: $button-font-size;
    font-weight: bold;
    text-transform: uppercase;
    border-width: $button-border-width;
    border-style: solid;
}

Экспортируемые селекторы

Эти стили можно выделить в отдельный класс, который я назвал .scotch-button. Он создается путем подключения базовой структуры и темы:

.scotch-button {
    @extend %button;
    @include scotch-button-theme($color-primary);

    &.secondary {
        @include scotch-button-theme($color-secondary);
    }
}

Вы отметили вариант с .scotch-button.secondary? Единственное различие между двумя вариантами это цвет. Еще одной выгодой от экспортируемых селекторов является их отделение от общих стилевых деклараций в плейсхолдер и это дает возможность легко встраивать их в любых системах именования. Например, в BEM &.secondary станет &--secondary.

Заключение

Правильная архитектура и организация стилей имеет решающее значение при разработке стилей — у нас получаются модульные, гибкие и масштабируемые стили компоненты. Вместо того, чтобы спрашивать себя “Куда мне поместить этот стиль?” и “Что означает это магическое число?”, лучше с самого начала спланировать и определить архитектуру и организацию стилей.

Следующая часть в нашей серии эстетичный Sass — цвета и палитры.