Разработка расширяемых HTML и CSS компонентов

Это гостевой пост Джона Яблонски. Джон покажет нам пример, как можно верстать, чтобы один компонент был практически универсальным. С помощью стандартизированного способа создания вариаций (путем добавления одного класса), дизайн можно изменять соответственно ситуации.
Дни веб страниц с фиксированной шириной давно прошли. Чтобы создавать гибкие макеты, которые умно адаптируются под любые размеры мониторов, наш рабочий процесс претерпел изменения, стал более быстрым и повторяющимся. Мы пришли к пониманию важности модулей и того, как они помогают с адаптивностью, которая должна оставаться быстрой и ловкой. Я заметил, что чаще принимаю дизайнерские решения в браузере, чем проектирую файлы, и для поддержания этого рабочего процесса мне нужна возможность строить интерфейс с помощью модулей, которые могут быть легко расширены.
Расширяемые модули
Расширяемость – это принцип дизайна, когда реализация учитывает будущий рост. Основная идея расширяемости – предусмотреть изменения с помощью минимального влияния на существующую систему. Для фронт-энда это значит создание разных модулей, которые могут быть легко расширены, чтобы соответствовать нуждам интерфейса, сохраняя при этом фундамент, лежащий в основе модуля. Конечный результат – это менее раздутый и менее фрагментированный код из-за одноразовых решений, и код, который легко поддерживать.
Использование расширяемости
Для совместимости наших компонентов и шаблонов, нужно строить их в повторяющейся и предсказуемой манере. Ниже приведены основные шаги, которые я использую:
Шаг 1. Определите тип модуля
Первый шаг – это определение типа модуля, с которым мы работаем. Он может быть отнесен к одной из двух категорий: компонент или шаблон. Компонент – это независимый модульный объект, у которого нет дочерних элементов, но могут быть модификаторы, меняющие его вид (например: кнопки, сообщения, превью). Шаблон, наоборот – объект, имеющий дочерние элементы (которыми могут быть самостоятельные компоненты), зависящие от родительского объекта (например: header, header logo, header nav). И компоненты и шаблоны могут иметь модификаторы, меняющие их вид или структуру.
Шаг 2. Определение основы модуля
Следующий шаг – найти основные правила компонента или шаблона, которые будут унаследованы всеми вариациями. Этих правил должно быть относительно не много, обычно это свойства, которые редко изменяются. Чаще всего это margin, padding, position, и display.
Все примеры кода в этой статье используют методологию присвоения имен BEM (block, element, modifier). BEM дает множество преимуществ, но наверное, мое самое любимое – это то, что я могу посмотреть на элемент разметки и понять, что он делает всего лишь по его имени. Если вы хотите узнать больше об этой методологии, я бы рекомендовал посмотреть эту статью.
<div class="block"></div>
.block {
position: relative;
margin: 0 0 1em;
}
Шаг 3. Определение простых элементов
Если вы строите компонент, то можете пропустить этот шаг и переходить к следующему; но если вы строите шаблон, который будет содержать дочерние элементы, то следующий шаг - определение простых элементов. Эти элементы тематически связаны с родительским блоком (но могут существовать отдельно от шаблона как самостоятельные компоненты).
<div class="block">
<div class="block__element">…</div>
<div class="block__another-element">…</div>
</div>
.block__element {
padding: 1em;
background: white;
border: 1px solid black;
}
.block__another-element {
position: absolute;
top: 0;
right: 0;
}
Шаг 4. Расширение с помощью модификатора
Финальный шаг – это расширение вашего компонента или шаблона с помощью модификаторов. Модификаторы – это по сути вариации, которые расширяют основной блок и дочерние элементы, и могут быть созданы, когда они вам нужны.
<div class="block block—modifier">
<div class="block__element">…</div>
<div class="block__another-element">…</div>
</div>
.block—modifier {
border-top: 3px solid red;
}
.block—modifier .block__element {
background: grey;
}
Примеры
Теперь, когда мы рассмотрели основные шаги, участвующие в построение расширяемых компонентов и шаблонов, самое время изучить несколько примеров. Мы начнем с относительно простых компонентов и того, как они могут быть расширены, чтобы охватить несколько сценариев, а потом мы рассмотрим немного более сложные шаблоны.
О компонентах
Ниже пример нескольких простых компонентов и их вариаций. У каждого компонента есть модификаторы, расширяющие его стиль. Это позволяет быстро создавать вариации, давая вам возможность повторять и адаптировать компоненты под любую ситуацию в вашем интерфейсе.
Пример простых компонентов
See the Pen Common Extendable Components by Jon Yablonski (@jonyablonski) on CodePen.
Компоненты по своей природе должны быть относительно простыми, так как не содержат дочерних элементов. Теперь, давайте рассмотрим что-то чуть более сложное.
О шаблонах
Медиа шаблон – объект, содержащий медиа элемент (это может быть изображение или видео) и связанный с ним контент (обычно в форме текста). Возможно, вы знакомы с вариантом медиа шаблона известным как ‘media object’ или ‘flag object’, который мы немного затронем. Этот шаблон – отличный пример построения с учетом расширяемости, которая обеспечивает бесконечную гибкость.
Стандартный медиа шаблон
Мы начнем со стандартного шаблона без модификаторов. Я использовал тег article, но вы можете поменять его на любой другой тег, какой захотите. Основные стили нашего медиа шаблона:
- Flex контейнер,
- Немного margin.
Все медиа шаблоны будут наследовать эти стили. Также, каждый медиа шаблон будет содержать медиа объект (в данном случае изображение) и тело, содержащее заголовок и список определений.
See the Pen Default Media Pattern by Jon Yablonski (@jonyablonski) on CodePen.
Шаблон «Media Card»
Если для одной ситуации стандартного шаблона может быть достаточно, то для множества других вы захотите кардинально изменить его вид. Следующий шаг – определить изменения, которые помогут шаблону адаптироваться к разным ситуациям. Давайте начнем с вариации, которая не сильно отличается от исходного вида – карточной вариации. Предпосылкой является то, что понадобится немного изменений в разметке и мы сможем изменить вид шаблона, просто добавив модифицирующий класс на родительский блок:
See the Pen Media Card Pattern by Jon Yablonski (@jonyablonski) on CodePen.
Шаблон «Media Object»
Предположим, что позже мне понадобился шаблон, в котором изображение и текст отображаются на одной линии, если для этого достаточно места. Такой шаблон обычно называют 'media object'. Чтобы создать его и избежать лишнего кода, мы можем просто расширить уже существующий медиа шаблон.
See the Pen Media Object Pattern by Jon Yablonski (@jonyablonski) on CodePen.
Шаблон «Media Slat»
Давайте пойдем немного дальше с вариацией, которая станет реальным тестом. Вариации, которые мы определили ранее, хорошо подстраиваются под все мои нужды, но мне нужна еще одна. Давайте создадим вариацию, которая занимает всю ширину окна, чтобы тело и картинка занимали по половине. Кроме этого, я хочу убедиться, что контент тела выравнивается в одну линию с другим контентом страницы. Мы назовем эту вариацию ‘media slat’:
See the Pen Media Slat Pattern by Jon Yablonski (@jonyablonski) on CodePen.
Теперь у нас есть несколько вариаций медиа шаблона: стандартная, карточная, объектная и, наконец, полочная. Все эти вариации шаблона полезны в разных ситуациях, и все они построены на одной базовой основе кода! Любые изменения, произошедшие с базовым шаблоном, отразятся на всех его вариациях, поэтому все они будут синхронизированы и последовательны.
Выводы
Мы рассмотрели, почему лучше использовать расширяемые компоненты и шаблоны при построении интерфейсов, сосредоточенных на гибкости и дальнейшей поддержке. И чтобы проиллюстрировать это, мы рассмотрели шаги создания некоторых расширяемых компонентов. Преимущества построения интерфейсов таким способом станут очевидны сразу же, так как вы будете тратить меньше времени на рефакторинг из-за неожиданного изменения дизайна или дополнений, а ваши стили будет легче поддерживать.