Процесс написания CSS-алгоритмов

Перевод статьи «Writing CSS Algorithms» Лары Шенк

Примечание переводчика: Эта статья — первая из серии, посвящённой CSS-алгоритмам. Если вам не до конца понятно, о чём в статье идёт речь — это не страшно =) Дождитесь перевода других статей по этой теме или прочитайте их в оригинале в блоге Лары Шенк по ссылке. Очень советую доклад «Bridging the Design and Development Gap with CSS Algorithms» с WordCamp US 2018.

Чуть раньше на этой неделе я поделилась твитом на тему «артефактов после разработки CSS-алгоритмов». Я была рада быстрому отклику аудитории, но считаю, что подобный материал лучше размещать в виде статьи. Этот пост планировался как быстрое повторение того самого твита и я собиралась сразу перейти к написанию следующего выпуска Designgineering Chronicles (который будет забавным…), но, как это часто случается, короткая заметка переросла во что-то большее…


Теперь у нас есть ещё одно описание алгоритмов в CSS!!! Крупная победа! Эта статья не идеальна, но я описала основные моменты и планирую навести порядок чуть позже.

Немного истории и определений

Возвращаясь к теме… CSS-алгоритмов! Я так взволнована! Перед тем, как перейти непосредственно к описанию, позвольте мне ответить на один вопрос: Что же такое CSS-алгоритм?

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

CSS-алгоритмы — это чёткая декларация или набор деклараций, которые дают на выходе определённый стиль.
Я, во второй версии доклада Algorithms of CSS на WordCamp US, 2018.

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

В данный момент CSS-алгоритмы не являются чем-то особенным, но я думаю, у них есть потенциал. Я использую эту концепцию в разработке весь последний год и она отлично себя зарекомендовала как в моей основной работе, так и в сторонних проектах. Фраза «CSS-алгоритмы» полезна в различных ситуациях, включая, но не ограничиваясь, следующими:

  • полезная парадигма именования (именование в конечном итоге оказывается самым сложным),
  • знакомая концепция для тех, кто приходит в CSS из бэкенда (и кто может списать CSS со счетов, считая его жёстким, странным, раздражающим или нелогичным),
  • интригующая концепция для новичков в веб-разработке (привлекает больше внимания к CSS!),
  • указывает на то, что CSS — это искусственно созданный язык (по словам Рейчел Эндрю), с помощью которого мы можем делать кучу классных штук.

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

Как писать CSS-алгоритмы

В первой версии Algorithms of CSS вторая часть доклада была посвящена сравнению написания алгоритмов во время вайтбоард собеседований с написанием CSS-алгоритмов. Вот основные этапы разработки алгоритма, согласно интервью Cracking the Coding:

  1. Псевдокод
  2. Грубый набросок решения
  3. Тестирование алгоритма
  4. Оптимизация

Этот же план вполне подходит для написания CSS-алгоритмов. Дальше я пройду по каждому из пунктов на примере макета статьи для редизайна Cantaloupe (подробнее по ссылке). В этом дизайне есть нюанс: один из элементов не ведёт себя как все остальные. Он перескакивает в другое место и становится липким при определённом размере. Он будто специально придуман для элегантного, алгоритмичного решения на гридах.

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

Шаг 1: псевдокод из блоков

Я начинаю писать свой псевдокод в виде блоков, поскольку, в конечном итоге, все CSS-разработчики программируют блоки (ещё один твит, который хорошо бы превратить в статью). Вот какие блоки получились:

Я работала с макетами для мобильных, десктопов и больших десктопов. Для меня на данном этапе псевдокода было важно:

  1. Разобраться, какие блоки есть и что в них вложено
  2. Дать имена блокам
  3. Составить список того, что меняется между контрольными точками
  4. Определить, за что будет отвечать алгоритм, а за что — некий другой механизм

Важно постоянно помнить о принципе единой ответственности. Этот слайд из второй версии Algorithms of CSS отлично иллюстрирует этот принцип:

Извини, вилколожка…

И так, поскольку этот алгоритм предназначен для макета статьи, свойства типа background-color или font-size находятся за пределами нашей задачи.

Шаг 1.5: настройка рабочего окружения

Теперь, когда у нас есть чёткое понимание, что должен делать наш алгоритм — и, главное, что он не должен делать — пора приступить к непосредственному программированию блоков где-нибудь в безопасной среде, желательно отдельно от продуктовой кодовой базы. Эта среда должна быть быстрой и изолированной, но также должна быть производительной и предоставлять все необходимые инструменты, нужные вам для написания CSS. Например, SCSS миксины и переменные. Бред Фрост назвал это средой для фронтенд-воркшопов. И CodePen был создан специально для этого.

В нашей компании существует определённая архитектура для прототипирования в библиотеке компонентов, которая выглядит как плоский HTML-сайт, сгенерированный из комментариев в SCSS в помощью kss-node.

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

scratch-pad.scss

В нашей структуре SCSS-файлов есть файл scratch-pad.scss, который загружается только в библиотеку компонентов (она же мастерская). В самом начале этого файла есть комментарий // stylelint-disable, отключающий линтинг кода.

Основным содержимым файла являются стили для имён классов с .kss-*, которые помогают создать прототип — например, .kss-add-height, который добавляет 1000px высоты или ряд вложенных селекторов .kss-box, которые добавляют разные цвета фона и цвета границ.

