Как вы можете использовать отзывчивые веб-компоненты сегодня +9



Пару лет назад я впервые услышал про веб-компоненты (Web Components). Сперва меня это действительно заинтересовало, но как только шумиха вокруг них приутихла, они тут же вылетели у меня из головы. Но, как оказалось, в последнее время прошло интересное движение и поддержка этой технологии значительно выросла. Отзывчивые веб-компоненты, в частности, призваны упростить наш подход к адаптивному дизайну. Как многообещающе звучит!
Вот четыре пункта, с которыми стоит ознакомиться любому разработчику перед началом использования данной технологии:
  • Поддержка технологии;
  • Кроссбраузерная работа;
  • Возможность адаптации в среде удельного проекта;
  • Модульный подход.

В этой статье мы рассмотрим каждый из этих пунктов в отдельности...

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


Что такое веб-компоненты?


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

Почему я хочу их использовать?


Хорошим примером того, когда вы можете захотеть использовать веб-компоненты является задача, где вам требуется создать пользовательский интерфейс, которого нативно не существует в браузере — такие элементы, как селектор цвета, карусель, аккордеон, поле с автодополнением. Можно использовать в качестве альтернативы одним и тем же компонентам, которыми вы пользуетесь из проекта в проект, предварительно лениво кастомизируя их под требования текущего. Это такие вещи, как социальные кнопки, формы подписки или уведомления. С помощью веб-компонентов вы можете связать разметку, стили и скрипты в один герметизированный модуль и использовать HTML-тег (как <color-picker></color-picker>), чтобы ссылаться на него. Это довольно таки знакомо, если вы уже использовали Angular-директивы или компоненты React, но преимущество здесь в том, что данный подход является родным для браузера и «агностиком» фреймворков.

Веб-компоненты дают вам возможность единожды создать UI-элемент и потом использовать его где угодно. Это идеально подходит для таких проектов как живой стилистический справочник (или styleguide), где вы хотите создать библиотеку с единственным источником истины для каждого из компонентов (где каждый компонент попадает только под своё уникальное правило поведения и отображения). Такой подход подразумевает более короткий, минималистичный код, а также наличие готовых UI-компонентов, ссылки на которые вы или ваша команда можете лёгко добавить в текущий интерфейс.

Другое большое преимущество использования веб-компонентов — это возможность упаковать свой модуль и поделиться ним с другими разработчиками/владельцами сайтов. По сути, пользователю всего лишь остаётся добавить оператор импорта на свой веб-сайт:

<link rel="import" href="http://url.com/subscribe-form.html">


А затем использовать кастомный тег элемента, что определён для данного веб-компонента. Так пользователь может добавить на свой веб-сайт столько кастомных веб-компонентов, сколько он захочет. К примеру, для формы подписки вы можете использовать тег — <subscribe-form></subscribe-form>, таким образом размещая её в одном, или нескольких местах на странице. Конечно, перед тем как сделать это, вы должны убедиться в том, что созданный вами веб-компонент достаточно гибок и будет адекватно работать в ряду различных устройств и размеров экранов.

Переходим от теории к практике


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

К примеру возьмём форму, которую я создал ранее:



Внутри данного шаблона я создал некую базовую разметку для формы:

<ul class="form"> 
  <li class="form__item">
    <label for="name">Name:</label>
    <input id="name" name="name" type="text">
  </li>
  <li class="form__item">
    <label for="name">Email:</label>
    <input id="name" name="name" type="text">
  </li>
</ul>


Моя разметка и стили спрятаны внутри веб-компонента с помощью возможностей, которые предоставляет Shadow DOM спецификация. Данный способ организовывает некую инкапсуляцию, которая даёт мне возможность использовать label и input селекторы свободно, не боясь влияния на них стилей родительского веб-сайта.

Для ясности и краткости, я не буду описывать написание стилей, кроме тех, которые я использовал для отображения разметки. Я использовал комбинацию свойств float: left и display: table для реализации данного интерфейса и избегания поломки при любой ширине.

.form__item {
  display: table;
  float: left;
  width: 50%;  
}

label {
  display: table-cell;
  width: auto;
}

input {
  display: table-cell;
  width: 100%;
}


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



