За пределами медиа-запросов: новые функции для адаптивного дизайна

За пределами медиа-запросов: новые функции для адаптивного дизайна

От автора: помимо использования медиа-запросов и современных макетов CSS, таких как flexbox и grid, для создания адаптивных веб-сайтов, есть некоторые упускаемые из виду вещи, которые мы можем сделать для создания адаптивных сайтов. В этой статье мы рассмотрим ряд инструментов (связанных с HTML и CSS), которые у нас есть, от адаптивных изображений до относительно новых функций CSS, которые работают нативно, независимо от того, используем мы медиа-запросы или нет.

Фактически, медиа-запросы при использовании с этими функциями становятся скорее дополнением, чем основным подходом. Посмотрим, как это работает.

Действительно адаптивные изображения

Помните, когда мы могли просто задать для изображения width: 100% и закончить на этом? Это, конечно, по-прежнему работает и делает изображения гибкими, но есть ряд недостатков, наиболее заметные из которых:

Изображение может сжаться до такой степени, что потеряет фокус.

Меньшие устройства по-прежнему загружают полноразмерное изображение.

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

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

HTML предлагает элемент <picture>, который позволяет нам указать точный ресурс изображения, который будет отображаться на основе добавляемого нами медиа-запроса. Как описано ранее, вместо того, чтобы отправлять одно изображение (обычно это большая версия с высоким разрешением) на все размеры экрана и масштабировать его до ширины области просмотра, мы указываем набор изображений, которые будут использоваться в определенных ситуациях.

<picture> <source media="(max-width:1000px)" srcset="picture-lg.png"> <source media="(max-width:600px)" srcset="picture-mid.png"> <source media="(max-width:400px)" srcset="picture-sm.png"> <img src="picture.png" alt="picture"">
</picture>

В этом примере picture.png — полноразмерное изображение. Затем мы определяем следующую по величине версию изображения picture-lg.png, и размер уменьшается в порядке убывания до самой маленькой версии picture-sm.png. Обратите внимание, что мы по-прежнему используем в этом подходе медиа-запросы, но именно сам элемент управляет адаптивным поведением, а не в CSS определяются контрольные точки.

Медиа-запросы добавляются в соответствии с масштабом изображения:

Для экранов размером 1000 пикселей и выше доставляется picture.png.

Для экранов размером от 601 до 999 пикселей доставляется picture-lg.png.

Для экранов размером от 401 до 600 пикселей доставляется picture-sm.png.

Все, что меньше 400 пикселей, получает picture-sm.png.

Интересно, что мы также можем пометить каждое изображение по плотности пикселей — 1x, 2x, 3x и так далее — после URL-адреса. Это работает, если мы создали разные изображения, пропорциональные друг другу (что мы и сделали). Это позволяет браузеру определять, какую версию загружать, на основе плотности пикселей экрана в дополнение к размеру области просмотра. Но обратите внимание, сколько изображений мы в итоге определяем:

<picture> <source media="(max-width:1000px)" srcset="picture-lg_1x.png 1x, picture-lg_2x.png 2x, picture-lg_3x.png 3x"> <source media="(max-width:600px)" srcset="picture-mid_1x.png 1x, picture-mid_2x.png 2x, picture-mid_3x.png 3x"> <source media="(max-width:400px)" srcset="picture-small_1x.png 1x, picture-small_2x.png 2x, picture-small_1x.png 3x"> <img src="picture.png" alt="picture"">
</picture>

Давайте отдельно рассмотрим два тега, вложенные внутрь элемента picture: source и img.

Браузер будет искать первый элемент source, в котором медиа-запрос соответствует ширине текущего окна просмотра, а затем отобразит соответствующее изображение (указанное в атрибуте srcset). Элемент img необходим в качестве последнего дочернего элемента picture, в качестве запасного варианта, если ни один из исходных источников не соответствует.

За пределами медиа-запросов: новые функции для адаптивного дизайна

Мы также можем использовать плотность изображения для обработки адаптивных изображений с помощью только элемента img, используя атрибут srcset:

<img srcset=" flower4x.png 4x, flower3x.png 3x, flower2x.png 2x, flower1x.png 1x " src="flower-fallback.jpg"
>

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

@media only screen and (max-width: 600px) { /* Style stuff */
}

Теперь у нас есть:

@media only screen and (min-resolution: 192dpi) { /* Style stuff */
}

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

body { background-image : picture-md.png; /* the default image */
}


@media only screen and (min-resolution: 192dpi) { body { background-image : picture-lg.png; /* higher resolution */ }
}

Что дает нам picture, так это возможность напрямую управлять изображениями. И, в соответствии с этой идеей, мы можем использовать функции CSS, такие как свойство object-fit, которое при использовании с object-position позволяет обрезать изображения для лучшей фокусировки, сохраняя при этом соотношение сторон изображения.

Итак, чтобы изменить фокус изображения:

@media only screen and (min-resolution: 192dpi) { body { background-image : picture-lg.png; object-fit: cover; object-position: 100% 150%; /* moves focus toward the middle-right */ }
}

Установка минимального и максимального значений в CSS

Функция min() определяет абсолютный наименьший размер, до которого элемент может сжиматься. Эта функция оказывается действительно полезной с точки зрения дополнения размеров текста для правильного масштабирования для разных размеров экрана, например, чтобы размер стандартного шрифта никогда не опускался ниже порога разборчивой читаемости:

