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

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

Соблазн логического CSS

Мое мертвое маленькое сердце затрепетало, когда я узнал об эволюции к логическому CSS. Я поэкспериментировал с новыми свойствами и, в конце концов, написал собственный пост на эту тему. В этот пост Логический CSS — это будущее Интернета и I18n я включил фрагменты кода, чтобы помочь другим начать работу с новыми концепциями уже сегодня.

Однако, когда я сам начал использовать эти фрагменты кода, везде применяя @supports запросы для физических запасных вариантов CSS, я очень быстро усвоил три вещи.

1. Этот подход быстро раздувал стили и становился трудным для чтения и работы.

2. Переключение на нескольких разработчиков с разным пониманием CSS ни для кого не было гладким или положительным.

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

Я провел годы, работая со стеками, построенными вокруг React и Styled Components, где название игры — компонентизация, чтобы уменьшить дублирование и централизовать логику. Как я мог бы использовать эти основы для устранения основных недостатков современных попыток использовать логический CSS?

Миксины со стилизованными компонентами

Если вы также имеете опыт работы с SASS (или LESS), концепция примесей, вероятно, не нова. По сути, миксин — это блок стилей, который можно рассматривать как компонент в том смысле, что:

  • Набор стилей пишется как отдельный блок
  • Эти стили можно импортировать и использовать много раз.
  • Набор может поддерживать свойства для динамического изменения значений на протяжении всего жизненного цикла.

Хотя Styled Components не имеет ничего готового для миксинов, как таковых, мы можем использовать его для достижения именно того, что нам нужно.

Во-первых, давайте посмотрим на набор стилей, которые я повторял снова и снова.

const SomeComponent = styled.div`
  inline-size: 100%;
  max-inline-size: 50rem;

  @supports not (inline-size: 100%) {
    max-width. 50rem;
    width: 100%;
  }
`;

Как вы можете себе представить, написание логического CSS сначала с различными @supports запросами может быстро привести к беспорядку.

const SomeComponent = styled.div`
  border-block-start: 1px solid orange;
  block-size: 15rem;
  inline-size: 100%;
  margin-inline: auto;
  max-inline-size: 50rem;
  @supports not (inline-size: 100%) {
    max-width. 50rem;
    width: 100%;
  }
  @supports not (border-block-start: 1px solid orange) {
    border-top: 1px solid orange;
  }
  @supports not (block-size: 15rem) {
    height: 15rem;
  }
  @supports not (margin-inline: auto) {
    margin: 0 auto;
  }
`;

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

Обмани меня один раз, позор вам. Обмануть меня кучу раз за несколько недель и, не знаю, уволить?

Но в конце концов связи начали загораться, и идея окончательно сформировалась.

Примеси

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

Mixins.js

import { css } from 'styled-components´;
export const Size = ({ height, maxHeight, maxWidth, width }) => css`
  block-size: ${height};
  inline-size: ${width};
  max-block-size: ${maxHeight};
  max-inline-size: ${maxWidth};
  @supports not (block-size: ${height}) {
    height: ${height};
    maxHeight: ${maxHeight};
  }
  @supports not (inline-size: ${width}) {
    max-width. ${maxWidth};
    width: ${width};
  }
`;

Component.js

import { Size } from 'Mixins';
const SomeComponent = styled.div`
  ${Size({ height: '15rem', maxWidth: '50rem', width: '100%' });
`;

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

Миксины

Давайте разберем, что происходит с нашим миксином Size.

Во-первых, мы импортируем вспомогательную функцию css из Styled Components. Обернув наши стили в это, мы можем гарантировать, что они получат префиксы потенциальных поставщиков и другую магию Styled Components.

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

Наконец, в нашем файле компонента мы импортируем функцию и вызываем ее из нашего стиля div. Мы передаем только те размеры, которые нам нужны, с именами свойств, которые мы уже знаем (и которые также короче и удобнее для пар ключ/значение), и в результате имеем более четкий набор стили со всеми желаемыми функциями.

Оглядываясь назад

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

1. С помощью примеси у нас теперь есть один вызов функции вместо нескольких строк стилей, написанных ранее. Читабельность кода несколько субъективна, но для меня это большая победа.1

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

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

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

Но мы еще не закончили. Мы можем пойти дальше.

Далее.

Стили с проверкой типа

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

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

Моя цель — иметь возможность смотреть на InVision, видеть padding из 16px и иметь возможность писать свои стили, используя только эту часть информации, без необходимости перекрестной проверки и ссылок на несколько файлов.

Итак, давайте снова взглянем на миксин Size, но теперь с проверкой типов.

interface SizeProps {
  height?: string;
  maxHeight?: string;
  maxWidth?: string;
  width?: string;
};
export const Size = ({ height, maxHeight, maxWidth, width }: SizeProps) => css` ... `;

Теперь, когда я буду использовать этот миксин позже, я могу взять числовое значение в пикселях, преобразовать его в rem единиц (используя вспомогательную функцию, которая принимает число и возвращает строку rem) и иметь свои логические стили CSS написано не более чем тем, что дал мне дизайн.

import { pxToRem } from 'utils/theme';
const SomeComponent = styled.div`
  ${Size({ width: pxToRem(500) });
`;

Бонус: не стесняйтесь расширить проверку типов, чтобы исключить любые строки, содержащие px. Или примите только те относительные единицы, которые вы хотите поддерживать.

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

Все. . Миксины.

Если вы знакомы с логическим CSS, вы знаете, что помимо block-size и inline-size существует довольно много свойств, которые находятся в разработке. Такие свойства, как margin, padding и даже border, имеют свои новые логические варианты.

Так зачем ждать? Вот Gist, содержащий миксины для Border, BorderRadius, Margin, Padding, Position и Size.

Вывод

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

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

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

Ресурсы:

Дополнительные материалы на plainenglish.io