В третьей части пособия, посвященного адаптивному веб-дизайну, Пол Роберт Ллойд рассказывает о включении изображений и видео в макеты адаптивного сайта и описывает еще нерешенные проблемы этой области.
В прошлой статье я описал, как возможно организовать подвижную структуру и предложил для решения данной задачи отказаться от измерений в пикселях в пользу пропорциональных единиц, таких как em и проценты.
Все хорошо, пока мы работаем с текстом: если колонка становится слишком узкой — текст с легкостью переносится на новую строку. Однако видео и изображения имеют определенный размер в пикселях. Мы, конечно, можем масштабировать элемент, но увеличится время его загрузки, а это, в свою очередь, негативно повлияет на пропускную способность ресурса.
Экраны с высоким разрешением (или retina displays) представляют еще одну проблему. У этих экранов число пикселей на квадратный дюйм намного больше, чем у обычных дисплеев, что позволяет отображать изображение более детально. Соответственно высококонтрастные изображения и иконографика, неадаптированные под такой формат, будут размытыми и нечеткими.
В этой статье мы рассмотрим решение этих вопросов. Но стоит отметить, что это быстроразвивающаяся область, новые решения в которой возникают чуть ли не каждый день. Это сложно и захватывающе одновременно!
В прошлой статье мы создали для примера подвижную структуру страницы списка превью. Однако изображения в пределах каждого элемента не адаптируются под изменения структуры страницы. Таким образом, либо разрываются границы элементов, либо остается много пустого пространства.
К счастью, есть простое решение. Его обнаружил Ричард Раттер (пионер разработки адаптивных макетов с подвижной структурой), оно заключается в добавлении следующего правила для всех изображений, которые должны масштабироваться:
img { max-width: 100%; }
Это правило диктует браузерам, что изображение занимает 100% ширины родительского элемента. Действительно просто.
Однако существует одна маленькая оговорка. Следуя правилам CSS, вы не сможете добавить атрибут height (высота) для ваших изображений. Это не лучший вариант с точки зрения производительности, ведь чем скорее браузер узнает, какой размер изображения отображать, тем меньше времени он затратит на отрисовку страницы. Поэтому добавлять атрибуты width и height имеет смысл для изображений, которые не нуждаются в масштабировании.
Обратите внимание, для этих превью я использовал изображения, предназначенные для десктопных разрешений, а потом пытался масштабировать их под наименьшие разрешения экрана. Это противоречит принципу «mobile first»!
Это вопрос здравого смысла. Нам нужно достичь баланса между технологичностью и рациональностью. Для этих превью, разница в размере будет достаточно мала (138px > 240px), значит, мы можем компенсировать размер файла другими способами. Используем файл правильного формата (JPEG, как правило, может генерировать фотографии меньшего веса) и правильно его сжимаем. Мы расскажем об оптимизации изображения более подробно в ходе заключительной части этой статьи.
На странице сайта с медиабиблиотекой изображения могут быть размером от 288рх до 800рх в ширину. Независимо от формата файла и оптимизации, большее изображение может достигать размера до 300Кб, занимая несколько секунд, если не больше, на загрузку страницы через соединение 3G. Это проблема.
В идеале, браузер должен сообщать размер изображения для отображения и данные о скорости соединения, мы, в свою очередь, должны рассчитать и предоставить изображение соответствующее данным ограничениям. Но, к сожалению, ни один браузер этого не делает, и нет никаких специфических решений (во всяком случае, пока).
Такова масштабность этого вопроса. Некоторые умные и талантливые разработчики предложили несколько решений. Одни из них решают проблему с помощью JavaScript, другие используют определение на стороне сервера, однако все имеют как свои преимущества, так и недостатки.
Скотт Джел разработал подход, который сочетает в себе решения на основе модуля mod_rewrite, использование cookies и JavaScript. Принцип действия данного метода основан на определении ширины экрана до того, как изображение будет загружено.
Если экран маленький, то запрос отправляется на небольшие картинки. Если экран достаточно велик, запрос будет переадресован в директорию, содержащую большие картинки, которые и будут загружены вместо предыдущих.
Подход очень хрупкий, так как, браузеры уделяют все больше внимания производительности, обычно используя техники предварительной выборки ресурсов. Помимо этого определяется ширина экрана для загрузки соответствующего изображения. Но не всегда верно, что при определении большого экрана гарантированно загрузится большое изображение.
Мэтт Уилкокс, вдохновленный работой Скотта, разработал решение на PHP, которое полностью совместимо с уже существующими разметками, и позволяет использовать изображения нескольких размеров. Опять же, браузер загружает изображения исходя из данных о разрешения экрана, которые не всегда соответствуют истине, вдобавок данное решение использует GD библиотеку PHP для работы.
Пока остальные сосредоточились на способах, целью которых является определение размера изображений до загрузки всей страницы, Джош Эмерсон предложил другой подход. Как и в других случаях, в разметке используются ссылки на маленькие изображения, но вместо того чтобы определять необходимо ли более крупное изображение перед тем, как страница загрузится, подгружается меньшее. Только после того, как это изображение загрузится, если требуется большее изображение, оно заменится версией с более высоким разрешением. Во многом это новшество взято из атрибута lowsrc, который таинственно исчез из HTML. Ох, как долго мы ждали его возвращения.
Помимо этого, возможен вариант с использованием media queries. Для определенных разрешений мы допускаем или запрещаем показ изображений (img), через CSS (display: none;). Все современные браузеры адаптированы так, что изначально не загружают изображения, которые отключены для показа.
Джейсон Грисби много писал об этой проблеме, вдаваясь в фантастические подробности о плюсах и минусах вышеописанных решений. Между тем, Мэтт Маркиз осознал необходимость нового HTML-элемента, и открыл рабочую группу для обсуждения деталей в W3C.
Долго ли коротко ли, но проблема так и не решена. Все что мы можем — это решить, какой из вышеописанных способов больше соответствует нашим потребностям. В этой статье мы рассмотрим технику адаптивного улучшения.
Во-первых, мы должны дать ссылку на файл JavaScript в <head>:
<head> ... <script src="/_js/responsive-enhance.js"></script> <title>Arriving in Las Vegas</title> </head>
Далее, для элемента <img> мы должны добавить новый атрибут data-fullsrc, со ссылкой на источник большего изображения:
<img id="media-object" src="http://farm8.staticflickr.com/7131/6998741089_0d87917944_n.jpg" data- fullsrc="http://farm8.staticflickr.com/7131/6998741089_0d87917944_c.jpg" alt="Sunset over Arizona« />
Далее добавим скрипт под изображением:
<script>responsiveEnhance(document.getElementById(’media-object’), 320);</script>
Таким образом, мы сообщаем браузеру, какое изображение заменить и для какой ширины экрана его отобразить. В случае если JavaScript отключен или недоступен, пользователи увидят наименьшее (дефолтное) изображение. Иначе говоря, когда ширина экрана больше 320рх, изображение наибольшего разрешения загрузится сразу после того, как загрузится дефолтное.
Теперь, мы должны аннулировать дефолтные стили изображений. Для дальнейшей работы нам нужно наименьшее изображение масштабировать в больший, нежели его изначальный, размер.
Сделать это можно следующим образом:
img.media-object { margin: 0 auto; width: 100%; max-width: 50em; /* 800px */ }
Опять же, это не идеальное решение (тем более что мы можем ссылаться только на одно дополнительное изображение подходящего размера), но в любом случае это гораздо лучше, чем просто обходиться увеличенной картинкой.
Само собой, изображения существуют не сами по себе, а в разметке: мы можем сослаться на них из CSS. Так немного проще, поскольку media queries означает, что мы можем выбрать, какие изображения будут отображаться в различных макетах.
Поскольку во многих случаях фон в CSS будет задан в виде изображения, сейчас самое время подумать о дисплеях с высоким разрешением, и, в частности, о двух методах, которые позволяют нам использовать изображения, независимые от разрешения экрана:
В растущем «безпиксельном» вебе Scalable Vector Graphics (SVG) сравнима с глотком воды после долгих лет скитаний по пустыне. С хорошей поддержкой большинства современных браузеров, включая IE9 и выше, мы можем использовать этот формат несколькими способами. Во-первых, мы можем ссылаться на него из элемента <img>, а во-вторых мы можем включить SVG код непосредственно в нашу разметку, и ссылаться на него из CSS. Дэвид Бушелл зафиксировал технику, которая использует спрайты изображений на основе SVG — советую к прочтению.
Осталось только дождаться, когда общая масса IE ниже 9 версии составит намного меньше 25% или последовать примеру Google и Apple, которые практически полностью отказались от поддержки IE8 и более ранних версий :)
Получить масштабируемые изображения также можно при помощи специально разработанных веб-шрифтов, которые включают изображения вместо букв и цифр. Это означает, что мы можем стилизовать изображения так же, как мы делаем это с текстом, и так же наслаждаться векторной иконографикой. Детально можно прочитать о шрифтах, состоящих из изображений у Джона Хикса.
Идея интересная, но реализация и поддержка данного решения может помешать внедрению данного приема в массы.
Окей, достаточно об изображениях — давайте поговорим о видео. К счастью, делать видео адаптивным менее проблематично. Видео должно иметь оптимальное разрешение и обладать рядом простейших кодеков, доступных на любом ПК. И, конечно же, видео должно начинать загрузку сразу же после нажатия кнопки play.
Я бы не стал так сразу сообщать, что с видео работать менее проблематично, я бы сказал, что проблемы все абсолютно такие же, как и с изображениями. Зачем подключать видео разрешения 1080pх для смартфона с 3G интернетом? Но это касается тэга VIDEO и собственных видеофайлов. Существует оптимальный вариант — это размещение видео на стороннем сервисе видеохостинга (YouTube, Vimeo и другие). У них имеется собственная система оптимизации, которая готовит «Адаптивное видео» в десятках форматах и размерах и на основе собственной системы определения устройства, предоставляет нужный формат. Дополнительный плюс этого способа заключается в том, что
Но мы хотим, чтобы видео масштабировалось только в пределах нашего макета. Если мы применяем исходный HTML5 код для видео, мы снова можем использовать следующий CSS:
video { max-width: 100%; }
Как бы то ни было, вложенные объекты (<iframe>, <object>, <embed>) ведут себя по-разному. Добавим для них следующее правило:
iframe.media-object { max-width: 100%; }
Видео может не сохранить правильные пропорции в процессе масштабирования, или вовсе отказаться адаптироваться:
Это происходит потому, что вложенные объекты не в состоянии сообщить пропорции видео, содержащегося в них. Для того чтобы решить эту проблему, мы должны поместить вложенный объект внутрь контейнера, который имеет правильные пропорции, и установить код для вставки: 100% ширину и высоту (подход впервые был предложен Тьерри Кобленцем).
Во-первых, мы должны заключить вложенные объекты в рамки контейнера:
<div> <iframe src="http://player.vimeo.com/video/40493662« /> </div>
Тогда мы установим следующий стиль оболочки:
.media-object-wrapper { padding-bottom: 56.25%; width: 100%; height: 0; position: relative; }
Padding-bottom задает пропорции оболочки. Наше встроенное видео имеет соотношение сторон 16:9, их высота составляет 56,25% от ширины (9/16 = 0,5625). Вы заметите, что до этого мы задали «position: relative»; теперь мы можем установить «position: absolute» вложенному <iframe>, это позволит проигнорировать отступ:
.media-object-wrapper iframe.media-object { width: 100%; height: 100%; position: absolute; }
И вот, что у нас получилось. Вложенное видео теперь размещается в макете так же красиво, как и наши изображения:
Посмотреть видео можно по этой ссылке в папке шаблонов разметки
Но все же, пока мы с вами анализируем наши макеты на адаптивность, можно заметить, что, несмотря на то, что они масштабируются, существуют места, в которых структуру стоит делать немного «умнее», адаптируя ее по мере увеличения ширины окна браузера.
Все решения, представленные в статье, имеют право на жизнь и применимы не только среди энтузиастов веб-разработчиков и веб-дизайнеров, но готовы к применению на коммерческих проектах. Выбирая способ оптимизации изображений и видео, нужно четко взвешивать все плюсы и минусы каждого способа и их сочетаний для своего проекта.
Ежедневно появляется большое количество новых приемов оптимизации графики, ежемесячно появляются фреймворки для удобной работы с адаптивными технологиями. Некоторые из них выживают и развиваются, остальные умирают и забываются, так или иначе все будет упрощаться, а время на разработку адаптивного сайта сокращаться, пока не станет занимать время кратное созданию классического сайта. Именно сокращению времени на разработку адаптивного веб-сайта мы сейчас в AGIMA уделяем особое внимание, проводя исследования и эксперименты перед тем, как применить ту или иную технологию на коммерческом проекте.
[Более подробную информацию об адаптивных изображениях, см. в заметке Мэтта Маркиза и в интервью Итана Маркотта с нашими читателями. — ED]
Оригинал: http://www.netmagazine.com/tutorials/build-responsive-site-week-images-and-video-part-3
Проведите конкурс среди участников CMS Magazine
Узнайте цены и сроки уже завтра. Это бесплатно и займет ≈5 минут.
Руководитель группы разработчиков AGIMA
Также подход несовершенен в том, что все мобильные браузеры (Google Android, Symbian, Windows Phone, Apple Safari) через JavaScript сообщают ложную информацию о размерах окна браузера (приблизительно 850px по ширине).
В некоторых случаях нам может помочь сторонний сервис или собственная база данных User Agent —> Устройство, но и этот способ обречен на провал для браузера Google Android и Opera Mobile, т.к. их User Agent не сообщает о платформе, на которой он установлен.