Оптимизация сайтов под Retina-экраны
Сравнительно недавно на рынок активно стали входить дисплеи с увеличенной плотностью пикселей – это Retina дисплеи (на Apple девайсах) и их аналоги других производителей.
* Далее, да простят нас конкуренты Apple, чтобы не писать длинных фраз, все экраны с высокой плотностью пикселей объединим названием Retina.
Для веб-разработчиков это новая головная боль. Так почему же? Попробуем разобраться. Большая плотность пикселей означает, что количество физических пикселей больше, чем виртуальных.
Физические пиксели — самые мелкие элементы любого дисплея, каждый из которых имеет свою яркость и цвет.
Плотность пикселей — это количество физических пикселей на единицу площади (обычно пикселей на дюйм).
CSS-пиксели — некоторая браузерная величина, используемая для точного отображения контента и независящая от экрана.
Соотношение между физическими пикселями и виртуальными
Для лучшего понимания сразу представим это соотношение графически:
Т.е. блок, например, шириной 300x700px на Retina дисплеях будет размером уже 600x1400px. Аналогично любая растровая картинка будет масштабироваться и при этом терять качество:
Очевидная разница в качестве. Одна и та же картинка на стандартном дисплеи (слева) и на Retina-дисплеи (справа).
Оптимизация графики под Retina
В общем-то сначала стоит понять, нужно ли это нам вообще? Доля Retina дисплеев хоть и неуклонно растет, но пока остается небольшой. Преимущественно это мобильные девайсы – планшеты. Так, например, для сайта фирмы, занимающейся продажей стальных дверей скорее всего это не понадобится, т.к. большинство заходов будет со стационарных компьютеров, где основная доля экранов стандартные. Другое дело, если говорить о сайтах, связанных с мобильными устройствами или интернет-магазинах. Там доля трафика с мобильных устройств значительно выше и заходов с устройств с Retina тоже больше.
Итак, мы решили, что нам необходимо оптимизировать графику под Retina. Как это сделать? Очевидно, что надо выдать картинку с требуемым разрешением. Есть несколько способов, рассмотрим их.
HTML и CSS масштабирование
Пожалуй, самый простой способ – это заранее подготовить картинки большего размера (требуемый размер, умноженный на 2). Так, например, чтобы показать лого размером 250x100px, надо загрузить картинку размером 500x200px и уменьшить его, используя CSS-свойства или HTML-атрибуты.
HTML
Можно просто задать атрибуты width и height для картинки:
<img src="logo@2x.png" width="250" height="100" alt="">
Javascript
То же самое можно получить, используя jQuery библиотеку:
$(window).load(function() { var images = $('img'); images.each(function(i) { $(this).width($(this).width() / 2); }); });
CSS
Для изображений на фоне можно воспользоваться CSS-свойство background-size для нужного блока. Тут стоит учесть, что данное свойство не поддерживается в IE8 и ниже. Для поддержки IE есть фиксы, но они не всегда помогают.
.logo { background-image: url(logo@2x.png); background-size: 250px 100px; /* Или, что то же самое: background-size: contain; */ width: 250px; height: 100px; }
Все три метода можно комбинировать в данном способе.
Плюсы:
- Простота;
- Кроссбраузерность.
Минусы:
- Скачиваются лишние и ненужные мегабайты для обычных дисплеев;
- Потеря качества масштабированных изображение из-за алгоритмов сжатия;
- Свойство background-size не поддерживается IE8 и ниже.
CSS
Данный способ заключается в том, чтобы в зависимости от разрешения экрана (resolution) или соотношения между физическими и CSS-пикселями (-*-*-device-pixel-ratio), выдать нужное нам изображение.
.logo { background-image: url(logo.png); background-size: 250px 100px; height: 250px; width: 100px; } @media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min--moz-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (min-resolution: 1.5dppx), only screen and (min-resolution: 144dpi) { .logo { background-image: url(logo@2x.png); } }
Наверное, следует пояснить, что это такое и с чем кушать. Есть стандартное свойство resolution. Оно определяет разрешение устройства в dpi (точек на дюйм) или dpcm (точек на сантиметр), что, наверное, несколько трудновато для восприятия и поэтому вебкит решили добавить свое свойство -webkit-min-device-pixel-ratio, которое означает «точек на пиксель» (безразмерное отношение). Суть у всех этих величин одна и их соотношение можно записать так: 1in = 96px = 2.54cm. Т.к. указывать разрешение не очень удобно, а писать длинное -webkit-min-device-pixel-ratio долго в стандарт была добавлена величина dppx, которая и означает «точек на пиксель». Итого, меди-запрос resolution имеет 3 величины: dpi (точек на дюйм), dpcm (точек на сантиметр) и dppx (точек на пиксель).
Плюсы:
- Скачиваются только нужные изображения;
- Кроссбраузерность;
- Мы можем сами задать плотность пикселей, при которой надо загружать изображения лучшего качества.
Минусы:
- Внедрение на крупных проектах может занять много времени;
- Универсальность. Не совсем корректно будет использование данного метода для изображений контента.
JavaScript
Аналогичный результат можно получить, воспользовавшись window.devicePixelRatio
$(document).ready(function(){ if ('devicePixelRatio' in window && window.devicePixelRatio > 1) { var lowresImages = $('img.replace-2x '); images.each(function(i) { var lowres = $(this).attr('src'); var highres = lowres.replace(".", "@2x."); $(this).attr('src', highres); }); } });
На основе этого метода создан плагин Retina.js, который умеет делать все то же самое, но с дополнительными возможностями, такими как пропуск внешних изображений и пропуск внутренних, не имеющих retina-копий.
Плюсы:
- Просто внедрять;
- Скачиваются только нужные изображения;
- Мы можем сами задать плотность пикселей, при которой надо загружать изображения лучшего качества.
Минусы:
- Устройства с Retina дисплеями скачивают оба варианта изображений;
- Подмена изображений заметна на устройствах с Retina дисплеями;
- Поддерживают не все браузеры.
Серверный метод
Метод заключается в том, чтобы часть работы переложить на сервер. Т.к. сервер не знает, какое разрешение у монитора пользователя, ему надо помочь с помощью небольшого скрипта, которым, если значение dppx (точек на пиксель) больше 1.5, мы установим cookies.
<script> if ('devicePixelRatio' in window && window.devicePixelRatio > 1) { setCookie('js_retina', window.devicePixelRatio, 30); } function setCookie(c_name, value, exdays) { var exdate = new Date(); exdate.setDate(exdate.getDate() + exdays); var c_value = encodeURIComponent(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString()); document.cookie = c_name + "=" + c_value; window.location.reload(); } </script> <? if (!empty($_COOKIE['js_retina'])) { ?> // картинка для retina дисплеев <img src="logo@2x.png" width="250" height="100" alt=""> <? } else { ?> // картинка для стандартных дисплеев <img src="logo.png" width="250" height="100" alt=""> <? } ?>
Плюсы:
- Достаточно один раз определить устройство, а дальше на основе установленной cookie сервер сам будет выдавать нужное изображение;
- Скачиваются только нужные изображения;
- Мы можем сами задать плотность пикселей, при которой надо загружать изображения лучшего качества.
Минусы:
- Внедрение может оказаться трудоемким;
- Поддерживают не все браузеры;
- После установки cookie нужно перезагрузить страницу.
SVG-графика
Как не крути, масштабируемость растрового изображения ограничена и при манипуляциях с размерами картинок они будут терять свое качество. Поэтому лучший результат можно получить, используя векторную графику – SVG (Scalable Vector Graphics) формат на основе XML. Использовать SVG-изображения достаточно просто — в теге img или CSS-параметром background-image.
<img src="logo.svg" width="250" height="100" alt="">
или
.logo { background-image: url(logo.svg); background-size: 250px 100px; width: 250px; height: 100px; }
Тут стоит учесть, что SVG формат не поддерживается в IE8 и ниже. Для поддержки IE требуется подготовка заменяющих PNG-изображений. Реализуется это при помощи плагина Modernizr.
.logo { background-image: url(logo.png); background-size: 250px 100px; height: 250px; width: 100px; } html.svg .logo { background-image: url(logo.svg); background-size: 250px 100px; height: 250px; width: 100px; }
Плюсы:
- Неограниченная масштабируемость, а следовательно высокое качество;
- Одно изображение для всех устройств;
- Относительная просто реализуется;
- Не требуется дополнительных скриптов.
- Требуется подготовка изображений в векторном формате, что подходит в основном для логотипов и иконок;
- Векторный формат не поддерживается старыми версиями IE.
← Назад в раздел