Адаптивные CSS шаблоны без медиа запросов

Адаптивные CSS шаблоны без медиа запросов

От автора: несмотря на заголовок, эта статья не посвящена каким-либо попыткам избавиться от медиа запросов. Медиа запросы невероятно полезны, я использую их везде. Однако они не решают все наши проблемы с адаптивным дизайном.

Зачастую лучше вносить изменения в расположение элементов по размерам их контейнера, а не вьюпорта. Для решения этой проблемы родилась концепция элементных запросов. И все же в концепции элементных запросов есть изьяны, и Mat Marquis продемонстрировал их и переформулировал концепцию в контейнерные запросы. К сожалению, и эта концепция до сих пор не идеальна.

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

Flexbox с flex-wrap

Flex-wrap может решить массу проблем, касающихся ответа на размеры контейнера. Например, часто нужно расположить два элемента рядом, если есть место. Если места недостаточно, элементы должны располагаться один над другим. В демо ниже показан этот пример в действии:

Никаких трюков, просто flexbox и flex-wrap, и все работает. С помощью flexbox можно делать много чего. Можно не просто создавать две колонки, но я не стал усложнять демо. Основные моменты техники очень просты:

Для правильной работы важно понимать, что из себя представляют свойства flex-grow, flex-shrink и flex-basis. У Zoe Gillenwater есть очень полезный совет по flexbox, помогающий понять связь между этими свойствами.

Техника великолепной четверки

Переключение ширины по брейкпоинтам с помощью свойств width, min-width, max-width и calc (или «техника великолепной четверки») было детищем Rémi Parmentier. Изначально созданная для адаптивных электронных писем, эта техника может легко использоваться и на обычных веб-страницах. Как показал Thierry, эта техника открыла новые возможности в создании самоадаптирующихся модулей. Например:

Техника работает, так как если width задана в процентах, проценты считаются от ширины контейнера элемента. Функция calc сравнивает это значение с желаемым брейкпоинтом и генерирует очень большое положительное число (если ширина меньше брейкпоинта) или очень отрицательное число (если ширина больше брейкпоинта), или ноль, если ширина совпадает. Большое положительное число записывается в max-width, большое отрицательное или ноль записываются в min-width.

В примере выше мы задали брейкпоинт 25em. Если шрифт равен 16px, это значение переводится в 400px. Если контейнер 400px или выше (т.е. равен или больше брейкпоинта), ширина равна нулю или большому отрицательному числу:

(400 — 400 = 0) * 1000 = 0 or (400 — 401 = -1) * 1000 = -1000

С такими значениями у нас срабатывает min-width, и результирующая ширина элемента в примере выше будет равна 50%. Однако если контейнер 399px и ниже (т.е. меньше брейкпоинта), ширина равна большому положительному числу:

(400 — 399 = 1) * 1000 = 1000

В этом случае срабатывает max-width, и результирующая ширина будет равна 100%. Рисунок ниже должен помочь визуализировать этот процесс:

Адаптивные CSS шаблоны без медиа запросов

Четыре демо ниже по-разному используют эту технику для переключения ширины элемента в ответ на ширину контейнера.

Изображение с обтеканием – полная ширина/частичная ширина

В этом демо я использовал технику великолепной четверки вместе со свойством float для переключения изображения с полной ширины на половину в зависимости от ширины контейнера:

Как и в примере с flexbox выше, эта техника позволяет элементам переключаться между одноколоночным видом при маленькой ширине и видом с обтеканием при достаточной ширине.

Изображение с обтеканием – видимый/скрытый

Эта техника адаптирована с предыдущей. Здесь инвертирован результат вычислений, и удалено свойство min-width, что создает переключатель вкл/выкл. Удобно для скрытия декоративных элементов в маленьких контейнерах, ведь они могут занимать ценное пространство:

И для ясности:

Текст и изображение – наложение/стек

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

Отрицательный margin располагает контент поверх изображения. Однако когда ширина контейнера пересекает брейкпоинт, нам необходимо отключать это свойство. Но у нас нет свойств min/max-margin, поэтому мы не можем использовать технику великолепной четверки.

Как бы то ни было, если padding задан в процентах, то это проценты от ширины контейнера, и padding-top и –bottom повлияют на высоту элемента. Зная это, мы можем использовать calc для создания padding-bottom, которое на основе ширины контейнера будет переключаться между нулем и очень большим значением:

padding-bottom: calc((30em — 100%) * 1000);

Напрямую к .pull мы это применить не можем, у нас нет свойств min/max-padding, чтобы ограничить эти значения. Выход – поместить переключатель padding’а на псевдоэлемент для принудительной смены высоты, а также использовать max-height на .pull и ограничивать высоту на значение отрицательного margin’а. Так мы эффективно компенсируем этот margin.

Эффект градиента перекрытия реализован с помощью переключателя вкл/выкл, как описано ранее:

Усечение списка

Последняя разработанная мной техника была вдохновлена шаблоном Priority Plus с сайта CSS tricks. Техника довольно простая и не требует JS:

Здесь опять используется техника великолепной четверки, только на этот раз на высоте контейнера, а не ширине.

Высота внешнего контейнера фиксирована и прячет любые заступы, только если это не :target.

Внутренний контейнер представляет собой флекс-контейнер со свойством flex-wrap. Когда элементы будут перепрыгивать на строки ниже, высота контейнера будет увеличиваться. Элементы ниже первой сроки прячутся свойством overflow:hidden на контейнере .outer, создавая эффект усечения.

Элементы more/less видны только, если высота контейнера превышает брейкпоинт (который равен высоте главных ссылок). Состояние :target определяет, какой элемент будет видимым.

Умное выравнивание текста в CSS

Очень удобно выравнивать текст по центру или по левому краю в зависимости от доступного пространства в контейнере по сравнение с длиной текста. Техника за авторством Vijay Sharma делает это очень легко.

Бонус: хак flex-grow 9999

В нашу коллекцию отлично подходит трюк Joren Van Hee – хак flex-grow 9999.

Смотрите, никаких медиа запросов от Vasilis van Gemert

Выступление Vasilis van Gemert смотрите, никаких медиа запросов придало мне импульс на изучение адаптивного дизайна без медиа запросов, что, в свою очередь, привело к написанию этой статьи. Стоит посмотреть его выступление, оно включает в себя парочку других идей, которые, хотя и полезны, не совсем вписываются в тему того, что я здесь представил.

Заключение

Много чего невозможно выполнить без элементных/контейнерных запросов. Список очень длинный, это цвета, размер шрифта, высота строки, рамки и тени, margin и padding. Все это должно настраиваться с помощью элементных/контейнерных запросов в ответ на состояние родительского контейнера, но, увы, в ближайшее время нет никаких признаков, что это воплотится в реальность. Тем не менее, надеюсь, что когда-нибудь что-либо из написанного мной вам пригодится.

Автор: Andy Kirk

Источник: //www.sitepoint.com/

Редакция: Команда webformyself.

Метки:

Похожие статьи:

Комментарии Вконтакте: