Пишемо елементні запити вже сьогодні за допомогою EQCSS

27

Від автора: всі ми чули про медіа запити в CSS, за допомогою яких можна змінювати зовнішній вигляд елемента на основі ширини екрана. Елементні запити схожі на медіа запити, але умови адаптивності застосовуються до окремих елементів на сторінці, а не до вьюпорту. Наприклад, можна застосовувати різні стилі елементу на основі його власної ширини, кількості елементів всередині нього або того, яким чином користувач прокрутив сторінку.

Навіщо нам потрібні елементні запити?

На початку я вже сказав, що елементні запити допомагають стилізувати елементи по ряду властивостей, а не просто по ширині і висоті вьюпорта. Крім цього існує ще кілька ситуацій, коли бібліотека може виявитися дуже корисною.

Наприклад, ви створили красивий адаптивний макет, на якому всі елементи ідеально підходять один до одного. І вас попросили додати до колонок ще одну. Простору для всіх інших колонок стане менше.

Ваші зображення і текст з ідеальними пропорціями для колонок шириною 800px на вьюпорте шириною 1366px можуть не так добре виглядати в колонках шириною 600px на тому ж вьюпорте. Ширина вьюпорта залишилася колишньою, а ось колонки стали вже, щоб звільнити місце під сайдбар. Використання елементних запитів замість медіа запитів в таких ситуаціях може заощадити вам купу часу, тому що вам не доведеться переписувати CSS при будь-яких змінах в макеті.

У демо нижче якщо наш вьюпорт звужується (стає вже 500px), ми задаємо зображень ширину 100% і переміщаємо все в одну колонку. Однак на великому вьюпорте якщо клікнути на кнопку «Add Sidebar», основна колонка стане значно вже без зміни ширини вьюпорта, з-за чого зображення здається дуже маленьким.

Тепер давайте уявимо, що ви створюєте віджет або плагін, а для адаптивності використовуєте медіа запити. Проблема полягає в тому, що віджет може бути всередині контейнера, чия ширина дорівнює вьюпорту або однієї четвертої. Якщо ширина віджета залежить від ширини контейнера, то не можна покладатися на розмір вьюпорта для стилізації віджета, це не спрацює. Тут нам допоможуть елементні запити! Елементні запити спрацюють як треба, так як вони використовують власну ширину віджета для стилізації.

На зображенні нижче один віджет поміщений у два різних місця. Як бачите, ширина вьюпорта однакова, а ширина віджетів різна. Так як стилі застосовуються на основі ширини віджета, то обидва віджета ідеально вписалися в макет.

Пишем элементные запросы уже сегодня с помощью EQCSS

Елементні запити відокремлюють умови адаптивності від макета сторінки. Можна створювати і стилізувати компоненти типу меню і таблиць без оглядки на навколишні елементи. Тобто таблицю з цінами для сайту А можна використовувати на сайті B. Сильно допомагає при створенні шаблонів.

Починаємо роботу з EQCSS

Щоб використовувати елементні запити в своїх проектах, вам знадобиться підключити EQCSS в HTML. Завантажити файл з їх репозиторію на GitHub або по прямой ссылке на минифицированный файл на CDNjs.

Плагін підтримує всі сучасні браузери, в тому числі IE9 і вище. Якщо вам потрібно підтримувати IE8, вам також знадобиться підключити полифил в свій проект. Полифил повинен бути підключений перед плагіном.

Після підключення потрібних файлів, можна почати використовувати EQCSS в своїх проектах. Існує два способи. Найпростіший – просто писати EQCSS в звичайному CSS в тегах style чи link. Інший спосіб – окремо підключати EQCSS стилі всередині тега script з користувальницьким типом:

/* Вставити ваш EQCSS */
або

За замовчуванням скрипт буде виконуватися і обчислювати всі стилі після завантаження контенту, а також щодо подій resize і scroll. Починаючи з версії 1.2, плагін також спрацьовує на події input, click, mouseup і mousemove. Для подій scroll якщо запит застосований до body або html, подія прокрутки чіпляється до window. В інших випадках подія прокрутки чіпляється до елементу, визначеній у запиті.

Якщо потрібно заново обчислити стилі по якійсь іншій події, можна викликати EQCSS.apply().

Пишемо елементні запити

Синтаксис елементних запитів сильно нагадує медіа запити. Наприклад, елементний запит починається з @element, після чого йде хоча б один селектор, до якого будуть застосовуватися стилі.

@element {selector} and {condition} {
/* Ваш дійсний CSS */
}

Зображення в демо вище, може повністю заповнювати ширину контейнера з допомогою наступного запиту:

@element «.content» and (max-width: 480px) {
.content img {
width: 100%;
}
}

Як тільки ширина нашого контенту стане менше 480px, всі зображення всередині контейнера отримають ширину 100%. Тільки є одна проблема. EQCSS повторно обчислює стилі тільки при зміні розміру вікна браузера, події click або scroll. В нашому випадку нам потрібно викликати EQCSS.apply() у події click по кнопці. У демо нижче показано, як добре наше зображення адаптується до додаткової колонці (якщо ширина вікна більше 480px, вам потрібно зменшити ширину вікна браузера):

