Метод «автомобиль клоуна»: применение адаптивных изображений в веб-дизайне.

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

В нашем распоряжении находятся изображения для переднего плана и фоновые изображения. У нас есть большие и маленькие дисплеи. Мы используем стандартные дисплеи и дисплеи с высоким разрешением. У нас есть соединения с высокой и низкой пропускной способностью. Мы можем использовать портретную и пейзажную ориентации.

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

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

Метод “автомобиль клоуна” позволяет приблизиться к правильному решению: совокупное использование хорошо поддерживаемых информационных запросов, SVG формата и элемента <object> позволяют обслуживать адаптивное изображение с помощью всего лишь одного запроса. Данное решение еще не идеально, но достаточно эффективно, поэтому не стоит его игнорировать.

Фоновые изображения и информационные запросы.

Мы решили использовать адаптивные фоновые изображения. Информационные запросы позволяют легко адаптировать размер и разрешение изображения к пиксельному соотношению устройства, размеру экрана и даже экранной ориентации.

Благодаря использованию информационных запросов вместе со стилизацией фонового изображения, мы сможем гарантировать, что с сервера будут загружаться только требуемые изображения. Мы можем ограничить загрузки для беспрепятственного доступа к наиболее подходящим файлам, экономии пропускной способности, памяти и запросов HTTP.

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

Предлагаемые решения с новыми технологиями.

Новые элементы и атрибуты.

Со встроенным или «содержащимися» изображениями, заставить браузер загружать и отображать только нужные изображения переднего плана немного сложнее. Большинство людей считают, что нет никакого механизма вызова <img> тега для загрузки изображения нужного размера и разрешения. С этой целью были созданы полинаполнители и соответствующие сервисы.

Было предложено использование элемента <picture>, который использует семантику HTML5 <video> элемента, с его поддержкой информационных запросов для осуществления изменений в различных исходных файлах:

<picture alt="responsive image"> 
     <source src="large.jpg" media="(min-width:1600px),
     (min-resolution: 136dpi) and (min-width:800px)">
     <source src="medium.jpg" media="(min-width:800px),
     (min-resolution: 136dpi) and (min-width:400px)">
     <source src="small.jpg">
  <!-- fallback -->
  <img src="small.jpg" alt="responsive image">
</picture>

Также был предложен и другой метод, связанный с использованием атрибута srcset в элементе <img>. Код аналогичный тому, что использовался для <picture> элемента в примере выше, был бы записан следующим образом:

<img
    alt="responsive image"
    src="small.jpg" 
    srcset="large.jpg 1600w, 
          large.jpg 800w 1.95x, 
          medium.jpg 800w, 
          medium.jpg 400w 1.95x">

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

Google предлагает использование клиентских подсказок, как части заголовка HTTP, для того, чтобы выбиралось требуемое изображение, которое будет обслуживаться сервером.

Использование SVG – замечательное решение.

Многие люди не понимают, что у нас уже есть технология для создания и обслуживания адаптивных изображений.

Уже довольно долго SVG (масштабируемая векторная графика) обладает возможностью поддержки информационных запросов, и браузеры в свою очередь также способны поддерживать SVG. Большинство браузеров обладает возможностью поддержки информационных запросов в SVG (можно протестировать свой собственный браузер). Когда дело доходит до адаптивных изображений, только браузеры старых версий Android на мобильных устройствах не поддерживают SVG (поддержка SVG Android начинается с версии Android 3.0).

Мы можем использовать возможность поддержки SVG браузером и поддержку информационных запросов и растровых образов SVG для создания адаптивных изображений. Использование информационных запросов в SVG позволяет обслуживать выбранное изображение.

Теоретически мой оригинальный эксперимент должен работать, и он работает в Internet Explorer (IE) 10 и Opera. Когда вы создаете HTML разметку, то должны добавить один вызов SVG файла.

 <img src="awesomefile.svg" alt="responsive image"> 

Сейчас код довольно прост, не правда ли?

Возможность поддержки SVG растровых изображений используется в комплекте с <image> элементом и свойством CSS background-image. В адаптивную SVG мы можем включать все изображения, которые нам могут понадобиться для обслуживания, а затем в зависимости от информационных запросов отображать только требуемые изображения.

Как можно загрузить одно растровое изображение.

Моя первая попытка использования SVG <image> с информационными запросами, скрывая их с помощью команды display: none.

