Skip to content

Instantly share code, notes, and snippets.

@cfxd
Last active May 7, 2022 07:13
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cfxd/cf83bc8477008848d40db8a5079e8b66 to your computer and use it in GitHub Desktop.
Save cfxd/cf83bc8477008848d40db8a5079e8b66 to your computer and use it in GitHub Desktop.
Efficient Responsive Images in WordPress. See https://cfxdesign.com/efficient-responsive-images-in-wordpress
<?php
/*
* THE FILTER
*
*/
function custom_responsive_image_sizes($sizes, $img_name, $attachment_id) {
$sizes = wp_get_attachment_image_sizes($attachment_id, 'original');
$meta = wp_get_attachment_metadata($attachment_id);
$width = $meta['width'];
if(!$width) {
return $sizes;
}
if('long_example_image' == $img_name) {
$sizes = '(max-width: 1337px) 1337px, 100vw';
}
return $sizes;
}
add_filter('responsive_image_sizes', 'custom_responsive_image_sizes', 10, 3);
<?php
/**
* Get an HTML img element representing an image attachment while allowing
* custom image names and individual size/srcset filtering
*
* @param int $attachment_id Image attachment ID.
* @param string $name Optional. Custom image name used for filtering purposes. Default
* 'default'.
* @param string|array $size Optional. Image size. Accepts any valid image size, or an array of width
* and height values in pixels (in that order). Default 'original'.
* @param bool $icon Optional. Whether the image should be treated as an icon. Default false.
* @param string|array $attr Optional. Attributes for the image markup. Default are filtered responsive
* attributes.
* @return string HTML img element or empty string on failure.
*/
function get_responsive_attachment_image($attachment_id, $name = 'default', $size = 'original', $icon = false, $attr = '') {
if(!$attachment_id) {
return false;
}
$src = wp_get_attachment_image_src($attachment_id, $size, $icon);
if(!$src) {
return false;
}
$default_attr = array(
'srcset' => apply_filters('responsive_image_srcset', false, $name, $attachment_id),
'sizes' => apply_filters('responsive_image_sizes', false, $name, $attachment_id)
);
$attr = wp_parse_args($attr, $default_attr);
$img = wp_get_attachment_image($attachment_id, $size, false, $attr);
return $img;
}
function responsive_image_sizes($sizes, $img_name, $attachment_id) {
$sizes = wp_get_attachment_image_sizes($attachment_id, 'original');
$meta = wp_get_attachment_metadata($attachment_id);
$width = $meta['width'];
if(!$width) {
return $sizes;
}
if('my_custom_image_name' == $img_name) {
$sizes = '';
$media_queries = array(
'(max-width: 575.98px) 576px',
'(max-width: 575.98px) and (min-resolution: 161dpi) 1152px',
'(max-width: 767.98px) 768px',
'(max-width: 767.98px) and (min-resolution: 161dpi) 1536px',
'(max-width: 991.98px) 992px',
'(max-width: 991.98px) and (min-resolution: 161dpi) 1984px',
'(max-width: 1199.98px) 1200px',
'(max-width: 1199.98px) and (min-resolution: 161dpi) 2400px',
'(min-resolution: 161dpi) 200vw',
'100vw',
);
$sizes = sprintf('%s', implode(', ', $media_queries));
}
return $sizes;
}
add_filter('responsive_image_sizes', 'responsive_image_sizes', 10, 3);
<?php
/**
* FINAL SOLUTION TEMPLATE FILE
*
* This snippet goes in a template file.
*/
$image = get_field('my_image');
?>
<div class="example">
<?php echo get_responsive_attachment_image($image['ID'], 'my_custom_image_name'); ?>
</div>
<?php
/**
* Get an HTML img element representing an image attachment while allowing
* custom image names and individual size/srcset filtering
*
* @param int $attachment_id Image attachment ID.
* @param string $name Optional. Custom image name used for filtering purposes. Default
* 'default'.
* @param string|array $size Optional. Image size. Accepts any valid image size, or an array of width
* and height values in pixels (in that order). Default 'original'.
* @param bool $icon Optional. Whether the image should be treated as an icon. Default false.
* @param string|array $attr Optional. Attributes for the image markup. Default are filtered responsive
* attributes.
* @return string HTML img element or empty string on failure.
*/
function get_responsive_attachment_image($attachment_id, $name = 'default', $size = 'original', $icon = false, $attr = '') {
if(!$attachment_id) {
return false;
}
$src = wp_get_attachment_image_src($attachment_id, $size, $icon);
if(!$src) {
return false;
}
$default_attr = array(
'srcset' => apply_filters('responsive_image_srcset', false, $name, $attachment_id),
'sizes' => apply_filters('responsive_image_sizes', false, $name, $attachment_id)
);
$attr = wp_parse_args($attr, $default_attr);
$img = wp_get_attachment_image($attachment_id, $size, false, $attr);
return $img;
}
<?php
/**
* EXAMPLE 1
*
* This will *NOT* work because WordPress will not genereate responsive
* image attributes. This example assumes you're using Advanced Custom
* Fields for your image.
*/
$image = get_field('my_image');
?>
<div class="example">
<img src="<?php echo $image['url']; ?>">
</div>
<?php
/**
* EXAMPLE 2
*
* This will work, but doesn't allow much control over the responsive
* image attributes.
*/
$image = get_field('my_image');
?>
<div class="example">
<?php echo wp_get_attachment_image($image['ID'], 'original'); ?>
</div>
<?php
/**
* LONG SOLUTION
*
* This solution with custom filters will work, but we can do better
* and keep our template cleaner and more consistent.
*/
$image = get_field('my_image');
$img = wp_get_attachment_image($attachment_id, $thumbnail_size, false, array(
'srcset' => apply_filters('responsive_image_srcset', false, 'long_example_image', $attachment_id),
'sizes' => apply_filters('responsive_image_sizes', false, 'long_example_image', $attachment_id)
));
?>
<div class="example">
<?php echo $img; ?>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment