Немного размышлений на тему модульного css и проблемы поддержки кода +8


В чем заключается вопрос?


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

Казалось бы в век развития технологий, когда каждый день мы сталкиваемся с новыми и новыми фреймворками, препроцессорами, шаблонизаторами и прочими вещами проблем вообще возникать не должно. Умные разработчики придумали кучу крутых «фич» для удобства создания мощных и расширяемых сайтов. Но как эти инструменты правильно использовать в CSS? И в чем возникают трудности?

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

Суровая реальность


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

Вы конечно как опытный разработчик откроете его в каком-нибудь IDE, по типу Visual Studio Code и легким взмахом руки через функцию поиска и замены легко сможете найти и переписать любой класс.

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

Я думаю что много. Да и все что вы сделаете будет мягко говоря «бесполезно». Представьте себе ситуацию когда переделанный вами такой сайт передают другому разработчику или через некоторое время вам говорят внести еще туда новые правки.

SASS решит наши проблемы


Переварив всю эту информацию типичный веб-разработчик скажет что вот он выход из ситуации: использовать препроцессоры CSS. Там и модульность и комфорт и все.

Конечно! Но любой инструмент в руках не опытного программиста теряет всякий смысл. Порой открываешь стили сайта и вот, заветная папка c названием «sass». Ожидая чуда чаще всего ты получаешь только разочарования.

Разбивка стилей на отдельные файлы: header.sass, main.sass, animation.sass и т.д. Как же это «гениально». И не эффективно. Открывая очередной такой файл ты сталкиваешься с той же кучей строк стилей.

Какие же есть альтернативы?


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

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

  • Первый, как Вы уже поняли это правильное именование ваших классов.
  • Второй, это избавиться от вложенности стилей. Здесь нам поможет именно БЭМ методология. Ознакомившись с основами этой замечательной документации можно приступать к следующему.
  • SASS — без этого инструмента никак. Именно он залог модульности и мощности вашего проекта.
  • Сборка проекта. Я думаю Вы много слышали о современных сборщиках (информации по сборке проекта в интернете очень много). Здесь нам поможет Gulp.

Теперь вы готовы.

А теперь по сути


В современной интерпретации frontend`а можно найти не мало javascript фреймворков. Большинство из них разделяют сайт на меньшие части, компоненты. Я предлагаю вам сделать то же самое, когда вы думаете как написать стили. Каждая кнопка, элемент меню, красивая ссылка, картинка и даже обычный текст может быть компонентом.

image

Например, на этой форме входа на сайт мы можем выделить несколько компонентов:

  1. Саму форму входа
  2. Поля ввода input`ы
  3. Кнопку отправки
  4. Чекбокс

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

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

Внутренности компонента


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

Каждый компонент я предлагаю представить в виде трех сущностей: vars, maker и creater. Простым языком, это данные, создатель действий(методы управления этими данными) и создатель стилей. Теперь обо всем по порядку.

  • Данные или vars. Сюда входят: цвет текста кнопки, цвет заднего фона кнопки, padding, border-radius, размер шрифта и т.д. Все эти данные записаны в виде переменных или ассоциативного массива в отдельном файле.
  • Создатель действия или maker. Содержит в себе различные функции или миксины которые в качестве аргументов будут принимать данные и генерировать с них стили.
  • Создатель стилей или creater. Собственно здесь мы импортируем себе данные и методы и связываем их друг с другом так как нам нужно.

Ниже показано схематически взаимодействие всех трех сущностей.

image

Сложно все это вложить в голову? Рассмотрим пример создания базового компонента кнопка — «button». В качестве препроцессора будем использовать SCSS.

Как вы уже поняли в новой папке «button» создаем три файла: _vars.scss, _creater.scss, _maker.scss.

_vars.scss

$button_size:(
    sm:5px 20px,
    md:15px 20px
);
$button_color:(
   white:#ffffff
);
$button_back:(
    blue: #00e5e5
);
/* This is component config, it must be below other variables */
$button_config:(
    padding:$button_size,
    color:$button_color,
    background:$button_back
);

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

_creater.scss:

@import "vars";
@import "maker";

.button{
   @include InitialComponent($button_config);
}

Здесь мы импортируем данные и создателя действий. Потом через миксин InitialComponent который прописан в maker мы инициализируем все стили передавая переменную button_config. И вот магия. Все нужные классы созданы в соответствии с БЄМ неймингом.

Результатом выполнения будут стили:

.button_padding_sm {
  padding: 5px 20px; 
}

.button_padding_md {
  padding: 15px 20px;
 }

.button_color_white {
  color: #ffffff;
 }

.button_background_blue {
  background: #00e5e5;
 }

И в чем же здесь успех?


Преимущество такого подхода ощущаешь не сразу. Но по мере того как растет проект понимаешь все удобство такой методологии. Если нужно изменить цвет нескольких кнопок на разных страничках, не нужно искать классы в кучи стилей. Все что нужно — это открыть папку button и соответственно файл с данными и заменить там нужный стиль.

А если нужно создать новую кнопку?

Тогда все еще проще, записываем нужные стили в уже готовый массив или создаем новый и подключаем его там же в конфиг и классы созданы.

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

Такой подход был успешно опробован на множестве проектов и реализация данной методологии скоро будет в свободном доступе с документацией на русском и английском языке.




К сожалению, не доступен сервер mySQL