12 июня 2017

Использование srcset для адаптивных изображений

Часто возникает желание использовать адаптивные по ширине изображения: на десктопной версии, в анонсах постов, они маленькие; сжимаем окно браузера — анонсы расширяются, а с ними растет размер изображения.

Вот, например, сайт одной газеты, которым мы занимаемся.

1. Десктопное разрешение. Ширина изображения анонсы 322 пксл.

Маленькие анонсы

2. Сжимаем браузер. Анонсов в горизонтали становится меньше, при этом ширина изображения увеличивается до 410 пксл.

Среднее разрешение, картина уже больше

3. Если еще сжать браузер, анонс в горизонтали останется один и ширина изображения станет самой большой (656 пксл). Как видно из скриншота ниже, качество изображения с мелкими деталями станет просто ужасным (если исходное изображение — десктопное и имеет ширину 322 пксл).

Плохое качество изображения анонса

Как же быть? Можно, конечно, сделать ширину изображения анонса 656 пксл (самое широкое, которое только может быть) и вывести его для всех ширин браузера. При этом браузер будет масштабировать в сторону уменьшения данное изображение без проблем. Но мы будем загружать пользователю большое изображение даже в том случае, когда оно ему не нужно.

На помощь приходит атрибут srcset тега img. Можете почитать по нему официальную документацию (текст на столько длинный, что браузер тормозит на моем вполне резвом компе). Смысл этого атрибута в том, чтобы через запятую перечислить URL различных вариантов изображения с различной шириной, а браузер сам решит, какой из предложенных вариантов окажется на данный момент оптимальным.

Стандартный вариант

<img src="/wp-content/cache/thumb/9712274fc_322x190.jpg" width="322" height="190" alt="Описание картинки">

Добавляю srcset исходя из нашей задачи

<img src="/wp-content/cache/thumb/9712274fc_322x190.jpg" width="322" height="190" alt="Описание картинки" srcset="/wp-content/cache/thumb/9712274fc_410x241.jpg 410w, /wp-content/cache/thumb/9712274fc_656x387.jpg 656w, /wp-content/cache/thumb/9712274fc_322x190.jpg 322w">

Только srcset:

srcset="/wp-content/cache/thumb/9712274fc_410x241.jpg 410w, /wp-content/cache/thumb/9712274fc_656x387.jpg 656w, /wp-content/cache/thumb/9712274fc_322x190.jpg 322w"

Как видите, скрипт создал копии изображения для нужных мне ширин. Рядом с URL я указал ширину изображения и перечислил их через запятую.

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

Чтобы HTML-валидатор не ругался, нужно добавить еще один атрибут тегу img: sizes="100vw". Странно, что валидатор без данного атрибута не пропускает тег img, т.к., согласно спецификации, его может и не быть.

Поскольку я работаю с WordPress (чего и вам желаю), для построения миниатюр заданного размера использую плагин Kama Thumbnail. После установки плагин позволяет пользоваться своей функцией kama_thumb_src('w=' . $w . '&h=' . $h), где переменные w, h передают ширину и высоту создаваемой копии изображения, которое, после создания, кешируется. Прекрасный плагин =)

Чтобы ускорить процесс заполнения атрибутов srcset, я написал небольшую функцию.

function morkovin_get_srcset($width, $height, $array_srcset_width, $post_id, $def_src = "/images/no-photo.jpg") {
    if ( function_exists('kama_thumb_src') ) {
        $srcset_array = array();

        $array_srcset_width[] = $width;

        foreach ($array_srcset_width as $item_width) {
            $item_height = $item_width * $height / $width;
            if ( kama_thumb_src('w='.$item_width.'&h='.$item_height.'&post_id='.$post_id) ) {
                $srcset_array[] = kama_thumb_src('w='.$item_width.'&h='.$item_height.'&post_id='.$post_id).' '.$item_width.'w';
            } else {
                $srcset_array[] = kama_thumb_src('w='.$item_width.'&h='.$item_height.'&src='.get_stylesheet_directory_uri().$def_src).' '.$item_width.'w';
            }
        }

        $src_result = 'srcset="'.implode(", ", $srcset_array).'"';

        return $src_result;
    } else {
        return false;
    }
}

Первые два аргумента функции — это ширина и высота исходной картинки (в примере это 322*190 пксл). Далее идет массив, в котором через запятую нужно передать все дополнительные ширины изображений (высоты будут вычисляться по пропорции автоматически). $post_id — это идетификатор поста, который нужен функции kama_thumb_src, чтобы найти исходное изображения для анонса. Последний аргумент — это путь к картинке по-умолчанию (отображается, если изображение не задано), отсчитывается от папки с темой.

Пример использования функции.

$w = 322;
$h = 190;

$post_id = get_the_id();
$item_srcset = morkovin_get_srcset( $w, $h, array(410, 656), $post_id );


if (kama_thumb_src()) {
	echo '<img src="' . kama_thumb_src('w=' . $w . '&h=' . $h) . '" width="' . $w . '" height="' . $h . '" alt="' . get_the_title() . '" '.$item_srcset.' sizes="100vw"/>';
}
Плюсануть
Поделиться
Отправить
Класснуть
Линкануть
Запинить