Frontender Magazine

Организация кода для CSS препроцессоров

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

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

Архитектура?

Одна из самых привлекательных возможностей CSS препроцессоров — подключение файлов. Это позволяет нам разделить код на несколько частей, которые впоследствии будут объединены препроцессором. Таким образом, можно работать с отдельными файлами и не беспокоиться о длинном списке HTTP запросов.

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

Итак, что же мы имеем? CSS с некоторой натяжкой можно назвать языком программирования, но мы не можем просто взять и скопировать свойственные ему архитектурные шаблоны. Как же нам тогда организовать различные части стилей проекты? Пакуйте чемоданы, впрыгивайте в ботинки и добро пожаловать в чудный новый мир, который я для вас открою (в смысле — просто расслабьтесь и позвольте мне сделать всю тяжелую исследовательскую работу за вас).

Создание архитектуры я всегда буду начинать с папки base. В ней будут файлы, которые не следует трогать (например, reset или стили библиотек).

Функциональное распределение

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

Достоинства

Недостатки

Вывод

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

Распределение «Катана»

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

Достоинства

Недостатки

Вывод

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

Шаблонное или страничное распределение

Если описывать отдельные файлы стилей для каждого шаблона или страницы, то легко найти какой-либо объект, особенно если он носит похожее название.

Вы можете заметить, что имена шаблонов выглядят очень похожими на имена шаблонов WordPress. Это сделано специально.

Достоинства

Недостатки

Вывод

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

В терминах веб-дизайна

Я слышал, как Крис Койер (Chris Coyier) описывал эту архитектуру в ролике «Рабочий процесс современного веб-дизайнера». Как и предполагает название, она предназначена для веб-дизайнеров. То есть комфортно ей воспользоваться смогут только люди знакомые как с дизайном, так и с профессиональным сленгом.

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

Достоинства

Недостатки

Вывод

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

Коктейль «Хьюго»

Чуть ранее в этом году Хьюго (Hugo Giraudel) описал свою Sass архитектуру. Оказалось, это смесь всего того, что мы обсуждали ранее.

Достоинства

Недостатки

Вывод

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

Дополнение от Игоря Зенича

Если вы используете БЭМ-методологию, то логичным будет использовать один из БЭМ-вариантов организации файловой системы:

Обратная БЭМ-иерархия

В раннем БЭМ, когда Яндекс ещё писал код руками, использовался другой вариант, который за неимением официального названия, я называю «обратная БЭМ-иерархия»: исходники раскладываются на папки по технологиям, а внутри них — разделяются на файлы по блокам:

scss/
blocks/
  input/                       # Директория блока input
    _input_theme_forest.scss   # Реализация модификатора theme в значении forest в технологии CSS
    _input__clear.scss         # Реализация элемента clear в технологии CSS
    _input.scss                # Блок input в технологии CSS
  button/                      # Директория блока button
    _button.scss
jade/
  _input.jade
  _button.jade
js/
  blocks/
    input.js                 # Блок input в технологии JavaScript
    button.js
xml/
xsl/
img/
  blocks/
    input/                     # Директория блока input
      input__clear.png       # Реализация элемента clear в технологии PNG
    button/                    # Директория блока button
      button.png

Достоинства

Недостатки

Прямая БЭМ-иерархия

Канонический Яндекс-вариант: разбирать вёрстку на блоки, складывая каждый в отдельную папку. В эту же папку добавляются все относящиеся к этому css-блоку изображения и js.

blocks/
  input/                     # Директория блока input
    _theme/                  # Директория опционального модификатора theme
      input_theme_forest.css # Реализация модификатора theme в значении forest в технологии CSS
    __clear/                 # Директория опционального элемента clear
      input__clear.css       # Реализация элемента clear в технологии CSS
      input__clear.png       # Реализация элемента clear в технологии PNG
    input.css                # Блок input в технологии CSS
    input.js                 # Блок input в технологии JavaScript
  button/                    # Директория блока button
    button.css
    button.js
    button.png