В то время как SVG отлично работает с точки зрения оперативности, она все равно имеет ряд проблем. К сожалению, установка display: none на <image> в SVG похожа на использование <img> в HTML и не предохраняет ресурс от загрузки. Если вы откроете <image> SVG на своем браузере, то все четыре изображения будут получены с сервера в формате PNG (переносимая сетевая графика), что влечет за собой необходимость четырех HTTP-запросов, траты пропускной способности и памяти.

Мы знаем из фоновых изображений CSS, что действительно существует возможность загрузки только необходимых изображений. Кроме того, для предотвращения загрузки из SVG всех включенных в нее изображений, мы будем использовать фоновое изображение CSS вместо изображений переднего плана в файле SVG:

<svg xmlns="http://www.w3.org/2000/svg" 
viewBox="0 0 300 329" preserveAspectRatio="xMidYMid meet"> <title>Clown Car Technique</title> <style>
svg {
background-size: 100% 100%;
background-repeat: no-repeat;} @media screen and (max-width: 400px) {
        svg {
               background-image: url(images/small.png");}
} @media screen and (min-width: 401px) and (max-width: 700px) {
        svg {
               background-image: url(images/medium.png);}
} @media screen and (min-width: 701px) and (max-width: 1000px) {
        svg {
               background-image: url(images/big.png);}
} @media screen and (min-width: 1001px) {
        svg {
               background-image: url(images/huge.png);}
}
</style>
</svg>

В пример выше можно также включить элементы < svg> или <img> src непосредственно в качестве встроенных атрибутов или атрибут <object> data.

Если вы знакомы с информационными запросами и запросами CSS, то большая часть кода, представленного выше, должна быть для вас понятна. Метод «автомобиль клоуна» использует те же самые информационные запросы, которые можно использовать и в другой части вашего адаптивного веб-сайта.

Для сохранения соотношения сторон элемента и гарантии корректного отображения и равномерного распределения мы воспользуемся атрибутами viewbox и preserveAspectRatio.

Значение viewbox атрибута представляет собой список из четырех цифр разделенных пробелами или запятыми: min-x, min-y, width и height. Определив ширину и высоту элемента viewbox, определим соотношение сторон изображения SVG. Значения, установленные для preserveAspectRatio атрибута — 300 × 329 — сохраняют пропорции, определенные в viewbox.

Существуют определенные проблемы 1) Chrome и Safari не сохраняют пропорций, когда используется встроенный атрибут <svg>: по умолчанию значение <svg> устанавливается до 100% ширины и высоты. Ошибка была исправлена.2) Webkit и Firefox не позволяют включать растровые изображения или скрипты в SVG с помощью <img> элемента 3) В IE <=8 и Android <=2.3.3 отсутствует возможность поддержки SVG.

Когда вы открываете SVG файл с фоновыми изображениями, растровое изображение будет занимать всю область просмотра. Вариант с использованием атрибута <image> выглядит предпочтительнее в роли самостоятельного файла, поскольку он сохраняет свои пропорции, а версия background-image позволяет выполнить заполнение всего окна просмотра. Когда вы включаете SVG в виде отдельного документа, извлекаемого в HTML, соотношение сторон сохраняется по умолчанию. В атрибуте background-size можно применять значения contain, cover или 100%: выберите то, которое лучше всего подходит для ваших требований.

С помощью свойства CSS background-image можно решить проблемы HTTP запроса. Откройте SVG файл со всеми PNG фоновыми изображениями (или JPEG версию) и посмотрите в закладке “Сеть” инструментальных средств разработчика. Вы увидите, что SVG сделал только два HTTP-запроса вместо пяти. Если ваш монитор больше, то браузер будет производить загрузку небольшого SVG файла (676 байт) и huge.png или huge.jpg.

Наша первая проблема — загрузка изображений разных размеров, даже тех, которые не нужны — была решена. Благодаря атрибуту background-image можно загружать только требуемое изображение, что позволяет исключить необходимость использования нескольких запросов HTTP и увеличивает пропускную способность.

Самое удивительное происходит тогда, когда мы включаем SVG в гибкий макет. Вы увидите, что при первом изменении размера изображения браузер может мигать белым, сигнализируя о необходимости использования PNG — поскольку он автоматически не может загружать все ресурсы. Он загружает только те ресурсы, в которых нуждается. Просто установите значение ширины или высоты контейнера (<img>, <svg> или <object>) вместе с CSS, которая содержит информационные запросы. SVG будет извлекать только то растровое изображение, в котором нуждается.

