Оптимизация графики для Retina-экранов
Добавлено 22.11.2015 в 15:06
Оптимизация графики для Retina-экранов
После выпуска Retina MacBook и 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-устройствах будет долгим. Можно сидеть и ждать его, а можно уже сейчас делать сайты, которые приятно посещать с любых устройств.
К материалу оставили 0 комментариев