Позвольте мне начать с того, что, несмотря на заголовок, эта статья не о том, чтобы покончить с медиа-запросами или сбоем медиа-запросов. Медиа-запросы невероятно полезны, и я использую их все время для самых разных вещей. Тем не менее, они не решают все наши адаптивные проблемы дизайна.
Часто желательно вносить изменения в расположение элементов на основе размеров их контейнера, а не области просмотра. Для решения этой проблемы родилась концепция элементарных запросов . Тем не менее, запросы к элементам пока не очень важны , и Мат Маркиз продемонстрировал некоторые проблемы с концепцией и сформулировал их как контейнерные запросы .
Но это еще не вещь , к сожалению.
Надеюсь, что они пройдут один день, но пока что я представил здесь несколько трюков и приемов, которые можно использовать для решения некоторых проблем, которые контейнерные запросы однажды решат.
Flexbox с flex-wrap
Flex-wrap
может решить множество проблем, когда дело доходит до реагирования на размеры контейнера. Например, обычно требуется, чтобы два элемента появлялись рядом, если места достаточно, но чтобы один располагался поверх другого, если его нет. В следующей демонстрации мы можем увидеть это поведение в действии:
Здесь нет причудливых трюков, просто flexbox с flex-wrap
но он работает без проблем. Конечно, Flexbox можно использовать не только для создания двух столбцов, но и для простой демонстрации. Основные части этой техники просто:
<div class="container"> <div class="img">...</div> <div class="content">...</div> </div> ...
.container { display: flex; flex-wrap: wrap; flex-direction: row; } .container .content, .container .img { flex: 1 0 12em; /* Change 12em to your breakpoint. */ }
Понимание flex-grow
, flex-shrink
и flex-basis
является важной частью правильного решения этой проблемы; Я нахожу этот наконечник flexbox от Zoe Gillenwater действительно полезным для понимания взаимосвязи между этими свойствами.
«Потрясающая Техника Четыре»
Использование width
, min-width
, max-width
и calc
для создания переключателя ширины на основе точки останова, получившего название «Техника Fab Four», был детищем мозга Реми Парментье . Первоначально созданный для помощи с адаптивными электронными письмами, он может легко использоваться для обычных веб-страниц и действительно открыл некоторые новые возможности в создании самоадаптируемых модулей, как продемонстрировал Тьерри . Например,
{ min-width: 50%; width: calc((25em - 100%) * 1000); max-width: 100%; /* Change 25em to your breakpoint. */ }
Это работает, потому что когда width
является процентом, это процент от ширины контейнера элемента. Затем функция calc
сравнивает это значение с требуемой точкой останова и затем генерирует действительно большое положительное число (если ширина меньше, чем точка останова), или действительно большое отрицательное число (если ширина больше, чем точка останова), или ноль, если есть точное совпадение. Большая положительная ширина ограничена max-width
а большая отрицательная или нулевая ширина устанавливается равной значению min-width
.
Итак, в приведенном выше примере мы установили 25em
останова 25em
. Это разрешает до 400px
если размер шрифта составляет 16px
. Если 400px
контейнера составляет 400px
или выше (другими словами, равен или превышает 400px
останова), ширина преобразуется в 0 или большое отрицательное число:
(400 - 400 = 0) * 1000 = 0
или (400 - 401 = -1) * 1000 = -1000
С такими значениями, min-width
вступает в силу, поэтому результирующая ширина элемента в примере выше будет 50%
. Однако, если 399px
контейнера составляет 399px
или ниже (другими словами, меньше, чем точка останова), ширина преобразуется в большое положительное число:
(400 - 399 = 1) * 1000 = 1000
В этом случае max-width
вступает в силу, и результирующая ширина составляет 100%
. Следующая диаграмма должна помочь визуализировать этот процесс:
Следующие четыре демонстрации все по-разному используют эту технику для переключения ширины элемента в ответ на ширину его контейнера.
Плавающее изображение — полная ширина / частичная ширина
В этой демонстрации я использовал «Fab Four Technique» в сочетании с float
чтобы переключать изображение между полной и полушириной в зависимости от ширины контейнера:
Подобно flexbox
примеру flexbox
, этот метод позволяет элементам переключаться между сложенным устройством на небольшой ширине и плавающим / обернутым устройством, если есть достаточно места.
Плавающее изображение — видимое / скрытое
Адаптированный от предыдущего метода, я инвертировал результат вычисления и удалил объявление min-width
чтобы создать переключатель включения / выключения. Это полезно для сокрытия декоративных элементов в небольших контейнерах, где они могут занимать ценное пространство:
И для ясности
{ /* Removed min-width since we want the width to be zero at this point and negative widths are treated as zero */ /* Inverted the multiplier: */ width: calc((25em - 100%) * -1000); max-width: 100%; /* Change 25em to your breakpoint. */ }
Текст и изображение — наложены / сложены
Аналогично предыдущим методам, я использовал дополнительный div
для вытягивания текста поверх изображения, но там, где изображение слишком маленькое и в противном случае было бы скрыто текстом, вместо этого текст защелкивается под ним. Эта часть техники немного сложна, поэтому я попытаюсь прояснить ее.
.pull { /* Pull the text up over the image by this much: */ margin-bottom: -10em; }
Здесь отрицательное поле вытягивает последующее содержимое вверх, чтобы оно перекрывало изображение. Тем не менее, мы должны отключить это, когда ширина контейнера пересекает точку останова, но так как нет свойства min/max-margin
, мы не можем использовать здесь «Fab Four Technique» для достижения этой цели.
Однако, по счастливой случайности, если для отступа задан процент, это процент от ширины контейнера, а padding-top
и -bottom
влияют на высоту элемента. Обладая этими знаниями, мы можем использовать calc
для создания значения padding-bottom, которое переключается между нулем или «действительно большим» в зависимости от ширины контейнера:
padding-bottom: calc((30em - 100%) * 1000);
Мы не можем применить это к .pull
div напрямую, так как нет свойства min/max-padding
для ограничения этих значений; решение состоит в том, чтобы поместить переключатель padding в .pull
чтобы вызвать изменение высоты, и использовать max-height
.pull
элемента .pull
чтобы ограничить высоту тем же значением, что и отрицательное поле, чтобы мы эффективно отрицали это поле.
.pull { /* Pull the text up over the image by this much: */ margin-bottom: -10em; /* Don't allow this container to be larger than the same amount: */ max-height: 10em; /* and hide any overflow, just to be on the safe side: */ overflow: hidden; } .pull::before { content: ""; display: block; padding-bottom: calc((30em - 100%) * 1000); /* Change 30em to your breakpoint */ }
Эффект наложения градиента достигается путем применения переключателя «вкл / выкл», как описано ранее, к псевдоэлементу, к которому был применен градиент фона:
.image::after { content: ""; display: block; position: absolute; left: 0; top: 0; /* Gradient to make the text more legible: */ background-image: linear-gradient(to bottom, rgba(0,20,30,0) 0%,rgba(0,20,30,0) 50%,rgba(0,20,30,1) 100%); /* Extra .5% to prevent bleed due to rounding issues: */ height: 100.5%; /* Toggle gradient overlay at the same breakpoint as the 'pull': */ width: calc((30em - 100%) * -1000); /* Change 30em to your breakpoint */ max-width: 100%; }
Усеченный список
Последняя техника, которую я разработал, была вдохновлена версией шаблона Priority Plus на приемах CSS . Хотя и не такой сложный, как этот, он не требует никакого JavaScript:
Опять же, здесь используется «техника Fab Four», только на этот раз в зависимости от высоты контейнера, а не от ширины.
<div class="outer"> <div class="inner"> <div class="item">...</div> ... <div class="control">...</div> </div> </div> ...
.outer { height: 2.25em; overflow: hidden; } .outer:target { height: auto; }
Внешний контейнер имеет фиксированную высоту и скрывает любое переполнение, если элемент не является :target
-ed.
.inner { display: flex; flex-wrap: wrap; }
Внутренний контейнер представляет собой гибкий контейнер с .outer
flex-wrap
, поэтому он будет увеличиваться по высоте при .outer
элементов, но элементы ниже первой строки будут скрыты .outer
контейнера .outer
overflow:hidden
, создавая эффект усечения.
.control { height: calc((2.25em - 100%) * -1000); max-height: 2.25em; } :target .control--open { display: none; } :target .control--close { display: block; }
Элементы управления « больше / меньше » становятся видимыми, только если высота контейнера превышает точку останова (которая совпадает с высотой основных ссылок), а состояние :target
определяет, какой элемент управления является видимым.
Выравнивание текста в CSS
Выравнивание текста по центру или слева в зависимости от свободного места в контейнере по сравнению с длиной текста — действительно полезная вещь, которую можно сделать. Эта техника, созданная Виджаем Шармой, облегчает достижение этой цели.
Бонус: Flex-grow 9999 Hack
Отличным трюком от Joren Van Hee, который отлично вписывается в эту коллекцию, является хакерский флекс-9999 .
Хвала: смотри, нет медиа-запросов Василис ван Гемерт
Выступление Василиса ван Гемерта. Послушайте, ни один медиазапрос не дал мне стимула исследовать адаптивный дизайн без медиазапросов, что, в свою очередь, побудило меня написать эту статью. Его выступление заслуживает того, чтобы его посмотреть, и включает в себя некоторые другие идеи, которые, хотя и являются действительно полезными, не совсем вписываются в тему того, что я здесь представил.
Вывод
Есть много вещей, которые нельзя сделать без запросов элемента / контейнера. Такие вещи, как значения цвета, размер шрифта и высота строки, границы и тени, поля и отступы — список длинный. Корректировка всех этих вещей в ответ на состояние родительского контейнера должна быть возможной с помощью запросов элементов / контейнеров, но, увы, в ближайшее время, похоже, нет никаких признаков того, что они станут реальностью. Тем не менее, я надеюсь, что в то же время некоторые из представленных здесь материалов будут вам полезны.
Если вы хотите знать, на что может быть похоже проектирование с использованием Element Queries, написание сегодняшних запросов к элементам с использованием EQCSS поможет вам начать.
Если вы хотите узнать больше о запросах элемента / контейнера, вот несколько полезных ресурсов:
- EQCSS — расширение CSS для запросов элементов и не только
- Почему элемент запрашивает материю
- Контейнерные запросы: еще раз к прорыву
- В поисках Святого Грааля: как я закончил с запросами на элементы и как их можно использовать сегодня
- Варианты использования и требования для черновика редактора запросов элементов
- Варианты использования для запросов контейнера
- Как определение стиля работает с запросами к элементам