Теперь у нас все готово, давайте рассмотрим некоторые техники достижения адаптивности.

Медиа запросы


Классический подход, который мы все знаем и любим, так же хорошо работает и в отзывчивых веб-компонентах. Вы можете использовать медиа запросы внутри вашего шаблона в случае, если вы хотите создать какие-либо дефолтные контрольные точки. С другой стороны вы можете использовать «крючки» (к примеру, создавая классы) и применяя их к родительскому контейнеру, таким образом оставляя возможность пользователю самостоятельно принимать решение. В нашем случае, всё, что нам нужно, — это создать контрольную точку, достигая которую мы отменяем свойство float для дочерних элементов и задаём им ширину в 100%.

@media (max-width: 30em) {
  .form__item {
    float: none;
    width: 100%;
  }
}



Однако, одних медиа запросов тут будет не достаточно.

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



Это происходит потому, что веб-компонент не видит своих границ — не имеет представления о контексте.

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

Flexbox-хак


Если вы задумали использовать веб-компоненты в своём проекте и готовы пожертвовать поддержкой старых браузеров (таких как IE9 и тд.), то чуточку Flexbox-магии вам совсем не навредит. Это отличное решение, которое, к тому же, совершенно не требует использование JavaScript.

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

.form {
  display: flex;
  flex-wrap: wrap;
}

.form__item {
  align-items: center;   
  display: flex;
  flex: 1 0 320px;
  flex-wrap: wrap;
  max-width: 100%;
}       

label {
  flex: 1 0 90px;
}

input {
  flex: 1 0 230px;
  width: 100%;
}


Устанавливая родительскому контейнеру display: flex и flex-wrap: wrap, дочерние .form__item выстроются один к одном, блок-о-блок, но нам всё ещё нужно определить несколько правил, чтоб в случае, если контейнер становится слишком мал, дочерние элементы спрыгивали один под другой.

Внутри .form__item мы использовали краткое записание свойства — flex: 1 0 320px, которое можно разложить как: flex-grow: 1, flex-shrink: 0, flex-basis: 320px. Установив flex-wrap: wrap, мы определили, что ширина нашего элемента не станет меньше указанной в 320px, в то время как указав свойство flex, мы разрешили нашему элементу расти и занимать оставшееся свободное место в строке.

Такой же подход я использовал для элементов input и label. Их суммарное значение flex будет равно 320px, что подразумевает, что они будут адекватно отображены и при меньших размерах контейнера.

Давайте посмотрим, к чему привели сделанные нами изменения:



Гораздо лучше! Тем не менее, это не единственный способ решения данной проблемы, их бесчисленное множество.

Запросы соответствующие веб-элементам


Идея использования запросов соответствующих определённым элементам — это то, что позволяет вам эмулировать функциональность медиа запросов на уровне веб-элемента — что очень удобно при создании отзывчивых веб-компонентов. Проще говоря, представьте, если бы у вас была возможность писать нечто на подобии этого в вашем css:

.form__item[max-width~="30em"] {
  /* Styles here */
}


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

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

В моём примере я использовал CSS Element Queries, созданный человеком по имени Marc J Schmidt. Этот плагин является действительно хорошей реализацией решения данной задачи. Есть также следующие похожие проекты:

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

.form__item[max-width~="30em"] {
  float: none;
  width: 100%;
}


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

Атрибуты


Одна из потрясающих вещей, которую мы можем предложить потребителю нашего отзывчивого веб-компонента, — это API атрибутов к данному элементу. Например, вы могли бы установить атрибут, называемый layout, определяющий размеры компонента в данном контексте: «малый» или «большой». А затем его можно использовать следующим образом:

<subscribe-form layout="small"></subscribe-form>


Таким образом создаём крючок, что определяет дополнительные CSS-свойства.

В Shadow DOM спецификации контейнер, содержащий в себе элемент, определён как :host. Пример будет выглядеть так:

:host { 
  display: block; 
} 

:host([layout = "small"]) .form__item { 
  float: none;
  width: 100%;
} 

:host([layout = "large"]) .form__item { 
  display: table;
  float: left;
  width: 50%;   
}


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

Вывод


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

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




К сожалению, не доступен сервер mySQL