- PVSM.RU - https://www.pvsm.ru -
В девелоперских сборках браузеров Chrome, Firefox и Opera появилась поддержка нового элемета picture
, призванного решить ряд проблем возникающих при разработке адаптивных дизайнов. Давайте рассмотрим его подробнее.
Новый элемент picture
, решает следующие задачи, встающие перед разработчиком адаптивных веб-приложений (я воспользуюсь классификацией, предложенной pepelsbey [1] на одной из недавних конференций по фронтенду):
Сложив первые буквы, получаем мнемонику РАФК
Условно, расширенный синтаксис нового элемента выглядит так
<picture>
<source
srcset="<список URL c дескрипторами>"
[sizes="<ваши размеры в зависимости от раскладки>"]
[media="<медиавыражение>"]
[type="<mime/type>"]
>
<source ...>
...
<img src="image.jpg" alt="My image"
[srcset="<список URL с дескрипторами>"]
[sizes="<ваши размеры в зависимости от раскладки>"]>
</picture>
Элемент picture
не рендерит никакой контент, а лишь является справочным контейнером для вложенного в него тега img
.
Поэтому для большинства задач хватит сокращенной записи, совсем без использования picture
<img src="image.jpg" alt="My image"
[srcset="<список URL с дескрипторами>"]
[sizes="<ваши размеры в зависимости от раскладки>"]>
Давайте рассмотрим как решаются вышеозначенные проблемы с помощью нового элемента. Все файлы примеров можно найти в этом репозитории github.com/fetis/picture [2]
Для тестирования примеров из данной статьи на десктопе вам понадобятся либо Firefox Nighlty [3] (поддержка picture
включается настройкой dom.image.picture.enable
в about:config), либо Chrome Canary [4], либо Opera Developer [5]. На мобильном устройстве новый элемент можно протестировать в Chrome Beta [6]
У нас есть изображение 400х300 пкс, которое мы хотим также красиво показывать при двукратной и трехкратной плотности пикселей. Для этого готовим еще 2 картинки, размерами 800x600 и 1200х900 и пишем следующий код
<img
src="images/400.jpg"
srcset="images/800.jpg 2x, images/1200.jpg 3x"
width="400" height="300"
>
2x
и 3x
это дескрипторы плотностей пикселей, они говорят браузеру, что вот эти картинки были подготовлены для вот этой плотности, если хочешь, можешь использовать. Обратите внимание, они не заставляют бразуер использовать эти картинки, а только подсказывают ему. Окончательное решение остается за ним в зависимости от других условий, например, текущего соединения.
Атрибут src
в данном случае служит источником картинки для плотности < 2 и фолбеком на случай, если браузер не поддерживает новый элемент.
Представим раскладку, в которой есть единственная контрольная точка (breakpoint) 700пкс. При размере вьюпорта более 700 пкс мы показываем справа сайдбар и размер нашего изображения должен быть 75% от ширины экрана. В противном случае сайдбар располагается в конце страницы и изображение должно быть растянуто на всю ширину. Это реализуется следующим кодом
<img
src="images/400.jpg"
srcset=" 400w, images/800.jpg 800w, images/1200.jpg 1200w"
sizes="(min-width: 700px) 75vw, 100vw"
>
400w, 800w, 1200w
— это дескрипторы ширины, они подсказывают браузеру картинка какой ширины находится по данному URL и на основе этой информации браузер принимает решение какое изображение лучше всего подойдет в текущей ситуации. Как и в случае с ретиной информация носит рекомендательный характер и окончательное решение какое изображение грузить остается за браузером.
Одновременное использование дескрипторов плотности и ширины недопустимо.
В атрибуте sizes
перечисляются размеры изображения для всех контрольных точек в нашем дизайне. Контрольные точки задаются в виде обычного медиавыражения, браузер берет первое, которое возвращает Истину и дальше цепочку не рассматривает. Для значения ширины используется новая единица длины vw [7], которая возвращает значение в процентах от ширины вьюпорта.
Если для картинки нет необходимости использовать контрольные точки, то запись можно сократить до такой sizes="100vw"
. А для более сложных дизайнов можно использовать CSS-функцию calc()
, например
sizes="(max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)"
Самый сложный в поведении атрибут на мой взгляд. Если не указывать sizes
, то браузер всегда выбирал самую большую картинку. В сочетании с width
не работает, хотя казалось бы логичное сочетание и ряд других глюков. Возможно это особенности ранней реализации.
Как видите, мы уже покрыли 80% потребностей адаптивной верстки, а еще ни разу не использовали picture
, настало время ему тоже вступить в игру.
Использование различных форматов для изображений мало отличается от способов используемых для тегов video
или audio
<picture>
<source srcset="images/400.webp" type="image/webp">
<img src="images/400.jpg"
width="400" height="300"
>
</picture>
Мы указываем список источников и mime/type для каждого, а браузер уже выбирает первый, который знает. В качестве фолбека используется изображения из атрибута src
.
Когда мы показываем фото на меньшем экране иногда имеет смысл обрезать лишние детали, оставив только основную часть. С этой задачей нам поможет справиться атрибут media
<picture>
<source media="(min-width: 900px)" srcset="images/original.jpg 1200w" sizes="100vw">
<source media="(min-width: 700px)" srcset="images/800crop.jpg 800w" sizes="100vw">
<img
srcset="images/400crop.jpg 400w"
sizes="100vw"
>
</picture>
В каждом атрибуте media
мы задаем медиавыражение, при котором у нас будет меняться исходное изображение и, в отличие от предыдущих примеров, браузер будет обязан ему следовать. Обратите также внимание как кадрирование здесь сочетается с адаптивностью, чтобы растянуть изображение на всю ширину.
А теперь все 4 метода в одном флаконе :) Возможно так будет выглядеть вставка картинок через пару лет (пример из блога Оперы)
<picture>
<source
media="(min-width: 1280px)"
sizes="50vw"
srcset="opera-fullshot-200.webp 200w,
opera-fullshot-400.webp 400w,
opera-fullshot-800.webp 800w,
opera-fullshot-1200.webp 1200w,
opera-fullshot-1600.webp 1600w,
opera-fullshot-2000.webp 2000w"
type="image/webp">
<source
sizes="(min-width: 640px) 60vw, 100vw"
srcset="opera-closeup-200.webp 200w,
opera-closeup-400.webp 400w,
opera-closeup-800.webp 800w,
opera-closeup-1200.webp 1200w,
opera-closeup-1600.webp 1600w,
opera-closeup-2000.webp 2000w"
type="image/webp">
<source
media="(min-width: 1280px)"
sizes="50vw"
srcset="opera-fullshot-200.jpg 200w,
opera-fullshot-400.jpg 400w,
opera-fullshot-800.jpg 800w,
opera-fullshot-1200.jpg 1200w,
opera-fullshot-1600.jpg 1800w,
opera-fullshot-2000.jpg 2000w">
<img
src="opera-closeup-400.jpg" alt="The Oslo Opera House"
sizes="(min-width: 640px) 60vw, 100vw"
srcset="opera-closeup-200.jpg 200w,
400w,
opera-closeup-800.jpg 800w,
opera-closeup-1200.jpg 1200w,
opera-closeup-1600.jpg 1600w,
opera-closeup-2000.jpg 2000w">
</picture>
Здесь используются 2 формата JPEG и WebP. При ширине экрана более 1280 пкс показывается полноразмерная картинка в половину вьюпорта. При ширине от 640 до 1279 показывается обрезанное фото на 60% ширины вьюпорта. При ширине экрана меньше 640пкс показывается обрезанная фотография на 100% ширины. Выбор под текущее DPI экрана производится на основе ширины исходных файлов.
Поддержка браузерами caniuse.com/#search=picture [8]
Спецификация www.w3.org/html/wg/drafts/html/master/embedded-content.html#the-picture-element [9]
Рабочая группа и типовые задачи, которые они решали с помощью нового элемента responsiveimages.org/ [10]
Множество примеров использования dev.opera.com/articles/responsive-images/ [11]
Автор: fetis26
Источник [12]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/html/70581
Ссылки в тексте:
[1] pepelsbey: http://habrahabr.ru/users/pepelsbey/
[2] github.com/fetis/picture: https://github.com/fetis/picture
[3] Firefox Nighlty: http://nightly.mozilla.org/
[4] Chrome Canary: http://www.google.com/chrome/browser/canary.html
[5] Opera Developer: http://www.opera.com/developer
[6] Chrome Beta: https://play.google.com/store/apps/details?id=com.chrome.beta
[7] единица длины vw: http://dev.w3.org/csswg/css-values/#viewport-relative-lengths
[8] caniuse.com/#search=picture: http://caniuse.com/#search=picture
[9] www.w3.org/html/wg/drafts/html/master/embedded-content.html#the-picture-element: http://www.w3.org/html/wg/drafts/html/master/embedded-content.html#the-picture-element
[10] responsiveimages.org/: http://responsiveimages.org/
[11] dev.opera.com/articles/responsive-images/: https://dev.opera.com/articles/responsive-images/
[12] Источник: http://habrahabr.ru/post/237991/
Нажмите здесь для печати.