html { font-size: min(1rem, 22px); /* Stays between 16px and 22px */
}

min() принимает два значения, и они могут быть относительными, процентными или фиксированными. В этом примере мы указываем браузеру, чтобы элемент с классом .box никогда не имел ширину меньше 45% или 600 пикселей, в зависимости от того, что меньше, в соответствии с шириной области просмотра:

.box { width : min(45%, 600px)
}

Если 45% вычисляет значение меньше 600 пикселей, браузер использует в качестве ширины 45%. И наоборот, если 45% вычисляет значение больше 600 пикселей, тогда 600 пикселей будет использоваться для ширины элемента.

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

.box { width : max(60%, 600px)
}

Если 60% вычисляет значение больше 600 пикселей, браузер использует 60% в качестве ширины. С другой стороны, если 60% вычисляет значение меньше 600 пикселей, тогда 600 пикселей будет использоваться в качестве ширины элемента.

Значения clamp

Многие из нас уже давно требуют clamp(), и на самом деле у нас уже есть широкая поддержка во всех современных браузерах (извините, Internet Explorer). clamp() — это сочетание функций min() и max(), принимающая три параметра:

минимальное значение,

предпочтительное значение и

максимальное значение

Например:

.box { font-size : clamp(1rem, 40px, 4rem)
}

Браузер установит для шрифта 1rem, пока вычисленное значение 1rem не станет больше 40 пикселей. А когда вычисленное значение больше 40 пикселей? Да, браузер перестанет увеличивать размер после достижения 4rem. Вы можете увидеть, как с помощью clip() можно сделать элементы гибкими, не обращаясь к медиа-запросам.

Работа с адаптивными единицами измерения

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

В CSS можно определить размеры или длины элементов с использованием различных единиц измерения, а наиболее используемые единицы измерения — это px, em, rem, %, vw и vh. Хотя есть еще несколько единиц, которые используются не так часто. Нас интересует то, что px можно считать абсолютной единицей, а все остальное — относительными.

Абсолютные единицы измерения

Пиксель (px) считается абсолютной единицей в основном потому, что он фиксирован и не изменяется в зависимости от измерения любого другого элемента. Его можно рассматривать как базовую или корневую единицу, которую используют некоторые другие относительные единицы. Попытка использовать пиксели для адаптивного поведения может натолкнуться на проблемы, потому что они фиксированы. Но они хороши, если у вас есть элементы, размер которых вообще не нужно изменять.

Относительные единицы измерения

Относительные единицы, например, %, em и rem, лучше подходят для адаптивного дизайна в основном из-за их способности масштабироваться для разных размеров экрана.

vw — относительно ширины области просмотра

vh — относительно высоты области просмотра

rem — относительно элемента root (<html>) (размер шрифта по умолчанию обычно составляет 16 пикселей)

em — относительно родительского элемента

% — относительно родительского элемента

Опять же, размер шрифта по умолчанию для большинства браузеров — это 16px, и это то, что единицы rem используют для генерации вычисленных значений. Итак, если пользователь настраивает размер шрифта в браузере, все на странице правильно масштабируется в зависимости от размера корневого элемента. Например, при работе с корневым набором 16px, указанное вами число будет умножено на размер по умолчанию. Например:

.8rem = 12.8px (.8 * 16)
1rem = 16px (1 * 16)
2rem = 32px (2 * 16)

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

Например, если вы в CSS изменили размер шрифта на 10px, то рассчитанные размеры в конечном итоге будут такими:

html { font-size : 10px;
}

Примечание: это также относится к процентам %. Например:

1rem = 10px (1 * 10)
2rem = 20px (2 * 10)
.5rem = 5px (.5 * 10)

А в чем разница между rem и em? В том, что единица измерения использует в качестве базового элемента. Rem вычисляет значения, используя размер шрифта элемента root (<html>), тогда как элемент, объявляющий значения em, ссылается на размер шрифта родительского элемента, который его содержит. Если размер указанного родительского элемента отличается от размера корневого элемента (например, размер для родительского элемента составляет 18 пикселей, а размер для корневого элемента — 16 пикселей), тогда em и rem будут генерировать разные вычисленные значения. Это дает нам более точный контроль над тем, как наши элементы реагируют в разных адаптивных контекстах.

Vh является аббревиатурой от высоты области просмотра или высоты видимого экрана. 100vh представляют 100% высоты области просмотра (в зависимости от устройства). В том же ключе, vw означает ширину области просмотра, означающую ширину видимого экрана устройства, и 100vw буквально представляет 100% ширины области просмотра.

Выходя за рамки медиа-запросов

Вы улавливаете суть? Мы только что рассмотрели ряд действительно мощных и относительно новых функций HTML и CSS, которые дают нам дополнительные (и, возможно, более эффективные) способы создания адаптивности. Это не значит, что эти новомодные техники заменяют то, что мы делали все это время. Это просто дополнительные инструменты в нашем наборе инструментов разработчика, которые дают нам больший контроль, чтобы определять, как элементы ведут себя в разных контекстах. Независимо от того, управляют ли они размерами шрифтов, разрешениями, шириной, точками фокусировки или чем-то другим, у нас есть более точный контроль взаимодействия с пользователем, чем когда-либо прежде.

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

Автор: David Atanda

Источник: https://css-tricks.com

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