Атомарный CSS — порядок и чистота

в 18:57, , рубрики: css

Атомарный CSS — порядок и чистота - 1

С первых строк кода, каждый человек начинает понимать важность правильной его организации и оптимизации рабочего пространства в целом.

Не важно о какой отрасли говорить конкретно, но важно понимать что везде где есть код – должны быть правила его создания и хранения.
На первых парах конечно может показаться, что придерживание определенных правил и порядков лишь отнимает время, что на практике выглядит совсем иначе. Квинтэссенция любых принципов написания кода заключается в том, что мы не пишем его один раз и навсегда – мы постоянно возвращаемся к нему с целью редактирования и модификации.
Этот процесс может превратиться в настоящую проблемму, если там царит хаос и непредсказуемость. Эта проблемма может усугубиться если этот хаос был создан не тобой, а человеком с которым нет возможности установить контакт. Именно для устранения таких ситуаций и существуют методологии.
Если говорить о 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 я оставил лишь названия для классов требующих описания отступов и размеров, и иерархию хранения файлов и папок. Набор готовых классов и функций, я подключаю к проекту в качестве библиотеки.
Важный момент который хотелось бы отметить – это удобство верстки станиц и отдельных ее секций целиком. Благодаря микроклассам достаточно легко создать “скелет” страницы или секции в шаблонизаторе и только потом перейти к написанию для нее стилей.

Автор: Юра

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js