// Sass (Scss)
.kss-box {
background-color: lemonchiffon;
border: 5px solid skyblue;
margin: $spacer-025;
  > .kss-box {
background-color: aliceblue;
border-color: hotpink;
    > .kss-box {
background-color: white;
border-color: peachpuff;
border-width: 1px;
}
}
}

Это очень грязный CSS, но мне плевать… для этого и нужен черновик!

Сюда также импортируется breakpoint-label.scss — маленький инструмент для создания переменных для контрольных точек:

Шаг 2: Грубый набросок решения

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

Создайте свои именованные блоки

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

Для раскладки нашего макета я использовала БЭМ для именования блоков. .a-article-grid содержит .a-article-grid__main и .a-article-grid__social и так далее. Затем я заполнила блоки текстом lorem ipsum, картинками-заглушками и повторила существующие паттерны там, где могла.

Вот как в итоге выглядел шаблон для макета статьи — с метками контрольных точек и некоторым горизонтальным переполнением, с которым я разберусь чуть позже:

Разберитесь с алгоритмом / напишите грязный CSS, который работает

Что это за «чётко определенная декларация или набор деклараций», которая решит нашу задачу? Какие из блоков требуют деклараций? Как свойства и значения меняются при достижении контрольных точек? Какие функции CSS вы будете использовать для решения задачи? Являются ли пользовательские свойства даром Божьим и Единственно Верным Решением?

Это программирование — вы подбираете набор инструкций для компьютера чтобы решить проблему, 💯.

(Заметка на полях: я работаю над этой темой уже больше года и, чем больше у меня опыта разработки, тем больше я признаю CSS как язык программирования, чёрт возьми! Я всё жду, что кто-то приведёт аргумент, который разубедит меня в этом. Но его всё нет. Я понимаю, что у кого-то это вызовет когнитивный диссонанс.)

Шаг 3: Тестирование алгоритма

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

В стране CSS-алгоритмов именно здесь вы моделируете движок рендеринга в своем мозгу, чтобы выяснить, что из написанного вами кода является частью алгоритма, а какие декларации не используются или должны быть переданы другому классу. Другими словами, уберите весь лишний жир из вашего алгоритма. Убедитесь, что у вас есть только те декларации, которые вам действительно нужны. Не осталось ли от черновика свойство вроде width: 100%, которое на самом деле не нужно?

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

Шаг 4: Оптимизация (или рефакторинг)

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

Слайд из первой версии Algorithms of CSS иллюстрирует процесс оптимизации:

Ваш грязный код постепенно превращается в красивый цветок!

На этапе оптимизации мы внедряем алгоритм в систему и пишем документацию к нему. Если весь код находится в файле scratch-pad.scss, подумайте, где он будет жить внутри продукта и напишите пояснение о том, как алгоритм должен работать, где он должен использоваться и где его использовать не стоит и как его следует поддерживать.

В нашей компании у нас есть специальная директория для алгоритмов внутри нашей архитектуры (пост в блоке и иллюстрация того, что получится на выходе). Комментарии к коду могут быть преобразованы в документацию к шаблону в библиотеке при помощи KSS. Мне нравится подчищать запись в библиотеке компонентов — особенно для алгоритмов раскладки — чтобы блоки явно иллюстрировали работу алгоритма.

Вот что получилось в итоге и ссылка на соответствующий SCSS-файл:

Запись для алгоритма шаблона статьи в библиотеке компонентов Cantaloupe.

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

// HTML
<div class="a-article-grid // kss-box">
<header class="a-article-grid__header // kss-box">
<div class="kss-height-sm"></div>
</header>
  <div class="a-article-grid__author // kss-box">
<div class="kss-height-sm"></div>
</div>
  <div class="a-article-grid__social // kss-box">
<div class="kss-height-sm"></div>
</div>
  <div class="a-article-grid__main // kss-box">
<div class="kss-height-lg"></div>
</div>
</div>

Финальный шаг — перенос алгоритма из библиотеки компонентов в продуктовую кодовую базу. И мы не должны недооценивать сложность этой задачи… Нам также стоит протестировать внедрённый алгоритм! Я до сих пор не сделала этого, но мой мозг переполнен различными перспективами.

Прощальные заметки для тех, кто интересуется CSS-алгоритмами

Я думаю, можно с уверенностью сказать, что в вашей архитектуре не предусмотрено отдельное место под алгоритмы. Так же вполне возможно, что если вы создадите такое место, то в процессе код-ревью к вам будут вопросы.

Хочу закончить парой предложений для тех, кто хотел бы написать CSS-алгоритмы, но не хочет называть их алгоритмами:

  1. Назовите их утилитами (они и так ими являются), но найдите способ пометить их как отличные или более сложные по сравнению с остальными утилитами, чтобы другие разработчики знали, что они требуют особого использования и обслуживания.
  2. Если это алгоритм создан для определенной части интерфейса, для которой уже есть файл, добавьте его в CSS этого файла и сгруппируйте деклорации под краткими комментариями с пометкой рассмотреть возможность абстрагирования в отдельный шаблон, не зависящий от UI.
  3. …у меня есть и другие мысли, но я добавлю их позже!

Что вы думаете в итоге? Пишите ли вы CSS подобным образом? Помогает ли это вам в работе?


Особая благодарность Natalia Ryzhova за редактуру! 📝

☕️ Купить чашку кофе переводчику