Адаптивные изображения в WordPress 4.4+

К написанию поста меня вдохновил вот этот комментарий.

Те, кто уже обновились до версии WordPress 4.4, могли заметить, что изменился HTML вывода изображений на сайте. По сути это касается изображений как в старых постах, так и в новых, которые вы только будете создавать. А именно — на тег <img> добавилось два атрибута scrset и sizes.

Как же работают scrset и sizes?

Переносы строк я добавил просто для наглядности:

<img src="image.jpg" srcset="image-300x200.jpg 300w,
			     image-700x620.jpg 700w,
			     image-1024x680.jpg 1024w,
			     image-1200x800.jpg 1200w" sizes="(max-width: 700px) 85vw,
							      (max-width: 1024px) 67vw,
							      (max-width: 1362px) 62vw, 
							      860px" />

Что же означает запись подобного рода?

  • scrset — если размер изображения на странице 300px или меньше, то будет использоваться image-300×200.jpg, если от 300px до 700px то image-700×620.jpg. В случае, если ни одно из условий не удовлетворится, то image.jpg.
  • sizes — по сути это максимальный размер изображения для определенных условий. То есть например при условии, что максмальный размер окна браузера (ширина) 700px, то изображение должно быть не шире, чем 85% по отношению к ней.

Вообще моя статья ориентируется больше на то, как работать с этим в WordPress, поэтому тут я и закончу.

Что же касается поддержки браузерами, то это Firefox 41+, Safari 9+, Opera 33+, iOS 9.0, Edge 13+ и Chrome 43+. IE не поддерживает вообще. C одной стороны может показаться, что не очень много, но плюс в том, что пользователям старых девайсов/браузеров будет просто показываться обычное изображение, взятое из атрибута src.

Как работать с адаптивными изображениями в WordPress 4.4+

Возможно первый вопрос, который встаёт перед нами, разработчиками — это то, как WP добавляет атрибуты изображениям. Очень просто, через фильтр the_content, если:

  • изображение имеет класс wp-image-{ID_изображения},
  • у изображения отсутствуют scrset / sizes атрибуты.

Как попросить WordPrеss не добавлять «адаптивные атрибуты» на изображения.

Тут есть два способа, либо вы удаляете класс wp-image-{ID_изображения} с тех изображений, с которых захотите, либо, если вам нужно запретить это глобально, то вставляете в functions.php:

remove_filter( 'the_content', 'wp_make_content_images_responsive' );

Как добавить атрибуты scrset и sizes через код самому.

<img src="<?php echo wp_get_attachment_image_url( $media_id, 'large' ) ?>"
     srcset="<?php echo wp_get_attachment_image_srcset( $media_id, 'large' ) ?>"
     sizes="<?php echo wp_get_attachment_image_sizes( $media_id, 'large' ) ?>" />

Ни одной из этих функций у меня в Кодексе нет, поэтому опишу их прямо здесь.

  • wp_get_attachment_image_url() возвращает URL копии изображения указанного размера (в примере — large).
  • wp_get_attachment_image_srcset() функция пропускает через цикл все зарегистрированные размеры изображений и добавляет их в атрибут scrset в следующем формате: image-{ШИРИНА}x{ВЫСОТА}.jpg {ШИРИНА}w. Обратите внимание, что функция игнорирует:
    • копии изображения других пропорций (если отношение ширины к высоте отличается больше, чем на 0.002)
    • отредактированные копии изображений
    • копии изображений, которые превышают по ширине максимально допустимое значение scrset (если не изменено в фильтрах, то 1600)
  • wp_get_attachment_image_sizes() если темы или плагины не добавили своих фильтров на эту функцию, то она возвращает следующее: (max-width: {ШИРИНА}px) 100vw, {ШИРИНА}px, где {ШИРИНА} это фактическая ширина файла в пикселях.

Как приспособить копии изображений с другими пропорциями для мобильных устройств

Для того, чтобы понять, что я имею ввиду, взгляните на наглядный пример:

Адаптивные изображения в WordPress

Не знаю, как вы, но я считаю, что на маленьких девайсах правое изображение будет выглядеть лучше (даже если со зрением у вас всё окей). Но я уже писал выше, что WordPress не станет добавлять в scrset изображения с другими пропорциями. Что делать?

Ну для начала мы добавим свой размер в scrset принудительно:

function misha_custom_razmer( $sources, $size_array, $img_src, $img_metadata, $attachment_id ){
 
	$img_size_name = 's500'; // ваш размер изображения, добавленный через add_image_size('s500', 500, 500, true);
 
	$upload_dir = wp_upload_dir();
 
	// знаю, что мог использовать wp_get_attachment_image_url() для получения URL изображения
	// но я хотел использовать только те данные, которые имеются, с минимумом доп. функций
	$img_url = $upload_dir['baseurl'] . '/' . str_replace( basename( $img_metadata['file'] ), $img_metadata['sizes'][$img_size_name]['file'], $img_metadata['file'] );
 
	$sources[ 500 ] = array( // добавляем свой размер в общий список размеров sources
		'url'        => $img_url,
		'descriptor' => 'w',
		'value'      => $breakpoint,
	);
	return $sources;
}
 
add_filter('wp_calculate_image_srcset', 'misha_custom_razmer', 10, 5);

Фильтр написал сам, если будут предложения по его доработке — буду рад выслушать.

А затем воспользуемся плагином Manual Image Crop чтобы вручную выбрать область обрезки — это очень удобно и круто!

Вот по сути и всё. Любые возникшие вопросы — в комментарии.

Подпишитесь, чтобы раз в неделю получать свежие статьи с блога по email.

Смотрите также

Комментарии 11

  • Егор19 декабря 2015 в 07:12 #

    Здравствуй, Миша. Вот в новой теме WP подгонка картинок

    /**
     * Add custom image sizes attribute to enhance responsive image functionality
     * for content images
     *
     * @since Twenty Sixteen 1.0
     *
     * @param string $sizes A source size value for use in a 'sizes' attribute.
     * @param array  $size  Image size. Accepts an array of width and height
     *                      values in pixels (in that order).
     * @return string A source size value for use in a content image 'sizes' attribute.
     */
    function twentysixteen_content_image_sizes_attr( $sizes, $size ) {
    	$width = $size[0];
     
    	840 <= $width && $sizes = '(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px';
     
    	if ( 'page' === get_post_type() ) {
    		840 > $width && $sizes = '(max-width: ' . $width . 'px) 85vw, ' . $width . 'px';
    	} else {
    		840 > $width && 600 <= $width && $sizes = '(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px';
    		600 > $width && $sizes = '(max-width: ' . $width . 'px) 85vw, ' . $width . 'px';
    	}
     
    	return $sizes;
    }
    add_filter( 'wp_calculate_image_sizes', 'twentysixteen_content_image_sizes_attr', 10 , 2 );
     
    /**
     * Add custom image sizes attribute to enhance responsive image functionality
     * for post thumbnails
     *
     * @since Twenty Sixteen 1.0
     *
     * @param array $attr Attributes for the image markup.
     * @param int   $attachment Image attachment ID.
     * @param array $size Registered image size or flat array of height and width dimensions.
     * @return string A source size value for use in a post thumbnail 'sizes' attribute.
     */
    function twentysixteen_post_thumbnail_sizes_attr( $attr, $attachment, $size ) {
    	if ( 'post-thumbnail' === $size ) {
    		is_active_sidebar( 'sidebar-1' ) && $attr['sizes'] = '(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 60vw, (max-width: 1362px) 62vw, 840px';
    		! is_active_sidebar( 'sidebar-1' ) && $attr['sizes'] = '(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 88vw, 1200px';
    	}
    	return $attr;
    }
    add_filter( 'wp_get_attachment_image_attributes', 'twentysixteen_post_thumbnail_sizes_attr', 10 , 3 );
  • Александр20 декабря 2015 в 02:12 #

    Обновился, но атрибуты scrset и sizes и не появилось. Подскажите, что может быть.

  • Александр31 декабря 2015 в 12:12 #

    А возможно ли это использовать в том случае, когда изображение подставляем фоном к блоку?
    Сейчас же все адаптивное нужно, а там есть cover. Например, и в шапку ставлю, и вывод миниатюр в ленте и пр.

  • Алекс18 января 2016 в 21:01 #

    После обновления WP добавились srcset к изображениям, причем выборочно, к каким-то добавилось, а к каким-то нет. На iphone(Safari) перестали картинки с srcset отображаться, просто пустое место.
    Решил проблему этим:
    remove_filter( 'the_content', 'wp_make_content_images_responsive' );

    Напридумывают всякое, что потом не работает или только на Айфоне так)

Оставить комментарий / вопрос

phpjsHTMLCSSSQLПросто код
  Для того, чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или авторизуйтесь на сайте.
Получайте новости блога по email или следите за мной в социальных сетях.
  • Миша: Да, точно)

  • Владимир: и на третьей строке не хватает скобки ) закрывающей if :)

  • Миша: Добрый вечер! Рекомендую получить ID пользователя через функцию get_current_user_id().

  • Дмитрий: Миша, подскажите пожалуйста, я использую такой редирект, но он не срабатывает: add_action( 'template_redirect', funct...

  • Миша: Ну как не определена - это аргумент функции. Или я просто вас не до конца понимаю.