Умови елементних запитах не обмежуються шириною і висотою елемента. Елементи можна стилізувати за кількістю дочірніх елементів. Один з прикладів, що приходить на розум – картковий макет на домашній сторінці сайту SitePoint. Всі картки в розділі Вибране мають одну ширину і висоту, а от довжина заголовка у картці може бути різною. Коли заголовок занадто довгий і не вміщується в картку, можна зменшити розмір шрифту за допомогою EQCSS:

@element «.card h2» and (min-characters: 50) {
$this {
font-size: 1em;
}
}

Деякі з вас могли помітити, що я використав $this замість .card h2. Якщо використовувати .card h2, то розмір шрифту не зміниться у всіх заголовках у картках, а конструкція $this змінить шрифт тільки в заголовку, чия довжина перевищує заданий ліміт. Є й інші схожі селектори: $parent , $prev і $next. Всі ці селектори називають мета селекторами.

Використання елементних запитів

Перш ніж вирішити, чи давати елементним запитам шанс, читачі SitePoint, можливо, хочуть дізнатися, як насправді працює плагін, щоб визначити, чи підходить це рішення під їх проекти (і зрозуміти, як можна його використовувати). Нижче я описав, що відбувається за лаштунками:

У циклі проганяються всі елементні запити і знаходяться необхідні елементи. Далі в циклі проганяються знайдені елементи, всім їм призначається унікальний ідентифікатор у формі атрибута. Формат ідентифікатора data-eqcss-{element-query-index}-{matched-element-index}. Data-атрибут додається до батьківського елементу, який виходить шляхом додавання –parent до ідентифікатором елемента. Схожі ідентифікатори додаються до попереднього і наступного суміжного елемента. В кінці всі елементи і їх запити перевіряються на виконання всіх можливих умов, таких як min-height, max-height, min-scroll-x і т. д., після чого застосовуються стилі.

Стилі додаються в тег . Примусова затримка забезпечує виклик EQCSS.apply() не частіше 200ms (затримка за замовчуванням). На відміну від resize, input і click, події scroll спрацьовують лише на елементах, що використовують елементний запит scroll.

Стилі для різних елементів обчислюються з допомогою JS, тобто продуктивність залежить від кількості елементів, до яких застосовуються стилі. У Firefox і Edge спостерігаються помітні лаги при великій кількості елементів. В останній версії Firefox продуктивність була покращена, а в майбутньому вона буде ще краще.

В ідеалі, плагін повинен додавати один або два EQCSS data-атрибута на елемент. Якщо помилитися, то на один елемент можуть бути присвоєні десятки EQCSS атрибутів, що сильно засмічує розмітку. Ви ж не хочете, щоб ваша розмітка стала схожа на:

Пишем элементные запросы уже сегодня с помощью EQCSS

Також не забувайте, що не потрібно додавати всі ці атрибути в HTML вручну. Вони додаються автоматично в момент роботи плагіна.

Налагодження елементних запитів трохи складніше медіа запитів. На даний момент браузери відрізняють тільки медіа запити, про елементні запити вони не знають. Тому вони зможуть розібрати тільки стилі EQCSS.

Після прочитання статті ви можете захотіти замінити всі медіа запити на елементні запити. Не робіть цього. По-перше, медіа запити виконуються швидше елементних, так як останні покладаються на JS для обчислення стилів. Занадто багато елементних запитів можуть вбити продуктивність вашого сайту (в Firefox і IE).

У 2015 плагін плавно працював у Firefox. Однак на початку 2016 розробники внесли кілька змін в браузер, з-за чого продуктивність впала. Розробникам плагіна довелося примусово занижувати частоту виклику за допомогою EQCSS.throttle() і контролювати повторну збірку стилів.

По-друге, медіа запити використовуються не тільки для елементів стилізації на екрані. Їх також використовують для створення стилів для інших медіа типів і властивостей. В якості прикладу – стилі версії сторінки для друку все ще додаються через медіа запити.

Висновок

EQCSS чудовий інструмент, якщо правильно підійти до справи. За допомогою цього плагіна можна робити багато всього, що неможливо в медіа запитах. При великій кількості елементів може постраждати продуктивність, однак синтаксис елементних запитів дуже схожий на медіа запити. Вивчення не буде важким.

В майбутньому браузери можуть отримати такі функції, як ResizeObserver, з допомогою яких розробники зможуть створювати поліпшені плагіни для умов min-width, max-width, min-height max-height. З’явиться підтримка Houdini, яка дозволить додавати підтримку цих умов прямо в браузер. Розробники будуть працювати над створення плагіна, який вбере в себе всі ці функції, але вони також планують продовжити підтримувати поточний плагін EQCSS. Їх мета – розробити колекція плагінів, щоб кожен з них підходив під певний браузер.

А що ви думаєте про цю бібліотеці? Використовували її в своїх проектах? Пишіть в коментарях.