Достоинства

Недостатки

Вывод

Прямая БЭМ-иерархия подходит для проектов любого размера, если у вас есть опыт работы с полным стеком БЭМ-технологий, если же нет — о ней стоит задуматься на больших и очень больших проектах, группах проектов с общим дизайном. Обратная БЭМ-иерархия — удобна на маленьких и средних проектах, где не стоит проблема частого переноса/замены блоков.

Резюмируя

Все это — не более чем примеры различных архитектур. Я все еще нахожусь в поиске «той самой», идеальной, архитектуры, если, конечно, она существует. Но, даже если я её и найду, это в любом случае будет моим субъективным мнением.

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

Если вы заметили ошибку, вы всегда можете отредактировать статью, создать issue или просто написать об этом Антону Немцеву в skype ravencry.

Brian Rinaldi
Автор:
Brian Rinaldi
Сaйт:
http://remotesynthesis.com/
GitHub:
remotesynth
Twitter:
@remotesynth
Руслан Каймаков
Переводчик:
Руслан Каймаков
GitHub:
mrmoranxp
Twitter:
@mrmoranxp
Игорь Зенич
Дополнил:
Игорь Зенич
Сaйт:
http://delka.name/
GitHub:
delka
Twitter:
@delaz

Комментарии (9 комментариев, если быть точным)

Автар пользователя
langolf

Насчет прямой БЕМ-иерархии. Из недостатков стоит убрать про сборщики, потому что им без разницы как у вас устроен проект, если вы указываете правильный glob matching (не знаю как по-русски написать): "app/blocks/**/*.js"

Автар пользователя
SilentImp

@langolf я тоже так сначала подумал … но @delka считает это недостатком. Это его мнение и его дополнение.

Ну и, откровенно говоря, когда я впервые использовал эту иерархию, то и правда минут на 5-10 завис, размышляя, как именно мне надо изменить конфигурацию gulp, так что некое зерно истины в этом есть.

Автар пользователя
huston007

БЭМ особенно хорош, если используется честный сборщик зависимостей (webpack, browserify). Тогда, подключая блок (require('blocks/test/test')), можно быть увереным, что все его элементы (стили, картинки, элементы и модификаторы) подключатся внутри основного файла блока.

Автар пользователя
GarikFF

я использую в последнее время MCSS, больно мне нравится идея библиотеке компонентов, которые формирую из кусков различных проектов потихоньку. для меня это еще один шажок в сторону полноценного стека БЭМ-технологий, когда-нибудь дорасту, надеюсь. Сейчас структура моего базового шаблона выглядит примерно так - http://take.ms/FdaKz. Понемногу внедряю различные полезные технологии в базовый шаблон.

Автар пользователя
GarikFF

Прошу прощения за опечатки в прошлом сообщении, был длинный день( Ссылка как-то не в виде ссылки привязалась - http://take.ms/FdaKz

Автар пользователя
mrmlnc

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

P.S.: Прошу прощения за публикацию ссылки, если это запрещено правилами ресурса (не нашел).

Автар пользователя
harmerok

Про БЭМ лучше почитать на Яндексе. Достоинств куда больше, чем недостатков. Но недостатки присутствуют. И gulp отлично справляется со сборкой БЭМ, все дело в настройке

Автар пользователя
devvk

Может быть и gulpfile.js даже покажете? Очень мало примеров в сети именно при сборке с gulp, уже начал смотреть в сторону Webpack, заодно и архитектуру можно будет подправить.

Автар пользователя
harmerok

Вот кому интересно, сборка БЭМ с помощью gulp, вебинары events.yandex.ru/lib/talks/2890/ events.yandex.ru/lib/talks/2977/ Все хорошо объясняется. Там же ссылка на гит под видео. А это первый вебинар из цикла: events.yandex.ru/lib/talks/2857/