Элементарные запросы и как их можно использовать сегодня
Опубликовано: 2022-03-10Подумайте на мгновение о физической структуре. Если вы строите большое здание из непрочного материала, требуется много внешней поддержки, чтобы удерживать его вместе, и чтобы оно оставалось прочным, необходимо строить слишком много. Когда вы создаете веб-сайт из HTML, CSS и JavaScript, эта внешняя поддержка может выглядеть как фреймворки, плагины, препроцессоры, транспиляторы, инструменты редактирования, менеджеры пакетов и процессы сборки.
Вместо того, чтобы добавлять еще один плагин на вершину стека, я задался вопросом, сможем ли мы, расширив один из основных языков, CSS , усилить материал, из которого построены веб-сайты, разрабатывая более качественные и надежные веб-сайты, которые требуют меньше внешней поддержки и инструментов. строить.
Текущее состояние запросов элементов
С помощью таких инструментов, как препроцессоры CSS, мы пишем CSS сокращенно, чтобы позже расширить его до полной формы (перед просмотром в браузере). Плагины могут работать на странице вместе с элементами, на которые они влияют, но для применения стилей они либо записывают стили CSS непосредственно в HTML, либо переключают имена классов, которые применяют другие правила CSS. В обоих случаях нам нужно написать или сгенерировать CSS, который нам понадобится до фактической загрузки страницы.
Эта проблема
Проблема с этим методом заключается в том, что даже самые лучшие плагины часто требуют настройки и настройки в каждом используемом вами макете. Кроме того, когда JavaScript пишет стили для вас, может быть сложно сохранить вместе логику, основанную на плагинах, и ваши стили CSS при рефакторинге или повторном использовании кода.
Еще одна проблема с препроцессорами заключается в том, что любые ошибки, написанные стенографией, быстро превращаются в гораздо больший беспорядок, как только CSS раскрывается до полной формы. При использовании плагинов мы добавляем много потенциальных точек отказа. Мы можем использовать несколько плагинов для выполнения нескольких разных задач, которые могли бы быть ненужными, если бы CSS был немного мощнее. Это создает дополнительную нагрузку для разработчиков, для браузеров — для отображения и для пользователей — для загрузки.
Есть ли надежда на будущее веб-разработки?
В 2013 году Тайсон Матанич написал статью под названием «Медиа-запросы — это не ответ: полифилл запросов к элементам», в которой представил концепцию запросов к элементам широкой аудитории. Это положило начало дискуссии о том, как можно создавать плагины и полифиллы, чтобы обойти недостатки CSS.
С тех пор, пока мы ждем развития функций CSS, было выпущено несколько плагинов, которые позволяют разработчикам использовать запросы к элементам несколькими различными способами.
Что такое запросы элементов?
Запросы элементов аналогичны медиа-запросам, за исключением того, что их правила применяются к свойствам фактических элементов, а не к свойствам области просмотра браузера.
Как появился EQCSS
В конце 2013 года я работал над интерфейсом веб-приложения Ruby on Rails. Приложению нужно было отображать подробную информацию для пользователей, и цель состояла в том, чтобы создать адаптивный интерфейс, который одинаково хорошо работал бы на телефонах, планшетах и в настольных браузерах. Это создало несколько проблем, одна из которых заключалась в том, что большая часть отображаемого важного контента лучше всего отображалась в таблицах — да, в реальных элементах table
(для отображения финансовых транзакций, спортивных рекордов и т. д.).
Я создал адаптивные стили с помощью медиа-запросов, которые правильно отображали элемент table
для браузеров разных размеров. Но как только одна из этих адаптивных таблиц отображалась в шаблоне, содержащем боковую панель, внезапно все мои адаптивные контрольные точки превращались в адаптивные контрольные точки. Они просто не учли боковую панель шириной 200 пикселей, из-за чего элементы перекрывались и выглядели сломанными.
Еще одно препятствие: имена пользователей варьировались по длине от 3 до 20 символов, и мне захотелось автоматически настроить размер шрифта каждого имени пользователя в зависимости от количества содержащихся в нем символов . Мне нужно было поместить каждое имя пользователя на боковую панель, и было сложно выбрать размер шрифта, достаточно маленький, чтобы вместить 20-символьное имя пользователя, но достаточно большой, чтобы зритель мог видеть 3-символьное имя пользователя.
Чтобы обойти подобные проблемы, я часто копировал целые медиа-запросы, дублируя большие разделы моей кодовой базы просто потому, что мне нужен был более разумный способ применения адаптивных стилей в каждом макете. Я полагался на JavaScript как на еще одно импровизированное решение, написав множество почти идентичных функций, которые следили за страницей и применяли стили в местах, недоступных для CSS. Через некоторое время дополнительное бремя всего этого дублированного кода стало отягощать кодовую базу и затрудняло внесение изменений.
Я знал, что должно быть решение получше, и через некоторое время начал думать: мне не нужны медиа-запросы — мне нужны запросы к элементам!
Исследования и разработки
В 2014 году я начал экспериментировать с различными способами информирования CSS о свойствах элементов по мере их появления на странице, чтобы я мог применять лучшие стили. Я надеялся найти подход, который позволил бы мне писать стили, сочетающие красоту CSS с мощью JavaScript.
Некоторые заброшенные подходы, от которых я отказался, включают добавление атрибутов к тегам HTML, чтобы добавить адаптивную поддержку, и попытки найти способы встроить целые блоки кода CSS в операторы if
на основе JavaScript для создания своего рода монстра Франкенштейна, склеенного из JavaScript. и CSS.
Но вместо того, чтобы упростить задачу, все мои неудачные подходы имели одну общую черту: они добавляли больше работы! Я знал, что правильное решение упростит и уменьшит объем работы, которую необходимо выполнить, поэтому продолжал поиски. В результате этих экспериментов я пришел к уточненному представлению о типе синтаксиса, который потребуется для правильной работы запросов к элементам.
Как уже упоминалось, для веб-сайта, созданного из HTML, CSS и JavaScript, внешняя поддержка предоставляется в виде фреймворков, плагинов, препроцессоров, транспиляторов, инструментов редактирования, менеджеров пакетов и процессов сборки. Вместо того, чтобы добавить еще один плагин на вершину стека, я задался вопросом, сможем ли мы, расширив один из основных языков, CSS, усилить материал, из которого построены веб-сайты, создавая более качественные и надежные веб-сайты, которые требуют меньше внешней поддержки и инструменты для сборки.
Рождение синтаксиса
К концу 2014 года, имея более четкое представление о необходимом синтаксисе, я связался с Максимом Эузьером, феноменальным игроком в гольф с кодом JavaScript, и спросил его мнение о возможности расширения CSS с помощью JavaScript в браузере во время выполнения. Он не только сообщил мне, что это возможно, но и предложил помочь мне сделать это! Мы назвали синтаксис EQCSS, сокращение от «элементный запрос CSS». Название также является отсылкой к слову «избыток», потому что все, что он делает, выходит за рамки того, что может сделать CSS.
Необходимость
Мое требование к синтаксису заключалось в том, чтобы он был как можно ближе к CSS — настолько близко, чтобы подсветчики синтаксиса могли обмануться, думая, что это стандартный CSS. Итак, я наметил синтаксис CSS для запросов к элементам, который имел смысл — такой синтаксис, который удивляет людей, еще не существует.
Я знал, что если мы собираемся расширить браузерную поддержку CSS с помощью JavaScript, то плагин должен быть как можно более легким и простым, чтобы выполнить свою работу, что исключало использование библиотек, таких как jQuery, для создания плагина. Мне нужна была чистая библиотека JavaScript, которая добавляла бы функции, которые я хочу в будущем, в браузеры, которые я должен поддерживать сегодня.
В настоящее время обсуждение в сообществе CSS сосредоточено на пользовательских правилах @
, а обсуждение запросов к элементам все еще носит предварительный характер. Скорее всего, нам еще далеко до официальной спецификации CSS для таких функций, и даже после спецификации нам все равно придется ждать достаточной поддержки браузера, прежде чем мы сможем использовать эти функции на веб-сайтах.
Ждать, пока эти функции будут добавлены в CSS, не имеет смысла, когда нам сегодня нужны эти функции для создания и исправления веб-сайтов.
Результат
Результатом этого исследования стало создание синтаксиса, включающего новый набор расширенных условий реагирования, стилей с ограниченной областью действия и новых селекторов для целевых элементов, а также библиотеку чистого JavaScript под названием EQCSS.js. Кроме того, поддержка Internet Explorer (IE) 8 реализована в дополнительном внешнем полифиле. И плагин, и полифил были выпущены под лицензией MIT и бесплатны для всех.
Варианты использования для запросов элементов
Разработчики плагинов
При создании компонентов пользовательского интерфейса и виджетов разработчики часто ограничиваются медиа-запросами. Нам часто приходится выбирать между созданием множества различных макетов, которые может настроить человек, использующий плагин, и упрощением интерфейса до такой степени, что вы можете создать универсальное решение.
Но при разработке плагинов и интерфейсов с запросами элементов мы можем легко написать адаптивные стили, которые охватывают все ожидаемые нами ситуации, делая их действительно пуленепробиваемыми, независимо от того, какой контент пользователь помещает внутрь или где появляется плагин. Предположим, мы можем стилизовать виджет с макетами шириной от 150 до 2000 пикселей. Тогда, независимо от того, где этот виджет отображается на веб-сайте, он всегда будет выглядеть великолепно.
Создатели шаблонов
Когда вы создаете прототип веб-сайта, принято реорганизовывать элементы дизайна на странице и думать о дизайне как о наборе модульных компонентов. Если вы написали медиа-запросы CSS, иногда это может быть случаем преждевременной оптимизации . При проектировании с помощью запросов к элементам вы сохраняете условия отклика независимыми от макета, что дает вам гораздо больше гибкости для перемещения вещей без необходимости переделывать стили.
Вещи, которые я нашел особенно полезными для разработки или моделирования с использованием запросов к элементам, включают:
- панели навигации,
- модальные,
- формы регистрации и входа в систему,
- нижние колонтитулы,
- графики цен,
- целевые страницы,
- столы,
- вкладки,
- аккордеоны,
- боковые виджеты,
- медиаплееры,
- разделы отзывов.
Любой элемент дизайна можно масштабировать и переносить куда угодно — со страницы на страницу или с сайта на сайт.
Поддержка устройств
Одна из проблем, с которой вы сталкиваетесь при поддержке Интернета на мобильных устройствах, — это изобилие аппаратного обеспечения. Рынок устройств более фрагментирован, чем когда-либо прежде, и каждый день появляются новые устройства. Мы больше не можем вести список поддерживаемых нами браузеров и устройств, поэтому важно знать, что дизайн работает везде, даже на еще не выпущенных устройствах.
Используя элементные запросы, вы можете лучше разрабатывать веб-сайты и устранять некоторые из этих межбраузерных различий.
Многие недавно написанные статьи о необходимости запросов к элементам подробно иллюстрируют многие варианты использования. Итак, давайте продолжим, как их использовать!
Как писать запросы к элементам
Начать работу с EQCSS очень просто. Все, что вам нужно, чтобы начать использовать синтаксис EQCSS, — это включить JavaScript где-нибудь в ваш HTML.
Загрузка EQCSS.js
Если вы хотите клонировать проект EQCSS из GitHub, вы можете ввести:
git clone https://github.com/eqcss/eqcss.git
Если вы используете npm, вы можете добавить EQCSS в свой проект с помощью следующей команды:
npm install eqcss
Добавление EQCSS.js в ваш HTML
После того, как вы загрузили EQCSS, вы можете добавить его в свой HTML-код с помощью тега script
:
<script src="EQCSS.js"></script>
Этот файл ( EQCSS.js
) включает поддержку всех современных браузеров, включая IE 9 и выше. Для поддержки IE 8 нам пришлось бы использовать много других полифиллов. Имейте в виду, что IE 8 даже не поддерживает медиа-запросы CSS без полифилла, поэтому просто удивительно, что мы смогли заставить работать и запросы к элементам. Чтобы включить поддержку IE 8 для веб-сайта, использующего EQCSS, добавьте следующую ссылку перед ссылкой на основной плагин:
<!‐‐[if lt IE 9]><script src="EQCSS‐polyfills.js"></script><![endif]‐‐>
Запуск EQCSS
По умолчанию подключаемый модуль EQCSS вычисляет любые стили, которые он находит, после загрузки страницы, а также всякий раз, когда он обнаруживает изменение размера браузера, аналогично медиазапросам. Вы также можете вызвать EQCSS.apply()
вручную с помощью JavaScript для пересчета стилей в любое время, что может быть полезно после обновления контента на странице.
Написание CSS запроса элемента
Плагин EQCSS.js может читать стили несколькими способами. Вы можете включать EQCSS в любые теги style
на HTML-странице. Вы также можете написать EQCSS во внешней таблице стилей CSS.
Если вы хотите, чтобы ваш код на основе EQCSS был отделен от вашего CSS, вы можете загрузить синтаксис EQCSS, используя тег script
с типом text/eqcss
. Вы можете добавить стили, встроенные в такой тег, или создать ссылку на внешнюю таблицу стилей .eqcss
с помощью <script type=“text/eqcss” src=styles.eqcss></script>
, которая загрузит файл с именем styles.eqcss
.
Анатомия запроса элемента
Область применения стиля
Синтаксис в EQCSS для написания запросов к элементам очень похож на форматирование медиазапросов CSS, но вместо @media
мы начинаем запрос с @element
. Единственная другая часть информации, которую нам нужно предоставить, — это по крайней мере один селектор, к которому должны применяться эти стили. Вот как вы могли бы создать новую область для элемента с именем <div class=“widget”>
:
@element '.widget' { }
Элемент между кавычками (в данном случае .widget
) может быть любым допустимым селектором CSS. С помощью этого запроса мы создали новую область для элемента .widget
. Мы еще не включили какие-либо адаптивные условия для области, поэтому любые стили в подобном запросе всегда будут применяться к элементу с областью действия.
Без возможности применять стили к одному или нескольким элементам (а не ко всей странице сразу) мы не смогли бы применять адаптивные запросы только к этим элементам. Как только мы создали эту область на уровне элемента, использование более продвинутых функций синтаксиса EQCSS становится простым — например, метаселектор $parent
— потому что у JavaScript теперь есть контрольная точка, от которой можно вычислять такие вещи, как parentNode
области видимости. элемент. Это огромно!
Правда, CSS уже включает селектор прямого потомка с >
, который позволяет нам выбирать элементы, которые являются прямыми дочерними элементами указанного элемента. Но CSS в настоящее время не предлагает возможности путешествовать в другом направлении вверх по генеалогическому дереву, чтобы выбрать элемент, который содержит другой элемент, который можно было бы назвать его родительским элементом. Спецификация «CSS Selectors Level 4» теперь включает селектор :has()
, который работает аналогично селектору jQuery :has()
, но в настоящее время браузер не поддерживает его. Scoped CSS делает возможным другой вид родительского селектора.
Теперь, когда мы открыли область действия в контексте элемента .widget
, мы можем написать стили с его точки зрения, чтобы настроить его собственный родительский элемент:
@element '.widget' { $parent { /* These styles apply to the parent of .widget */ } }
Еще одним примером специальных селекторов, которые можно использовать в запросе любого элемента, являются селекторы $prev
и $next
, представляющие предыдущий и следующий одноуровневые элементы. Несмотря на то, что CSS может добраться до следующего брата нашего виджета с помощью селектора, такого как .widget + *
, в CSS нет возможности вернуться назад и выбрать элемент, который находится непосредственно перед другим элементом.
<section> <div>This will be the previous item</div> <div class="widget">This is the scoped element</div> <div>This will be the next item</div> </section> <style> @element '.widget' { $prev { /* These styles apply to the element before .widget */ } $next { /* These styles apply to the element after .widget */ } } </style>
Запросы элементов
Разработчики чаще всего используют мультимедийные запросы CSS для адаптивного дизайна, применяя стили в зависимости от высоты или ширины области просмотра браузера. Синтаксис EQCSS поддерживает множество новых типов условий реагирования. Вместо того, чтобы работать только с шириной и высотой браузера, вы можете писать стили, которые применяются к элементам на основе их собственных свойств, например, сколько дочерних элементов он содержит или сколько символов или строк текста находится в элементе в данный момент. .
Добавление этих адаптивных условий к стилям с ограниченной областью действия похоже на то, как вы форматируете медиа-запросы: вы добавляете and (condition: value)
для каждого условия, которое хотите проверить. В этом примере мы проверим, отображаются ли какие-либо элементы .widget
на странице шириной не менее 500 пикселей.
@element '.widget' and (min‐width: 500px) { /* CSS rules here */ }
Синтаксис запроса элемента выглядит следующим образом:
- запрос элемента
@element selector_list [ condition_list ] { css_code }
- список селекторов
" css selector [ "," css selector ]* "
- список условий
and ( query_condition : value ) [ "and (" query condition ":" value ")" ]*
- число значений
number [ css unit ]
- условие запроса
min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
- css единица
% | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax
% | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax
В качестве другого примера, вот как написать запрос, который превращает элемент body
в красный, когда элемент .widget
достигает ширины 500 пикселей:
@element '.widget' and (min‐width: 500px) { body { background: red; } }
Обратите внимание, что элемент body
изменяется, когда .widget
достигает определенной ширины, а не сам элемент .widget
!
Условия запроса элемента
Ниже приведен полный список условий реагирования, которые поддерживает EQCSS.
Условия на основе ширины
- демонстрация
min-width
для пикселей, демонстрация для процентов - демо
max-width
для пикселей, демо для процентов
Условия, основанные на высоте
- демонстрация
min-height
для пикселей, демонстрация для процентов - демонстрация
max-height
для пикселей, демонстрация для процентов
Условия на основе подсчета
- демонстрация
min-characters
для блочных элементов, демонстрация для ввода формы - демонстрация
max-characters
для блочных элементов, демонстрация для ввода формы - демонстрация
min-lines
- демонстрация
max-lines
- демонстрация
min-children
- демонстрация
max-children
Условия на основе прокрутки
- демонстрация
min-scroll-y
- демонстрация
max-scroll-y
- демонстрация
min-scroll-x
- демонстрация
max-scroll-x
Вы можете комбинировать любое количество этих условий в своих запросах элементов для действительно многомерных адаптивных стилей. Это дает вам гораздо больше гибкости и контроля над визуализацией элементов. Например, чтобы уменьшить размер шрифта заголовка, содержащего более 15 символов, когда для отображения доступно менее 600 пикселей, вы можете объединить условия для max‐characters: 15
и max‐width: 600px
:
h1 { font‐size: 24pt; } @element 'h1' and (min‐characters: 16) and (max‐width: 600px) { h1 { font‐size: 20pt; } }
Мета-селекторы
Одна из проблем, с которой вы можете столкнуться, когда начнете писать стили с ограниченной областью действия с адаптивными условиями, заключается в том, что когда на странице находится несколько экземпляров одного и того же селектора, использование этого селектора в запросе элемента приведет к применению стилей ко всем экземплярам этого селектора на странице. страницу, когда любой из них соответствует условиям. Взяв наши примеры .widget
из предыдущих примеров, предположим, что у нас есть два виджета на странице (возможно, один на боковой панели, а другой отображается во всю ширину), и мы написали наш запрос элемента следующим образом:
@element '.widget' and (min‐width: 500px) { .widget h2 { font‐size: 14pt; } }
Это будет означать, что когда любой элемент .widget
на странице имеет ширину не менее 500 пикселей, стиль будет применяться к обоим элементам .widget
. Вероятно, это не то, чего мы хотим в большинстве случаев. Здесь на помощь приходят метаселекторы!
Две части, из которых состоит запрос элемента, — это селектор и условие отклика. Итак, если мы хотим настроить таргетинг только на те элементы на странице, которые одновременно соответствуют и селектору, и условиям отклика, мы можем использовать метаселектор $this
. Мы можем переписать наш последний пример так, чтобы стиль применялся только к элементам .widget
, которые соответствуют условию min‐width: 500px
:
@element '.widget' and (min‐width: 500px) { $this h2 { font‐size: 14pt; } }
Синтаксис EQCSS поддерживает ряд новых селекторов, которых нет в обычном CSS. Вот полный список:
-
$this
демонстрация -
$parent
демонстрация -
$root
демо -
$prev
демонстрация -
$next
демонстрация
Эти селекторы будут работать только в элементном запросе.
Открытие портала между JavaScript и CSS
-
eval(')
демо
Последняя и последняя функция EQCSS — самая дикая из всех: eval(')
. Через этот дверной проем кроется вся мощь JavaScript, доступная из CSS. Хотя JavaScript может применять стили к элементам, в настоящее время ему трудно достичь некоторых вещей, таких как псевдоэлементы :before
и :after
. Но что, если бы CSS мог достичь JavaScript с другой стороны? Вместо того, чтобы JavaScript устанавливал свойства CSS, что, если бы CSS мог знать о JavaScript?
Здесь на помощь приходит eval(')
. Вы можете получить доступ и оценить любой JavaScript, использовать ли значение переменной JavaScript в вашем CSS, чтобы выполнить однострочный код JavaScript (например, eval('new Date().getFullYear()')
), чтобы установить значения о браузере и других элементах, которые может измерять JavaScript (например, eval('innerHeight')
), или запустить функцию JavaScript и использовать возвращаемое ею значение в ваших стилях CSS. Вот пример, который выводит 2016
в элементе <footer>
:
@element 'footer' { $this:after { content: " eval('new Date().getFullYear()')"; } }
Использование $it внутри eval(')
При оценке JavaScript eval(')
также работает в контексте элемента с активной областью видимости, того же элемента, к которому применяются стили для $this
. Вы можете использовать $it
в JavaScript, написанном в eval(')
, в качестве заполнителя для элемента с областью действия, если это поможет вам структурировать код, но если его опустить, он будет работать так же. Например, предположим, что у нас есть div
со словом «привет». Следующий код выведет «hello hello»:
<div>hello</div> <style> @element 'div' { div:before { content: "eval('$it.textContent') "; } } </style>
Здесь $it
относится к div
, потому что это текущий селектор области действия. Вы также можете опустить $it
и написать следующий код, чтобы отобразить то же самое:
@element 'div' { div:before { content: "eval('textContent') "; } }
eval(')
может быть полезен в ситуациях, когда CSS не знает об измерениях или событиях, происходящих на странице после ее загрузки. Например, элементы iframe, используемые для встраивания видео YouTube, имеют заданную ширину и высоту. Хотя вы можете установить ширину auto
в CSS, нет простого способа сохранить правильное соотношение сторон ширины к высоте, когда видео расширяется, чтобы заполнить доступное пространство.
Обычный обходной путь для сохранения отзывчивых соотношений сторон при масштабировании — поместить содержимое, которое должно поддерживать соотношение сторон, в оболочку, а затем добавить отступы к оболочке со значением, основанным на отношении ширины к высоте, которое вы хотите сохранить. Это работает, но требует, чтобы вы заранее знали соотношение сторон всех видео, а также требовали дополнительной HTML-разметки (элемента-оболочки) для каждого видео, которое вы хотите встроить в ответ. Умножьте это на каждый веб-сайт, на котором есть адаптивные видео, и вы поймете, что это много мусора, которого не было бы, если бы CSS был немного умнее.
Возможно, лучший подход к отзывчивым соотношениям сторон заключается в том, чтобы поместить каждое видео в обертку без отступов, а затем написать библиотеку JavaScript, которая вычисляет соотношение сторон каждого найденного видео и применяет правильное количество отступов к каждой оболочке.
Но что, если бы CSS мог получить доступ к этим измерениям напрямую? Мы могли бы не только объединить CSS для всех различных соотношений сторон в одно правило, но и, если бы мы могли оценить его после загрузки страницы, мы могли бы написать одно правило, которое изменит размер любого видео, которое мы когда-либо дадим ему в будущем. И мы могли бы сделать все это без всяких оберток!
Если это кажется слишком хорошим, чтобы быть правдой, проверьте это. Вот как просто написать в EQCSS элементы iframe без обертки, быстро изменяющие их размер:
@element 'iframe' { $this { margin: 0 auto; width: 100%; height: eval('clientWidth/(width/height)'); } }
Здесь width
и height
относятся к атрибутам width=“”
и height=“”
в iframe в HTML. JavaScript может выполнять вычисление (width/height)
, что дает нам соотношение сторон; и чтобы применить его к любой ширине, мы просто разделим текущую ширину элемента iframe на коэффициент.
В нем есть лаконичность и разборчивость CSS и вся мощь JavaScript. Никаких дополнительных оберток не требуется, никаких дополнительных классов и никакого дополнительного CSS.
Однако будьте осторожны с eval(')
. Есть причина, по которой CSS-выражения считались опасными в прошлом, и есть также причина, по которой мы опробовали эту идею. Если вы не будете осторожны с количеством элементов, к которым вы их применяете на странице, или с тем, как часто вы пересчитываете стили, то JavaScript может в конечном итоге запускать вещи в сотни раз больше, чем необходимо. К счастью, EQCSS позволяет нам вызывать EQCSS.apply()
или EQCSS.throttle()
для пересчета стилей вручную, так что у нас больше контроля над обновлением стилей.
Опасная зона!
Другие проблемы могут возникнуть, если вы создаете запросы с конфликтующими условиями или стилями. EQCSS, как и CSS, читается сверху вниз с использованием иерархии специфичности. Хотя CSS является декларативным языком, он содержит некоторые дополнительные функции. Он всего в паре шагов от того, чтобы стать полным по Тьюрингу языком программирования. До сих пор отладка CSS была довольно простой задачей, но EQCSS превращает CSS из простого интерпретируемого декларативного языка в язык динамических таблиц стилей с дополнительным уровнем интерпретации между CSS и браузером. С этой новой территорией приходит множество потенциальных новых ловушек.
Вот пример взаимного цикла в EQCSS, от которого обычные медиа-запросы CSS невосприимчивы:
@element '.widget' and (min‐width: 300px) { $this { width: 200px; } }
Я называю это jekyll: hide;
CSS. Но в дополнение к тому, что один стиль постоянно срабатывает сам, существует также возможность написания нескольких запросов, которые запускают друг друга, в том, что мы называем «двойным инвертированным взаимным циклом», самым неприятным из всех:
@element '.widget' and (min‐width: 400px) { $this { width: 200px; } } @element '.widget' and (max‐width: 300px) { $this { width: 500px; } }
Теоретически этот злосчастный виджет застрял бы в цикле, изменяя размер от 200 до 500 пикселей до скончания века, не имея возможности установить ширину. В подобных случаях EQCSS просто вычисляет правила в том порядке, в котором они оцениваются, награждает победителя и движется дальше. Если бы вы изменили порядок, в котором появляются эти правила, последний стиль всегда выигрывал бы, если бы они имели одинаковую специфичность.
Некоторые люди говорят, что возможность создавать циклы (или даже дважды инвертированные взаимные циклы) является недостатком дизайна, но для того, чтобы предотвратить появление циклов, вам нужно ограничить возможности EQCSS таким образом, чтобы удалить большую часть значение, которое предоставляет синтаксис. С другой стороны, создавать бесконечные циклы в JavaScript очень просто, но это не рассматривается как недостаток языка — это рассматривается как свидетельство его мощи! То же самое и с запросами элементов.
Отладка запросов элементов
В настоящее время отладка запросов к элементам может немного напоминать отладку медиа-запросов до того, как у нас появились такие инструменты, как веб-инспектор, показывающий нам стили по мере их вычисления на странице. На данный момент для отладки и разработки запросов к элементам от разработчика требуется поддерживать ментальную модель того, какое поведение должно происходить. В будущем возможно создание инструментов разработчика с поддержкой EQCSS, но на данный момент инструменты разработчика во всех основных браузерах знают только о стилях, которые EQCSS уже применил к элементам на странице, и не знают о них. условия реагирования, которые отслеживает EQCSS.
Как проектировать с запросами элементов
Самый простой способ использовать запросы элементов — преобразовать существующие дизайны с помощью медиазапросов в запросы элементов, «освободив» элементы и их адаптивные стили от одного макета и облегчив повторное использование этого кода на других страницах и проектах. Следующий медиа-запрос и элементный запрос могут означать одно и то же:
footer a { display: inline-block; } @media (max‐width: 500px) { footer a { display: block; } }
footer a { display: inline-block; } @element 'footer' and (max‐width: 500px) { $this a { display: block; } }
Разница в том, что в исходном примере ссылки нижнего колонтитула остаются как display: block
до тех пор, пока ширина браузера не станет не менее 500 пикселей. Второй пример с использованием запросов к элементам будет выглядеть так же, но только если элемент footer
будет полной ширины.
После освобождения этого стиля от исходного медиа-запроса мы теперь можем поместить нижний колонтитул в контейнер любой ширины и быть уверенными, что, когда нижний колонтитул нуждается в применении адаптивного стиля (т. е. когда он уже, чем 500 пикселей), он будет применяемый.
- Убедитесь, что
EQCSS.js
присутствует в HTML целевого документа. - Замените
@media
на@element
в CSS. - Добавьте селектор CSS в область действия каждого запроса
@element
. - Необязательно: замените вхождения элемента с областью действия на
$this
в запросах элементов.
Если только компонент дизайна, который вы конвертируете, изначально не был предназначен для отображения с использованием полной ширины области просмотра браузера, вам, вероятно, придется настроить точки останова после преобразования в запросы элементов.
Как избежать блокировки
Опыт создания стилей EQCSS аналогичен опыту написания обычного CSS: все ваши любимые свойства и методы CSS по-прежнему присутствуют, только с некоторыми дополнительными функциями, которые помогают им работать вместе по-новому. Поскольку EQCSS выводит стандартный CSS в браузер, любая функция CSS, для которой ваш браузер имеет встроенную поддержку, будет работать при использовании с EQCSS. Если когда-нибудь такие функции, как запросы к элементам и стили с заданной областью, будут указаны в CSS и будут поддерживаться в браузерах, то вы сможете сразу же начать использовать их в своем коде EQCSS, по-прежнему полагаясь на EQCSS для других функций, которые браузер не поддерживает. но поддерживает изначально.
Поскольку вы можете использовать синтаксис EQCSS как непосредственно в CSS, так и в собственном сценарии с типом text/eqcss
, если CSS когда-либо разработает синтаксис для собственных запросов элементов, вы все равно сможете загрузить EQCSS как сценарий и избежать конфликтов. .
Заглядывая вперед, одно из решений, с которым разработчики браузеров сейчас экспериментируют, — это Houdini, которое откроет доступ разработчикам плагинов для расширения CSS новыми способами, например, для добавления поддержки в сам браузер. Когда-нибудь можно будет написать более эффективные плагины, интерпретирующие синтаксис EQCSS и предоставляющие эти функции браузерам более прямым и производительным способом, чем позволяет текущая библиотека JavaScript.
Итак, должны ли мы по-прежнему использовать медиа-запросы?
Да, несмотря на то, что запросы к элементам предоставляют много новых и интересных способов нацеливания на элементы со стилями, медиа-запросы (хотя и ограниченные) всегда будут выполняться в браузере быстрее, чем стили, использующие для вычислений JavaScript. Однако медиа-запросы CSS предназначены не только для стилизации HTML для экранов. Медиа-запросы CSS также поддерживают запросы на печать и другие способы отображения информации веб-сайтами. EQCSS можно использовать в сочетании с медиа-запросами для таких вещей, как стили печати, поэтому нет необходимости отказываться от медиа-запроса только потому, что теперь также можно использовать запросы к элементам!
Проектирование с видением 20 ⁄ 20
Лучшее, что мы можем сделать для будущего CSS, — это как можно больше экспериментировать с этими идеями сегодня. Никакие мозговые штурмы и теоретические размышления об этих функциях не будут столь же полезными, как настоящие попытки их реализовать и использовать, открывая методы, которые делают их полезными и мощными.
Мы надеемся, что помимо предоставления решения для запросов к элементам, EQCSS.js также послужит платформой для других экспериментов по расширению CSS. Если у вас есть идея для нового адаптивного условия, нового свойства CSS или нового селектора для использования в вашем коде, разветвление EQCSS.js и изменение его, чтобы включить вашу идею, может помочь вам в этом с небольшими усилиями.
Modular Design
In designing layouts using element queries, the biggest shift is learning how to stop viewing the DOM from the top down and from the perspective of only the root HTML element, and to start thinking about individual elements on the page from their own perspectives within the document.
The old paradigms of “desktop-first” and “mobile-first” responsive design aren't relevant any longer — the new way of building layouts approaches design “element-first.” Using element queries enables you to work on the individual parts that make up a layout, in isolation from one another, styling them to a greater level of detail. If you are using a modular approach for your back-end code already but have so far been unable to package your CSS with your modules because of the difficulties of styling with media queries alone, then element queries will finally allow you to modularize your styles in the same way.
Thinking Element-First
Element-first design is in the same spirit as the atomic design principle but looks different in practice from how most people have implemented atomic design in the past.
For example, let's say you have some HTML like the following, and the desired responsive behavior can be explained as, “The search input and button are displayed side by side until the form gets too narrow. Then, both the input and the button should be stacked on top of each other and displayed full width.”
<form> <input type=search> <input type=button value=Search> </form>
Desktop-First Approach
In a desktop-first mindset, you would write styles for the desktop layout first and then add responsive support for smaller screens.
input { width: 50%; float: left; } @media (max‐width: 600px) { input { width: 100%; float: none; } }
Mobile-First Approach
In a mobile-first mindset, you would design the mobile view first and add support for the side-by-side view only when the screen is wide enough.
input { width: 100%; } @media (min‐width: 600px) { input { width: 50%; float: left; } }
Element-First Approach
In the first two examples, the media breakpoint was set to 600 pixels, and not because that's how wide the inputs will be when they switch. Chances are, the search input is probably inside at least one parent element that would have margins or padding. So, when the browser is 600 pixels wide, those inputs might be somewhere around 550 or 525 pixels wide on the page. In a desktop-first or mobile-first approach, you're always setting breakpoints based on the layout and how elements show up within it. With an element-first layout, you're saying, “I don't care how wide the browser is. I know that the sweet spot for where I want the inputs to stack is somewhere around 530 pixels wide.” Instead of using a media query to swap that CSS based on the browser's dimensions, with element-first design, we would scope our responsive style to the form
element itself, writing a style like this:
input { width: 100% } @element 'form' and (min‐width: 530px) { $this input { width: 50%; float: left; } }
The code is similar to that of the two previous methods, but now we are free to display this search input anywhere — in a sidebar or full width. We can use it in any layout on any website, and no matter how wide the browser is, when the form itself doesn't have enough room to display the inputs side by side, it will adapt to look its best.
Resources For Getting Started
EQCSS-Enabled Template
<!DOCTYPE html> <html> <head> <meta charset="utf‐8"> <title></title> <style></style> </head> <body> <!‐‐[if lt IE 9]><script src="https://elementqueries.com/EQCSS‐polyfills.min.js"></script><![endif]‐‐> <script src="https://elementqueries.com/EQCSS.min.js"></script> </body> </html>
Демо
- Responsive Aspect Ratio
- Sticky Scroll Header
- Blockquote Style
- Календарь
- Content Demo
- Counting Children Demo
- Date Demo
- Zastrow-style Element Query Demo Demo
- Flyout Demo
- Headline Demo
- Media Player Demo
- Message Style Demo
- Modal Demo
- Nav Demo
- Parent Selector Demo
- Pricing Chart Demo
- Responsive Tables Demo
- Scroll-triggered Blocker Demo
- Signup Form Demo
- Testimonials Block Demo
- Tweet-Counter Demo
- JS Variables Demo
- Responsive Scaling Demo
- Geometric Design Demo
- Responsive Order Form
- Element Query Grid
- JS Functions in CSS
- Responsive Content Waterfall
Дальнейшее чтение
You can find the EQCSS project on GitHub, demos, documentation and articles on the EQCSS website. An ever-growing number of Codepens use EQCSS, and you can create your own pen by forking the batteries-included template that comes hooked up with EQCSS. You can also play with the EQCSS tool that I built to preview if your EQCSS code is working as expected.
Happy hacking!