У нас по-прежнему остается сам SVG файл, который требует наличия HTTP-запроса, когда не встроен внутрь вместе с <svg>. Мы решим этот вопрос.

Вопросы безопасности контента.

В Opera или в Windows 9 или 10, откройте HTML-файл, содержащий растровое SVG изображение, которое связано с <img> тегом. Обратите внимание, что в панели «Ресурсы» инструментальных средств разработчиков загружается только один JPEG или PNG файл. Измените размер окна вашего браузера. Обратите внимание, что <img> реагирует на изменения. Все дополнительные изображения в формате JPEG или PNG (мы также могли бы использовать GIF или WebP файлы) загружаются только тогда, когда необходимо.

Если вы попытаетесь открыть HTML-файл, содержащий растровое SVG изображение в Firefox или WebKit, то, скорее всего, не увидите никаких изображений. SVG работает во всех современных браузерах, но тэг <img>, который вызывает в SVG загрузку растрового изображения, работает только в Operaи IE 9 и версиях выше. Сначала мы рассмотрим, как все это работает в IE и Opera, а затем рассмотрим вопросы, связанные с WebKit и Firefox.

Код прост:

 <img src="awesomefile.svg" alt="responsive image"> 

При использовании SVG в HTML <img> с изменяемой шириной, например, 70% от величины размера окна просмотра, то при увеличении и уменьшении контейнера путем изменения размера окна или CSS, изображение будет реагировать соответствующим образом.

Информационный запрос width в SVG основан на родительском элементе, в котором содержится SVG — в данном случае <img> — а не значение ширины окна просмотра.

По мере того, как окно увеличивается или уменьшается в размерах, изображение, отображаемое SVG, также изменяется. В файле SVG параметры изображения устанавливаются в 100%значение от высоты и ширины родительского элемента, который в случае выше, когда мы открыли SVG напрямую, был областью просмотра. Теперь, контейнер – это <img> элемент. Поскольку мы использовали атрибуты viewbox и preserveAspectRatio, то до тех пор пока, по крайней мере, одна длина не будет определена, SVG будет увеличиваться или уменьшаться, сохраняя соотношение заданных в файле сторон независимо от размера изображения.

Изображения переднего плана отлично работать в Operaи IE 9+ (версии, найденные на мобильных устройствах). В Chrome и Safari если сначала открыть файл SVG и тем самым выполнить его кэширование, то HTML-файл, содержащий SVG изображение переднего плана, может работать корректно.

Ранее мы уже увидели, что браузер действительно может визуализировать SVG, если SVG включен в наш документ через <img> тег. Но существует определенный тип SVG, который не сможет быть визуализирован.

Почему? Для предотвращения спланированных междоменных атак, некоторые браузеры проводят политику безопасности контента в местах хранения SVG файлов, полученных благодаря импорту информационных запросов или скриптов, в случае, если они вредоносны.

Блокировка SVG файлов, полученных от импорта скриптов и изображений имеет смысл: для предотвращения спланированных междоменных атак, необходимо изолировать файл с потенциально вредоносным контентом. Несмотря на то, что SVG поддерживается WebKit и FireFox, была исключена возможность загрузки внешних растровых изображений. Я представил отчет об ошибках Сhrome для изучения возможных запретов на импорт растровых изображений в SVG.

В Firefox адаптивный файл SVG также работает определенным образом. Firefox полностью поддерживает SVG. Тем не менее, по соображениям безопасности Firefox блокирует импорт внешних растровых изображений, даже если эти изображения находятся на том же домене. Обосновывается это тем, что пользователь может загружать изображения, а затем отображать эти изображения и скрипты как часть SVG, что может представлять угрозу безопасности. Я уверен, что если сайт использует небезопасный пользовательский контент, он совершает огромную ошибку.

Для демонстрации события давайте прямо сейчас посмотрим на эту простую линию …

 <img src="awesomefile.svg" alt="responsive image"> 

… она будет блокирована в некоторых браузерах и, следовательно, не является подходящим решением.

Все браузеры поддерживают SVG информационные запросы. Все они поддерживают SVG как изображение переднего плана или содержимое. Все они поддерживают SVG в качестве фонового изображения. В разных браузерах поддержка не идентична из-за различного уровня политики безопасности.

Все браузеры поддерживают использование <object> ...

Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров

Comments are closed.