После недавнего выпуска Retina MacBook Pro и The new IPad, экраны с увеличенной плотностью пикселей начали активно входить в нашу жизнь. Что это значит для веб-разработчиков?
Для начала разберемся в терминологии.
Физические пиксели
Физические пиксели (device pixel или physical pixel) — привычные нам пиксели: самые маленькие элементы любого дисплея, каждый из которых имеет свой цвет и яркость.
Плотность экрана (Screen density) — это количество физических пикселей дисплея. Обычно измеряется в пикселях-на-дюйм (PPI: pixels per inch). Apple, разработав Retina-экраны с двойной плотностью пикселей, утверждает, что человеческий глаз не способен различить бо′льшую плотность.
CSS-пиксели
CSS-пиксели (CSS pixels) — абстрактная величина, используемая браузерами для точного отображения контента на страницах, вне зависимости от экрана (DIPs: device-independent pixels). Пример:
<div height="200" width="300"></div>
Такой блок на обычных экранах будет занимать область 200x300 пикселей, а на Retina-экранах тот же блок получит 400x600 пикселей.Таким образом, на Retina-экранах плотность пикселей в 4 раза больше, чем на обычных:
Соотношение между физическими и CSS-пикселями можно устанавливать так:
device-pixel-ratio,
-o-device-pixel-ratio,
-moz-device-pixel-ratio,
-Webkit-device-pixel-ratio {
…
}
Или так:
device-pixel-ratio,
-o-min-device-pixel-ratio,
min--moz-device-pixel-ratio,
-Webkit-min-device-pixel-ratio {
…
}
В Javascript добиться этого можно, используя
window.devicePixelRatio
Растровые пиксели
Растровые пиксели (bitmap pixels) — самые маленькие части, составляющие растровое изображение (PNG, JPF, GIF и т.д.) Каждый пиксель содержит информацию, о цвете и расположении в системе координат изображения. В некоторых форматах пиксель может содержать дополнительную информацию, например, прозрачность.
Кроме растрового разрешения, изображения в интернете имеют абстрактные размеры в CSS-пикселях. Браузер сжимает или растягивает изображении в соответствии с его CSS-шириной и -длиной. При отображении на обычном экране один растровый пиксель соответствует одному CSS-пикселю. На Retina-экранах каждый растровый пиксель умножается в 4 раза:
Оптимизация
Существует несколько способов оптимизации графики для отображения на Retina-экранах. Каждый имеет и плюсы, и минусы, необходимо в каждом конкретном случае выбирать, что имеет больший приоритет: производительность, простота реализации, поддержка браузерами или какие-то другие параметры.
HTML и CSS-масштабирование
Самый простой способ подготовить графику к Retina-дисплею — это просто разделить пополам физические размеры изображения. Например, чтобы показать фотографию 200x300 пикселей на экране с увеличенной плотностью пикселов, необходимо загрузить фото размером 400x600 пикселей и уменьшить его, используя CSS-аттрибуты или HTML-параметры. Таким будет отображение на обычном экране:
А таким на Retina:
Есть несколько способов реализации HTML и CSS-масштабирования:
HTML
Самый простой способ — просто задать параметры width и height тегу img:
<img src="example@2x.png" width="200" height="300" />
Где использовать: на одностраничных сайтах с несколькими изображениями.
Javascript
Такого же результата можно добиться, используя Javascript для того, чтобы делить пополам размеры изображений для Retina-экранов. С использованием библиотеки jQuery это выглядит так:
$(window).load(function() {
var images = $('img');
images.each(function(i) {
$(this).width($(this).width() / 2);
});
});
Где использовать: на сайтах с несколькими изображениями в контенте.
CSS (SCSS)
Также можно использовать изображение в качестве фона с необходимыми размерами (background-size) определенного div'а. Параметр background-size не поддерживается в IE 7 и 8.
.image {
background-image: url(example@2x.png);
background-size: 200px 300px;
/* Alternatively background-size: contain; */
height: 300px;
width: 200px;
}
Можно использовать псевдоэлементы :before или :after
.image-container:before {
background-image: url(example@2x.png);
background-size: 200px 300px;
content:'';
display: block;
height: 300px;
width: 200px;
}
Техника работает и при использовании спрайтов:
.icon {
background-image: url(example@2x.png);
background-size: 200px 300px;
height: 25px;
width: 25px;
&.trash {
background-position: 25px 0;
}
&.edit {
background-position: 25px 25px;
}
}
Где использовать: на сайтах с ограниченным количеством фоновых изображений (например одним в качестве спрайта).
HTML и CSS-масштабирование: плюсы
- Простота реализации
- Кроссбраузерность
HTML и CSS-масштабирование: минусы
- Устройства и обычными экранами будут скачивать лишние мегабайты
- На обычных экранах четкость изображений может пострадать из-за алгоритмов сжатия
- Параметр background-size не поддерживается в IE 7 и 8.
Определение плотности пикселей экрана
Возможно это самый популярный способ оптимизации графики для Retina-дисплеев. Используется CSS или Javascript.
CSS
В этом способе используется device-pixel-ratio, чтобы установить нужное соотношение между физическими и CSS-пикселями:
.icon {
background-image: url(example.png);
background-size: 200px 300px;
height: 300px;
width: 200px;
}
@media only screen and (-Webkit-min-device-pixel-ratio: 1.5),
only screen and (-moz-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min-device-pixel-ratio: 1.5) {
.icon {
background-image: url(example@2x.png);
}
}
Где использовать: на сайтах или в приложениях, в которых применяется background-image для элементов дизайна. Не подходит для изображений внутри контента.
Плюсы
- Устройства не скачивают лишние изображения
- Кроссбраузерность
- Контроль плотности пикселей на сайте
Минусы
- Утомительно внедрять, особенно на крупных сайтах
- Использование изображения контента в качестве фона семантически некорректно
Javascript
Того же результата можно добиться, используя window.devicePixelRatio:
$(document).ready(function(){
if (window.devicePixelRatio > 1) {
var lowresImages = $('img');
images.each(function(i) {
var lowres = $(this).attr('src');
var highres = lowres.replace(".", "@2x.");
$(this).attr('src', highres);
});
}
});
Существует специальный Javascript плагин Retina.js, который умеет делать все вышеописанное, но с дополнительными возможностями, такими как пропуск внешних изображений и пропуск внутренних, но не имеющих retina-копий.
Где использовать: на любых сайтах с изображениями в контенте.
Плюсы
- Простота внедрения
- Устройства не скачивают лишние изображения
- Контроль плотности пикселей на сайте
Минусы
- Retina-устройства скачивают оба варианта каждого изображения
- Подмена изображений заметна на retina-устройствах
- Не работает в некоторых популярных браузерах (IE и Firefox)
Масштабируемая векторная графика
Вне зависимости от используемого метода растровые изображения по своей природе остаются ограниченными в масштабировании. Тут нам может помощь векторная графика. SVG (Scalable Vector Graphics) формат на основе XML поддерживается большинством браузеров. Самый простой способ использования SVG-изображений — в теге img или CSS-параметрами background-image и content:url().
В этом примере простое SVG-изображение может быть как угодно масштабировано:
<img src="example.svg" width="200" height="300" />
То же самое получится с применением CSS:
/* Использование фонового изображения */
.image {
background-image: url(example.svg);
background-size: 200px 300px;
height: 200px;
width: 300px;
}
/* Использование content:url() */
.image-container:before {
content: url(example.svg);
/* width and height do not work with content:url() */
}
Для поддержки IE 7 или 8 и Android 2.x потребуется использование заменяющих PNG-изображений. Это можно легко сделать с помощью Modernizr:
.image {
background-image: url(example.png);
background-size: 200px 300px;
}
.svg {
.image {
background-image: url(example.svg);
}
}
Для лучшей кроссбраузерности, чтобы избежать проблем растеризации в Firefox и Opera, следует сделать каждое SVG- изображение соответствующим его родительскому HTML-элементу.
В HTML можно реализовать аналогичное с помощью нужного data в теге a:
<img src="example.svg" data-png-fallback="example.png" />
С использованием jQuery и Modernizr:
$(document).ready(function(){
if(!Modernizr.svg) {
var images = $('img[data-png-fallback]');
images.each(function(i) {
$(this).attr('src', $(this).data('png-fallback'));
});
}
});
Где использовать: на любых сайтах, подходит для иконок, логотипов и простых векторных иллюстраций.
Плюсы
- Единый набор изображений для всех устройств
- Простота реализации
- Бесконечное масштабирование
Минусы
- Нет точного сглаживания «до пикселя»
- Не подходит для сложной графики из-за больших размеров файла
- Нет встроенной поддержки в IE 7, 8 и в ранних версиях Android
Иконочные шрифты
Популярный благодаря Twitter Botstrap способ, заключается в замене букв в шрифте на нужные символы с последующим их отображением на странице с помощью CSS. Существует множество иконочных шрифтов с символами на любой вкус, но можно также создать свой с помощью Fontello, Font Builder или даже Inkscape.
Наиболее распространенный способ использования иконочных шрифтов — это применение нужного класса к определенному элементу страницы:
<span class="icon">a</span>
А в стилях указывается нужный шрифт:
.icon {
font-family: 'My Icon Font';
}
Таже можно использовать псевдоэлемент :before и параметр content с уникальным классом к каждой иконке:
<span class="glyph-heart"></span>
[class^="glyph-"]:before {
font-family: 'My Icon Font';
}
.glyph-heart:before {
content: 'h';
}
Где использовать: на сайтах с большим количеством иконок и для быстрого прототипирования.
Плюсы
- Бесконечное масштабирование
- Кроссбраузерность
- Более универсальное решение, чем набор графических элементов
Минусы
- Нет точного сглаживания «до пикселя»
- Сложность реализации: отдельный символ шрифта к каждой иконке
- Способ основан на семантически некорректной разметке
Favicon
Favicon'ки все чаще используется вне браузера в качестве графического представления сайта или приложения. Чтобы оптимизировать favicon для Retina-устройств, необходимо подготовить .ico в двух размерах: 16x16 и 32x32 пикселей.
Взгляд в будущее
Существует специальный -Webkit-image-set от Apple, представленный весной, который позволяет использовать несколько вариантов одного изображения в CSS:
.image {
background-image: -Webkit-image-set(url(example.png) 1x, url(example@2x.png) 2x);
background-size: 200px 300px;
}
Но этот способ не распространяется на изображения внутри тега img.
Еще одно инструмент — Picturefill, автор Scott Jehl. Это HTML и Javascript решение:
<div data-picture>
<div data-src="example.png"></div>
<div data-src="example@2x.png" data-media="(min-device-pixel-ratio: 1.5)"></div>
<!-- Fallback content for non-JS browsers -->
<noscript>
<img src="example.png" >
</noscript>
</div>
Несмотря на такую разметку, это вполне нормальное кроссбраузерное решение.
Еще одно амбициозное предложение — использование элемента picture, который позволяет использовать несколько адаптивных изображений, заменяющих друг друга в зависимости от размера и плотности пикселей экрана
Заключение
Как и многие другие большие изменения в веб-дизайне, поиск универсального решения для изображений на Retina-устройствах будет долгим. Можно сидеть и ждать его, а можно уже сейчас делать сайты, которые приятно посещать с любых устройств.
Автор: grokru