От автора: с тех пор, как я узнала о переменных CSS несколько лет назад, моя самая любимая функция — возможность привязывать переменные к компонентам. Но, честно говоря, я не использовала эту функцию на протяжении многих лет, пока в прошлом году я не создала собственную библиотеку шаблонов для ускорения создания прототипов и работы с клиентами.
За последние несколько месяцев я начала подходить к тому, как организовать и управлять CSS, по-другому…
Глобальные настройки проекта
Сегодня в начале каждого проекта я создаю таблицу стилей _settings.scss. Эта таблица стилей содержит глобальные настройки для проекта. Эти настройки обычно получаются из руководства по стилю дизайна, предоставленного командой разработчиков, с которой я буду работать.
Пример визуальных настроек, определенных в руководстве по стилю для моего текущего клиентского проекта. Руководство по стилю содержит образцы цветов, фирменные цвета, цвета взаимодействия и пользовательского интерфейса, стили шрифтов, размеры шрифтов, интервалы, иконки и т. д. Я использовала руководство по стилю в качестве отправной точки в своем CSS, так как создавала и определяла глобальные стили проекта выводя их значения из их визуальных эквивалентов в руководстве по стилю.
Также, как руководство по стилю содержит настройки для визуальных стилей, такие как цвета, стили теней, стили шрифтов, размеры шрифтов и т. д., таблица стилей _settings содержит переменные, которые являются эквивалентом этих настроек, и которые используются в CSS для поддержки визуальных элементов.
:root { /* UI Colors */ --primary-hue: 12; --color--primary: hsl(var(--primary-hue), 100%, 44%); --color--primary--hover: hsl(var(--primary-hue), 100%, 39%); --color--primary--active: hsl(var(--primary-hue), 84%, 30%); /* ... */ --border-color: #ebebeb; /* Box Shadows */ --shadow-01: 0px 2px 4px rgba(37, 37, 37, 0.1); --shadow-02: 0px 4px 8px rgba(37, 37, 37, 0.1); --shadow-03: 0px 8px 16px rgba(37, 37, 37, 0.1); --shadow-04: 0px 16px 24px rgba(37, 37, 37, 0.1); --shadow-05: 0px 24px 32px rgba(37, 37, 37, 0.1); /* ... */ }
Пример глобальных настроек стиля, определенных в таблице стилей _settings.scss в моем текущем клиентском проекте.
.card { /* ... */ box-shadow: var(--shadow-01); border: 1px solid var(--border-color); transition: box-shadow .2s linear; &:hover, &:focus { box-shadow: var(--shadow-03); } }
Если в какой-то момент проекта потребуется изменить какие-либо из этих параметров, я точно знаю, куда их внести, и я знаю, что изменения будут последовательно распространены по всей системе.
В дополнение к этим настройкам я нашла наибольшую ценность и удобство в использовании переменных CSS для определения локальных стилей в области компонентов…
Быстрое прототипирование с использованием компонентов Skeleton
За эти годы, чтобы сэкономить свое время и ускорить создание прототипов и работу с клиентами, я создал библиотеку UI и шаблонов проектирования, которые, как мне кажется, нужны мне для воссоздания в большинстве проектов. Библиотека теперь содержит растущую коллекцию шаблонов пользовательского интерфейса, которые можно многократно использовать, и которые я могу смело копировать и вставлять в проекты, когда они мне нужны. Каждый шаблон постепенно совершенствуется с использованием современных CSS и JavaScript, и доступен с нуля для различных браузеров и платформ.
Поскольку я создала библиотеку как «внутренний» проект, она в настоящее время находится в частном хранилище Github и за паролем в домене .dev моего сайта.
Я назвала библиотеку «Skeleton» и создала ее с помощью Fractal. Я использую Fractal уже пару лет. Я выбрал его среди других инструментов шаблонов, потому что он идеально соответствовал моим потребностям — мне нужен был инструмент, который был бы достаточно гибким, чтобы позволить настроить и структурировать мой проект так, как я хотела. Fractal идеально подходит под это описание, потому что он не зависит от того, как я разрабатываю или какие инструменты использую. Особенно мне нравится, что: «компоненты могут быть вложены в папки, чтобы упростить поиск конкретных компонентов, и то, как вы структурируете папки, полностью зависит от вас».
Я организовала шаблоны так, чтобы каждый шаблон находился в своем собственном каталоге, содержащем HTML-шаблон компонента, CSS и файлы обычного JavaScript, а также любые дополнительные ресурсы, специфичные для Fractal (например, файлы конфигурации).
Используя эту структуру, каждый из моих шаблонов самодостаточен. И я могу включать и объединять стили и скрипты шаблона в проектах по мере необходимости.
/* styles.scss */ @import "accordion"; @import "modal";
Моя цель при создании этой библиотеки — создать инструмент, который позволит мне разрабатывать прототипы быстрее, и который будет достаточно гибким и эффективным для использования в различных проектах. А поскольку шаблоны обычно по-разному оформляются в моих проектах, я хотела упростить процесс их настройки для каждого проекта.
Настройки для компонента с ограниченной областью применения
Поскольку я не хочу тратить много времени на переопределение и отмену стилей при использовании шаблона в новом проекте, я создала эту библиотеку с компонентами, по умолчанию практически не имеющими стиля — в основном белый цвет (без цветов), минимальный интервал и границы только там, где это визуально уместно. Таким образом, шаблоны буквально выглядят как скелеты, отсюда и название. Теперь, когда мне нужно использовать один из этих компонентов, у меня есть немного CSS для переопределения, прежде чем они будут готовы для подключения к новому проекту.
Я обнаружила, что для каждого шаблона я изменяю одни и те же свойства всякий раз, когда мне нужно его использовать — например, шрифт, цвета (текст, фон, рамка), тень от рамки, интервалы и т. д. Поэтому я подумала, что это будет полезно и эффективно, если я создам переменные для этих свойств, определив эти переменные в «корне» компонента и «передав» значения для этих переменных, когда я буду использовать шаблон по мере необходимости. Таким образом, я могу настроить или создать тему для компонента, изменив значения свойств в одном наборе правил, вместо того чтобы переходить между несколькими.
Я использую переменные для абстрагирования всех стилей, которые мне обычно нужно переопределить. Таким образом, каждое свойство, которое изменяется в разных проектах, обычно «превращается» в переменную. Затем, если в какой-то момент проекта мне нужно настроить стиль(и) шаблона, я точно знаю, где это сделать. Это делает стили для каждого шаблона более читаемыми и более удобными в обслуживании, что еще более важно, когда CSS нужно изменить кому-то еще.
Этот подход довольно хорошо сочетается с моим подходом к организации файлов CSS. Мне нравится организовывать CSS в отдельные таблицы стилей по шаблонам, которые включают все стили шаблона и адаптивное поведение. Из этого правила будут исключения… скажем, стили для «атомов» (например, кнопок, полей ввода и т. д.), которые повторно используются в шаблонах, определены в одной таблице стилей. И даже тогда, когда стилизация атома становится немного сложной (например, стилизация пользовательского поля ввода для загрузки файлов), я могу создать для этого отдельную таблицу стилей. Я подробнее расскажу о том, как организую свой CSS, в другой статье.
Пример
Как и большинство из вас, я создаю элемент select почти во всех своих проектах. С прошлого года я использую кроссбраузерную технику Скотта Джела. Я считаю, что в основном мне нужно изменить иконку, цвет границы, радиус границы и цвет фона. В каждом проекте я также устанавливала схему фокуса для интерактивных элементов. Цвет контура также варьируется в зависимости от проекта.
Итак, я вывела эти свойства в переменные. Для каждого свойства я устанавливаю значение по умолчанию или пустое значение и изменяю это значение при использовании компонента в новом проекте по мере необходимости.
.c-custom-select { --icon: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2232%22%20height%3D%2232%22%20viewBox%3D%220%200%2032%2032%22%3E%0A%3Cpath%20fill%3D%22%23777%22%20d%3D%22M9.914%2011.086l-2.829%202.829%208.914%208.914%208.914-8.914-2.828-2.828-6.086%206.086z%22%3E%3C%2Fpath%3E%0A%3C%2Fsvg%3E%0A"); --icon--disabled: ; --border-color: currentColor; --border-color--disabled: ; --color--disabled: ; --border-radius: 0; --background-color: #fff; --gradient-background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%); --outline-color: hsl(265, 50%, 50%); --padding: .5em; }
Мне нравится думать об этом правиле, как об объекте настроек для компонента. Это ускоряет темизацию компонента, передавая нужные значения. Остальные наборы правил для компонента select содержат фиксированные правила или стили, которые, скорее всего, не изменятся в разных проектах:
.c-custom-select { -moz-appearance: none; -webkit-appearance: none; appearance: none; box-sizing: border-box; display: block; width: 100%; max-width: 100%; padding: var(--padding); padding-right: calc(var(--padding) * 3); font: inherit; color: inherit; line-height: 1.3; border: 1px solid var(--border-color); border-radius: var(--border-radius); background-color: var(--background-color); background-image: var(--icon), var(--gradient-background); background-repeat: no-repeat, repeat; background-position: right calc(var(--padding) * 1.5) top 50%, 0 0; background-size: 1em auto, 100%; } .c-custom-select::-ms-expand { display: none; } .c-custom-select:focus { outline: none; box-shadow: 0 0 0 3px var(--outline-color); box-shadow: 0 0 0 3px -moz-mac-focusring; } .c-custom-select:focus:not(:focus-visible) { box-shadow: none; } .c-custom-select:disabled, .c-custom-select[aria-disabled=true] { color: var(--color--disabled); background-image: var(--icon--disabled), linear-gradient(to bottom, #ffffff 0%,#e5e5e5 100%); } .c-custom-select:disabled:hover, .c-custom-select[aria-disabled=true] { border-color: var(--border-color--disabled); }
Двигаемся вперед
Как бы мне ни хотелось делать это во всех проектах, к сожалению, пока я могу использовать этот подход только для стилизации и управления CSS компонентов в моих собственных проектах. Причина в том, что большинству моих клиентов по-прежнему требуется поддержка как минимум одной или двух версий IE, которые не поддерживают переменные CSS. И хотя для переменных CSS существует полифилл, он обеспечивает поддержку только тех переменных, которые определены в корневом HTML-элементе. В зависимости от уровня поддержки и оптимизации, который нам нужен для IE, в настоящее время я использую полифилл и переменные CSS, по крайней мере, для определения глобальных стилей проекта.
В будущем я буду использовать этот подход к управлению стилями в сочетании с веб-компонентами для создания в целом более переносимых шаблонов. И, надеюсь, когда-нибудь в будущем у нас будут контейнерные запросы, чтобы сделать эти компоненты действительно автономными.
Что касается Skeleton, ей еще предстоит пройти долгий путь. Моя цель — создать собственную тему Fractal. Я еще не нашла хорошего и полного руководства о том, как это сделать, тем более что я стремлюсь создать тему с нуля, чтобы иметь полный контроль над ее стилями. Если вы знаете меня, вы знаете, что я, вероятно, напишу это руководство, как только пойму, как создать тему с нуля.
Я также постоянно работаю над добавлением новых шаблонов и вариантов шаблонов. И я планирую включить раздел Сниппеты, который будет включать фрагменты кода, которые я также часто использую в проектах, таких как шаблоны и функции JavaScript. И, конечно же, я хочу серьезно заняться документацией, включая добавление постов о передовых практиках, таких как методы оптимизации перфокарт, лучшие методы работы с иконками и изображениями и т. д., и я уже начала составлять большинство этих вещей.
Я в какой-то момент в будущем могу (или нет) превратить библиотеку в совместный продукт. Но это не то, что заложено в ее дорожной карте на данный момент. На данный момент мне нравится идея, что это небольшой личный проект без каких-либо условий. Тем не менее, я хотела бы опубликовать библиотеку в виде пакета npm (для частного использования для начала). Я пока не знакома с тем, как это сделать. Но я нашла статью на CloudFour, которая посвящена именно этому, так что, вероятно, это будет моей отправной точкой. И я определенно задокументирую свой процесс, сейчас я придумываю способ сделать это.
Внимание: использование переменных CSS с определенной областью применения также имеет преимущества в производительности, потому что установка и изменение переменных, определенных в глобальной области видимости, могут быть затратным и сопряженным с ошибками в производительности из-за большого количества пересчетов стилей.
Автор: Sara Soueidan
Источник: https://www.sarasoueidan.com
Редакция: Команда webformyself.