Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Перевод статьи Ollie Williams "Using Performant Next-Gen Images in CSS with image-set"
CSS функция image-set
поддерживается в браузерах на основе Chromium с 2012 года, а Safari начиная с версии 6. Недавно поддержка появилась в Firefox 88. Давайте углубимся в эту тему и посмотрим, что мы можем и чего не можем делать с помощью функции image-set ()
Несколько расширений одного и того же изображения
Вот что говорится в спецификации о функции image-set ():
Обеспечение наиболее подходящего разрешения изображения для устройства пользователя может быть сложной задачей. В идеале изображения должны иметь то же разрешение, что и устройство на котором они просматриваются. Однако, есть факторы которые могут повлиять на то, какое изображение отправить на устройство. Например, если у пользователя медленный интернет, вероятнее всего он захочет получить изображение с низким разрешением и не ждать загрузки большого изображения.
По сути, это CSS фон, эквивалентный HTML атрибуту srcset
для тегов img
. Используя image-set ()
, мы можем выбрать несколько расширений для изображения и доверится браузеру, чтобы он выбрал наиболее подходящее расширение. Это можно использовать для указания значения для трех различных CSS свойств: content
, cursor
и, самое полезное, background-image
.hero {
background-image: image-set("platypus.png" 1x, "platypus-2x.png" 2x);
}
1x используется для определения изображения с маленьким разрешением, а 2x используется для определения изображения с большим разрешением. x - расшифровывается как dppx, что означает количество точек на пиксель.
Chrome / Edge / Opera / Samsung Internet в настоящее время работают только с префиксом -webkit-. Если вы используете Autoprefixer, то он подставит этот префикс за вас. В Safari функция image-set
не требует префикса -webkit-, но использует старый синтаксис, который требует чтобы функция url()
указывала путь к изображению.
.hero {
/* Fallback */
background-image: url("platypus.png");
/* Chrome/Edge/Opera/Samsung, Safari will fallback to this as well */
background-image: -webkit-image-set(url("platypus.png") 1x, url("platypus-2x.png") 2x);
/* Standard use */
background-image: image-set("platypus.png" 1x, "platypus-2x.png" 2x);
}
Теперь пользователи дорогих устройств увидят сверхчеткое изображение.
Также производительность будет улучшена для пользователей с медленным интернетом или с более дешевыми экранами, поскольку их браузер автоматически будет запрашивать изображение с более низким разрешением. Если вы хотите быть уверены, что изображение с высоким разрешением используется на мощных устройствах, даже при медленном соединении с интернетом , вы можете воспользоваться медиа-запрос min-resolution
вместо image-set().
Подробнее о том как показывать четкие изображения на экранах с высокой плотностью пикселей, можно прочитать в недавнем посте Джейка Арчибальда в его блоге.
Всё это очень круто, но что мне действительно нужно, так это иметь возможность использовать новые форматы изображений в CSS, и при этом поддерживать старые браузеры...
Новые форматы изображений
Safari 14 поддерживает webp. А это значит, что теперь webp поддерживается везде (кроме IE). Главное преимущество webp в том, что он весит меньше чем (но при этом имеет такое же качество) JPG, PNG, или GIF.
Также, появляется всё больше и больше новых форматов изображений. Например, изображения в формате AVIF имеют невероятно маленький размер. Chrome, Opera и Samsung Internet уже поддерживают этот формат. В Firefox AVIF доступен за флагом. Этот формат изображений пока не поддерживается многими дизайн инструментами, но вы уже можете конвертировать изображения в AVIF формат с помощью приложения Squoosh, созданного командой Google. WebP 2, HEIF и JPEG XL также, в конечном итоге появятся в браузерах. Все это довольно интересно, но мы хотим чтобы браузеры, которые не поддерживают эти новые форматы, получали изображения в другом формате. К счастью, у image-set()
есть для этого синтаксис.
Использование новых форматов изображений путем указания типа
HTML уже много лет поддерживает тег<picture>
.
<picture>
<source srcset="./kitten.avif" type="image/avif">
<img src="./kitten.jpg" alt="a small kitten">
</picture>
Функция image-set
предоставляет CSS эквивалент, позволяющий использовать современные форматы изображений, указав MIME-тип изображения:
.div1 {
background-image: image-set(
"kitten.avif" type("image/avif"),
"kitten.jpg" type("image/jpeg")
);
}
Если браузер не поддерживает AVIF, он проигнорирует этот формат и загрузит только второе указанное вами изображение. Если AVIF поддерживается, резервное изображение игнорируется.
В пример выше мы использовали изображение AVIF и добавили JPEG в качестве запасного варианта, но запасным вариантом может быть любой широко поддерживаемый формат изображения. Вот пример использования PNG.
.div2 {
background-image: image-set(
"puppy.webp" type("image/webp"),
"puppy.png" type("image/png")
);
}
В Chromium и Safari указание типа пока не поддерживается. Это значит, что вы можете использовать функцию image-set
только для указания разрешений широко поддерживаемых форматов изображений, но не для добавления обратной совместимости при использовании WebP или AVIF в этих браузерах.
.div2 {
background-image: image-set(
"puppy.webp" type("image/webp") 1x,
"puppy2x.webp" type("image/webp") 2x,
"puppy.png" type("image/png") 1x,
"puppy2x.png" type("image/png") 2x
);
}
Вместо этого используйте <picture> для фона
Возможно, вам вообще не нужно фоновое изображение. Если вы хотите использовать современные форматы изображений, вы можете использовать тег <picture>
, который лучше поддерживается браузерами. Если вы установите для изображения position: absolute
, поверх него легко можно будет отобразить другие элементы.