Ситуация получилась следующая.
Компания переделывала сайт и сказала, что необходимо сделать его максимально гибким, чтобы, во-первых, можно было дизайн обновлять просто, во-вторых, сделать ещё несколько подразделов на базе готового функционала (вроде как SaaS фишка для заказчиков).
(Часть 1)

Прилетает первый дизайн (пришлось сильно изменить, т.к. nda, все дела, но что-то похожее).

Что тут у нас интересное.
Есть секции, которые разбиты по принципу:

·         Заголовок
·         Контент

Заголовок всегда одинаковый.
Значит выносим заголовок и текст контента в типографию (Components/Typography, либо любое другое название, абы вам нравилось и семантически объясняло, что это).

Дальше куча всяких секций. На таком мелком рисунке не видно, но многие секции имеют одинаковые отступы, а у 50% ещё и высота одинаковая.

Получается нужна ещё сущность, которая задаёт одинаковые правила для секций, например, единые отступы и единую минимальную высоту. Я назвал этот тип сущностей containers. В частности, для секции BasicSection.

Получается, у нас уже есть Typography, в которой есть заголовок и Containers, где есть BasicSection.

Замечательно, создаём такие секции.

Наверное, немного сумбурно в стилях, да?
Сейчас поясню.

Из предыдущей статьи мы помним, что у нас есть ритм в дизайне. Поэтому мы взяли 10px, как основу для всех-всех отступов на сайте.

Почему 10px?
Потому что все отступы кратны 10ке.
Отступы сбоку страницы – 90px, отступы между кнопочками, лейблами, формой – 10px либо 20px и тд.

Далее именно от 10px ($offset-basic) будут считаться все отступы. Сам же $offset-basic использоваться нигде не должен, т. к. является исключительно точкой отсчёта и не относится к семантике сайта.

Двигаемся дальше. Высота секции, по нашему мнению, равна высоте экрана (100vh). Вроде бы всё логично, но, когда я добавляю на сайт хедер, появляется полоса прокрутки. Связанно это с тем, что у нас блок 100vh + 150px (например, столько) высота header. Для того, чтобы не терять контекст, который мы только что обнаружили, предлагаю записать эту логику в переменную высоты секции.

Итого:

Почему это важно.
Я часто видел записи в компоненте header, height: 150px, а в высоте секции height: 95vh.
Вроде бы точно, но куда делись 5vh? Почему 150px = 5vh? И прочие вопросы.

