С первых строк кода, каждый человек начинает понимать важность правильной его организации и оптимизации рабочего пространства в целом.
Не важно о какой отрасли говорить конкретно, но важно понимать что везде где есть код – должны быть правила его создания и хранения.
На первых парах конечно может показаться, что придерживание определенных правил и порядков лишь отнимает время, что на практике выглядит совсем иначе. Квинтэссенция любых принципов написания кода заключается в том, что мы не пишем его один раз и навсегда – мы постоянно возвращаемся к нему с целью редактирования и модификации.
Этот процесс может превратиться в настоящую проблемму, если там царит хаос и непредсказуемость. Эта проблемма может усугубиться если этот хаос был создан не тобой, а человеком с которым нет возможности установить контакт. Именно для устранения таких ситуаций и существуют методологии.
Если говорить о css, то с уверенностью можно сказать — каждый из нас пользуется определенной методологией, осознанно или нет. Даже если человек не использует определенные правила и стандарты, то у него все равно есть свои привычки и постоянно повторяющиеся приемы.
Способы написания кода не обязательно должны быть общепринятыми и стандартизированными, обязательным должно быть другое – они должны быть предсказуемыми.
Список методологий на которые стоит обратить внимание не так велик:
-BEM,
-Smacss,
-OOCSS,
-MCSS,
-Atomic CSS
Atomic CSS – пожалуй является самой необычной и даже в какой то мере пугающей методологией, что к счастью не мешает ей быть очень понятной и предсказуемой.
Что бы обосновать свой выбор я должен откатить немного назад.
Почти Атомарный CSS
Были времена, когда корневой каталог подавляющего количества проектов на стадии создания интерфейса выглядел как три файла и две папки:
>fonts
>img
-index.html
-style.css
-script.js
Но эта простота обманчиво может показаться удобной, на самом деле как в минимум в двух из трех этих файлов творилось нечто ужасное.
Меня всегда раздражало две вещи – беспорядок и отсутствие стиля. В Css под классификацию беспорядка попадает масса различных нюансов, но больше всех меня не устраивало постоянное повторение одних и тех же правил и свойст для разных селекторов.
Первым решением этой проблеммы были следующие действия:
- создание файла с названием “re-use.css”,
- создание в этом файле инструкций, которые в теории могут понадобиться больше чем одному селектору,
- дописывание разных селекторов к одной и той же инструкции.
Имело это следующий вид:
...
.class { display: inline-block;}
.class { text-transform: uppercase;}
...
и в последствии принимало следующий:
...
.menu-link, .primary-button, .form-button, .footer-link, .social-link
{ display: inline-block;}
...
Конечно это решение было очень не удобным и к счастью временным. Недолго помучавшись с бесконечным переключенем между файлами, и поиском нужного места в них, я пришел к выводу что гораздо удобнее будет создать отдельные классы, отвечающие за одну инструкцию каждый:
…
.inline-block { display: inline-block;}
.block {display: block;}
.uppercase {text-transform: uppercase;}
В html файлах теги с большим количеством классов выглядели странновато, но это решение мне показалось вполне приемлемым:
<aside class=”sidebar fixed left top w-30 h-100 main-fill”></aside>
С одного взгляда достаточно что бы понять что это боковая колонка, с фиксированным позиционированием, с левой стороны экрана, занимающая 30% его ширины и 100% высоты, залитая главным цветом.
Все что касалось числовых значений, в основном это были внешние и внутренние отступы, я записывал в стандартном формате. Для этого каждому тегу, или группе тегов я добавлял отдельный класс идущий первым, на примере выше это класс “slider”.
Это был почти атомарный и почти удобный подход. Удобным ему мешало стать несколько недостатков, важнейшим из которых были следующие ситуации:
- при создании большого количества похожих тегов, например элементов списка, приходилось много копировать классы и это выглядело громоздко,
- при внесении любых правок, приходилось удалять и дописывать классы для каждого элемента отдельно,
- оставалось много неиспользуемых классов которые было сложно отлавливать.
И тогда на помощь пришли две вещи, которые помогли решить все проблеммы – это препроцессор и шаблонизатор.
С их помощью я модифицировал свою методологию и сделал верстку приятной и удобной.
Почти идеальный Css
Начну с препроцессора. Его выбор не принципиален, изначально я пользовался Sass, потом SCSS и в итоге перешел на Stylus, потому что уважаю минимализм, а Stylus был максимально минималистичен (в примерах ниже будет использован scss, по причине его популярности).
Итак, первое что я сделал это написал дополнительные классы которые с помощью директивы @extend выглядели как настоящие атомы:
.flex {
display: flex;
flex-wrap: no-wrap;
}
.flex-jc-center {
@extend .flex;
justify-content: center;
}
.flex-ai-center {
@extend .flex;
align-items: center;
}
Мне понравилась идея, а директива @extend вызвала сходство с ядром атома, рядом с которым были дополнительные инструкции.
Я решил что идею надо развивать и создал отдельный файл для организмов. Организмами я называл классы включающие в себя несколько директив @extend:
.header {
@extend .fixed;
@extend .w-100;
@extend .main-fill;
@extend .left;
@extend .top;
@extend .flex-ai-center;
@extend .z-top;
}
Создав небольшой “зоопарк” из различных организмов, я решил что то сделать с классами которые требуют числовых значений для отступов и размеров.
С этим снова помогли справиться возможности препроцессора, с помощью которых я написал некоторые функции и добавил переменные.
Сначала я детально изучил графические проекты которые мне достаются от дизайнеров и выявил ряд закономерностей:
- количество цветов для каждого проекта,
- количество шрифтов,
- количество разных размеров для текста и заголовков,
- повторяющиеся отступы (для секций, кнопок и тд.)
Первым делом нужно было написать функции и миксины для создания нужных классов:
//создаем функцию для пересчета px в em
@function em($pixels, $context: $browser-context) {
@return #{$pixels/$context}em
};
// создаем массив с размерами для текста
$text-size: (
l: 18,
m: 16,
s: 14,
xs: 12
);
@mixin emFonts($list, $n) {
//создаем миксин $list – массив, n – Число на которое требуется уменьшить шрифт для адаптивности.
@each $status, $size in $list {
//используя интерполяцию - создаем класс для каждого из размеров
&-#{$status} {
font-size: em($size - $n);
//присваиваем нужные числовые значения тексту
}
}
}
Теперь мы можем вызвать эту комбинацию из миксина и функции в любом удобном для нас месте:
.txt {
@include emFonts($text-size, 0)
}
И на выходе получим 4 класса для текста разных размеров:
.txt-m { font-size: 1.125em; }
.txt-s { font-size: 1em; }
Аналогичным образом создаются и вызываются функции для размеров заголовков, цветов текста и заливки, шрифтов и тд.
То есть работа над каждым проектом начинается с заполнения значений для переменных, а сами классы и функции кочуют из одного проекта в другой.
Шаблонизатор.
Я думаю многие из вас пользуются шаблонизаторами, и скорее всего – это Pug(который раньше назывался Jade).
Для атомарной верстки он необходим благодаря 3 вещам:
- миксины
- переменные
- циклы
Pug полностью избавляет нас от громоздкого из за микроклассов HTML кода, так как мы можем превратить следующий код:
…
<ul class=”menu__list flex-ai-center w-100 relative “>
<li class=”menu__item m-color m-font txt-s inline-block bold-border”>first</li>
<li class=”menu__item m-color m-font txt-s inline-block bold-border”>second</li>
<li class=”menu__item m-color m-font txt-s inline-block bold-border”>third</li>
</ul>
в удобный для редактирования:
-let menuItemClasses = ‘menu__item m-color m-font txt-s inline-block bold-border’
//создав переменную содержащую все класы мы можем менять их в одном месте
ul
li(class=`${menuItemCLasses}`) frst
li(class=`${menuItemCLasses}`) second
li(class=`${menuItemCLasses}`) third
...
</ul>
или в другом варианте, с помощью цикла:
let menuItems = [‘first’, ‘second’, ‘third’]
ul
-for(let item of menuItems) {
li(class=”menu__item m-color m-font txt-s inline-block bold-border”)
-}
Это не менее удобно, ведь строка с нужными классами не повторяется больше одного раза.
Последнее уязвимое место данной методологии заключалось в том что в коде оставалось большое количество неиспользуемых классов. Но эта казалось бы серьезная проблемма легко решилась добавлением в сборщик проекта плагинов удаляющих ненужные классы.
Заключение
В заключении хотелось бы сказать следующее:
перед тем как начать пользоваться “почти атомарной методологией”, я долгое время использовал smacss и потом BEM. В итоге от bem я оставил лишь названия для классов требующих описания отступов и размеров, и иерархию хранения файлов и папок. Набор готовых классов и функций, я подключаю к проекту в качестве библиотеки.
Важный момент который хотелось бы отметить – это удобство верстки станиц и отдельных ее секций целиком. Благодаря микроклассам достаточно легко создать “скелет” страницы или секции в шаблонизаторе и только потом перейти к написанию для нее стилей.