Где? Ну вот например откройте сайт Forbes (https://www.forbes.com).
Похожая логика магических чисел: 3%, 31.8%

Ну да, я понимаю, что, скорее всего, оставшийся блок занимает 97% и 68.2%, или не оставшийся блок, а два оставшихся блока. Хмм. Ладно, да, я не понимаю.

Думаю, на этом с формулой высоты мы закончили, едем дальше.

Попалась такая замечательная секция (белая), для которой есть и мобильный дизайн, и планшетный дизайн. Что с этим то делать?

Media queries.
Здесь отступы в каждой секции изменены. В мобильной версии практически нет фона, в планшетной его немного, а в десктопной он заполняет, насколько я понимаю, всё свободное пространство.

Здесь, следуя логике первой статьи, мы идём к дизайнеру и уточняем, точно ли всё правильно поняли, чтобы не догадки строить, а точно узнать, что нужно.

Отлично, что мы делаем с полученной информацией?
Первым на ум приходит простая вставка значений в каждой media query.

Надеюсь, вас не сильно удивят переменные ширины экранов…

Получилось, по-моему, читаемо.

Глобальные переменные из html подставляются в компонент. В будущем их можно переиспользовать в других компонентах, секциях (с другой высотой).

Смотрим на секции дальше.

Чётко выделяется отступ между элементами и отступ от заголовка.
Следовательно, для label нам необходимо добавить отступ справа, равный одному $offset-basic, а заголовку снизу – равный двум $offset-basic.

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

Результат:

Я добавлю media queries, потому как у нас всё-таки вёрстка под разные устройства …

Если честно, уже слабо читаемо.

Да, если разнести по разным файлам, будет лучше.

Например, в main.scss объявлять глобальные переменные и использовать их в media queries внутри компонентов.









Media queries вынести в mixins.scss как что-то типа @include mobile, @include tablet.

Вот так

Получаем следующее:

В принципе неплохо. Ладно. Не неплохо. Терпимо. Но это будет для каждого элемента, каждого тега. Выглядит как очень странное дублирование кода…

Здесь мне очень хочется побеседовать о читаемости.
Давайте сравним 3 варианта кода, которые я часто встречаю, и тот, что был выше.

#1
#1
#2
#2
#3
#3

Смотрим, вникаем.
Первый вариант (#1) – классическое копирование из фигмы или ещё откуда.

Второй вариант (#2) – классическое унифицирование переменных. Когда у нас цвета идут как $red, $black либо $alpha, $beta, а отступы просто умножаются (в лучшем случае, бывает просто новые переменные создаются и существует по 1000 переменных в проекте одновременно).

Третий способ (#3) вроде как читаем, но, честно говоря, тоже не сильно хороший. Есть какая-то идея в имени переменной ($[property]-[element]-[media-query]), но выглядит уж больно избыточно.

Ииии, «silver bullet», который я предлагаю.
Вариант записи, к которому мы так долго шли!
Выносим переменные, которые мы меняем из каждого компонента в один глобальный – html тег.

Как?
Добавляем css-variables.

Теперь наши классы выглядят вот так.
Все классы. Все секции, все заголовки, кнопочи, лейбочки – всё в проекте.

Потому как они будут создаваться по подобию.

Как же выглядят media queries?

А вот так.
Код стал разделён по файлам. Теперь в компонентах содержится только информация о типе отступа (его семантическое значение), а в файле variables.scss – информация о том, как отличаются отступы в зависимости от устройства.

Для продолжения статьи я сделал шаблон на базе create-react-app, чтобы вы могли самостоятельно следить за развитием событий, тыкая в код и пробуя своими руками, удобно вам или нет (https://github.com/DrBoria/cra-scss).

Я добавил некоторые переменные, например, для типографии.
Для понимания размера шрифта предлагаю ознакомиться с данной статьёй.

Дальше задачка посложнее прилетела – правки по дизайну.
Ну, как сказать правки. Дизайн полностью изменился.

Некоторые секции возможно только переписать с нуля, некоторые похожи, но их нужно полностью модифицировать.

Было








Стало

Главная практически не изменилась – только отступ между секциями (от меню до заголовка) и цвета.

Зато сервисы полностью другие. Единственное, что похоже – структура карточек. И то не сильно.

Было
















Стало

И думаете, это проблема? На изменение ушло минут 20 максимум.

Было

(зачёркнутое вынес в отдельный компонент)


















Стало

1) Меняем две колонки на сложную систему колонок, как в grid template areas.

2) Т.к. у нас теперь два типа карточек – картинки и текст. Вынес их в отдельный компонент

3) Для отступов между карточками добавляем grid-gap, равный отступу между элементами.

4) Всё, можно кофе заварить. Даже структуру в jsx не пришлось переписывать (я вынес для красоты карточки в отдельный компонент, но там всё равно меньше 20 строк было…)

Выше я обещал, что дизайна будет три.

Подлетела белая версия…

Как мы видим – логика совершенно разная.
Слева (на чёрном) у нас есть, назовём это, overlay. Справа (на белом) у нас сразу идёт текст и фото.
Сами фото идут в разном порядке, разной структуре.
По сути это одна и та же страница, но для разной темы.

Как расставлять фото – думаю нет особого смысла показывать – гридом это делать.

Основные вопросы – как добавить разную логику в зависимости от темы? И как организовать цвета?

В данном проекте я разделил цвета на базовые и связанные с темой.
Базовые – это выделение (розовое, фиолетовое), цвет текста в выделенных элементах (всегда белый) и disabled – для элементов формы.
Все остальные цвета вошли в темы.

Дальше, чтобы понять, какая тема в данный момент включена, я добавил css переменную –theme с указанием темы (‘dark’, ‘light’ соответственно), которую ловил в компонентах, где оно было необходимо, с помощью следующей логики.

В отличие от подхода с data-attribute, данный способ позволяет переопределять тему не только в root компоненте, но и во вложенных.
Собственно переопределение происходит с помощью ThemeProvider.

Получив доступ к текущей теме уже непосредственно в jsx компоненте, я добавлял логику overlay (подложки под текстом в тёмной теме) и расстановки карточек (2 или 3 ряда).

Как резюме, хочу обрисовать плюсы и минусы данного подхода.

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

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

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

Ещё раз хочется напомнить, что разработчик – это человек, который переводит мысли заказчика на язык машины.

Пишите понятный код, надеюсь, поддержка теперь станет для вас удовольствием!

Комментарии (9)


  1. notiv-nt
    18.12.2021 11:51
    -5

    Конечно прекрасно, но такой контент лучше в видео формате воспринимать


    1. Xeldos
      18.12.2021 11:55
      +7

      Нет.


    1. FFF
      18.12.2021 18:30
      +5

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


  1. IgosYee
    18.12.2021 14:59
    +1

    Ох, все отступы кратные 10ке. Тут недавно клиент пришел со своим дизайном, вроде ок. Но все отступы плавают 17рх, 9рх и тд, логики в них никакой нет. "Дизайнер" ставил их на глаз. На просьбу подправить или что мы будем использовать одинаковые в похожих элементах, клиент сказал "нетЪ, хочу перфект пиксель"...


    1. mikita_du Автор
      18.12.2021 15:13

      Тут дело такое.

      У меня в одном дизайне были разные отступы в дизайне вокруг одного элемента.

      Сверху 9px, справа 7px, снизу 8px.

      Я на своё усмотрение сделал единое. На дизайн было похоже - все были рады)


      1. stainlouder
        19.12.2021 00:20

        Согласен, довольно небольшой процент дизайнеров, которые относятся к своей работе с пониманием. Как раз используют ритмику, палитры, иногда даже золотое сечение, причем со знанием дела. Многие, к сожалению, считают, что достаточно просто "природного" чутья и понимания "что с чем слепить чтобы было круто". А еще находятся заказчики, которые до абсурда отставают каждый пиксель подобных дизайн кодов.

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


  1. pkashtanov
    19.12.2021 00:20

    Искал гайды по сабжу, похоже нашел. Спасибо вам.


  1. skeevy
    20.12.2021 02:02

    В первой части переизобрели бутстрап 4, во второй части в css уже видны проблемы отсутствия следования методологии какой либо

    Для новичков материал суперский, но автору посоветовал бы пересмотреть подход к организации css, начиная с нейминга и раз вы используете scss - использовать миксины чаще и placeholder-классы. Даже "улучшенный" код можно ещё сократить, используя все выше, а спагетти из card-* упаковать в 3-5 строчек, используя map


  1. n1ck_dev
    20.12.2021 12:39

    Зачем же так все усложнять ..