responsive - How to exclude an image size from the Wordpress srcset

admin2025-06-07  28

Wordpress srcset is a great feature but there are occasions when it's important to control exactly which image sizes are included in the srcset code.

For example, on one of our sites we generate a custom image size which is ONLY intended for external use - this means an external sales portal collects this image automatically for display on their site. It is NOT intended for display anywhere on our site.

However, the Wordpress srcset functionality currently includes ALL image sizes. For example:

<img width="350" height="426" src="https://xxx/wp-content/uploads/omega-pink-gold-1235-1-350x426.jpg" class="attachment-shop_catalog size-shop_catalog" alt="xxx" srcset="https://xxx/.../omega-pink-gold-1235-1-350x426.jpg 350w, https://xxx/.../omega-pink-gold-1235-1-246x300.jpg 246w, https://xxx/.../omega-pink-gold-1235-1-768x935.jpg 768w, https://xxx/.../omega-pink-gold-1235-1-841x1024.jpg 841w, https://xxx/.../omega-pink-gold-1235-1-1051x1280.jpg 1051w, https://xxx/.../omega-pink-gold-1235-1-534x650.jpg 534w, https://xxx/.../omega-pink-gold-1235-1-104x127.jpg 104w, https://xxx/.../omega-pink-gold-1235-1-595x725.jpg 595w, https://xxx/.../omega-pink-gold-1235-1-680x828.jpg 680w" sizes="(max-width: 350px) 100vw, 350px" title="xxx">

How can we control this better?

Thanks in advance for any help!

Wordpress srcset is a great feature but there are occasions when it's important to control exactly which image sizes are included in the srcset code.

For example, on one of our sites we generate a custom image size which is ONLY intended for external use - this means an external sales portal collects this image automatically for display on their site. It is NOT intended for display anywhere on our site.

However, the Wordpress srcset functionality currently includes ALL image sizes. For example:

<img width="350" height="426" src="https://xxx/wp-content/uploads/omega-pink-gold-1235-1-350x426.jpg" class="attachment-shop_catalog size-shop_catalog" alt="xxx" srcset="https://xxx/.../omega-pink-gold-1235-1-350x426.jpg 350w, https://xxx/.../omega-pink-gold-1235-1-246x300.jpg 246w, https://xxx/.../omega-pink-gold-1235-1-768x935.jpg 768w, https://xxx/.../omega-pink-gold-1235-1-841x1024.jpg 841w, https://xxx/.../omega-pink-gold-1235-1-1051x1280.jpg 1051w, https://xxx/.../omega-pink-gold-1235-1-534x650.jpg 534w, https://xxx/.../omega-pink-gold-1235-1-104x127.jpg 104w, https://xxx/.../omega-pink-gold-1235-1-595x725.jpg 595w, https://xxx/.../omega-pink-gold-1235-1-680x828.jpg 680w" sizes="(max-width: 350px) 100vw, 350px" title="xxx">

How can we control this better?

Thanks in advance for any help!

Share Improve this question edited Jan 23, 2018 at 14:12 Richard Tinkler asked Jan 23, 2018 at 8:42 Richard TinklerRichard Tinkler 2455 silver badges14 bronze badges 3
  • srcset will only include images with a matching aspect ratio, so the image should just be the original image at a smaller size. What's the problem with it being used in the srcset if the browser finds it useful? – Jacob Peattie Commented Jan 23, 2018 at 9:00
  • Since you don't display the image on your own site and only make the full-res image available to a third-party site, there's no need to generate all other image sizes. That I get. But what does this have to do with srcset? Are you sending the full <img> tag to the external sales portal instead of just the image URL? – swissspidy Commented Jan 23, 2018 at 9:19
  • @JacobPeattie - the custom image size intended for external use is branded with a watermark and therefore should never display on our website, only on the external sales portal – Richard Tinkler Commented Jan 23, 2018 at 14:14
Add a comment  | 

2 Answers 2

Reset to default 3

WordPress allows you to hook into wp_calculate_image_srcset

See Core file on Trac

This filter gives you 5 arguments:

  • $sources One or more arrays of source data to include in the 'srcset'
  • $size_array Array of width and height values in pixels (in that order).
  • $image_src The 'src' of the image.
  • $image_meta The image meta data as returned by 'wp_get_attachment_metadata()
  • $attachment_id the post_id from the image

Here is a sample code you can use within your themes function.php or plugin files to get started:

add_filter( 'wp_calculate_image_srcset', 'my_custom_image_srcset', 10, 5);

function my_custom_image_srcset($sources, $size_array, $image_src, $image_meta, $attachment_id) {
    // The following code is an adaption from wp-includes/media.php:1061-1180
    $image_sizes = $image_meta['sizes'];

    // Get the width and height of the image.
    $image_width = (int) $size_array[0];
    $image_height = (int) $size_array[1];

    $image_basename = wp_basename( $image_meta['file'] );

    /*
     * WordPress flattens animated GIFs into one frame when generating intermediate sizes.
     * To avoid hiding animation in user content, if src is a full size GIF, a srcset attribute is not generated.
     * If src is an intermediate size GIF, the full size is excluded from srcset to keep a flattened GIF from becoming animated.
     */
    if ( ! isset( $image_sizes['thumbnail']['mime-type'] ) || 'image/gif' !== $image_sizes['thumbnail']['mime-type'] ) {
        $image_sizes[] = array(
            'width'  => $image_meta['width'],
            'height' => $image_meta['height'],
            'file'   => $image_basename,
        );
    } elseif ( strpos( $image_src, $image_meta['file'] ) ) {
        return false;
    }

    // Retrieve the uploads sub-directory from the full size image.
    $dirname = _wp_get_attachment_relative_path( $image_meta['file'] );

    if ( $dirname ) {
        $dirname = trailingslashit( $dirname );
    }

    $upload_dir = wp_get_upload_dir();
    $image_baseurl = trailingslashit( $upload_dir['baseurl'] ) . $dirname;

    /*
     * If currently on HTTPS, prefer HTTPS URLs when we know they're supported by the domain
     * (which is to say, when they share the domain name of the current request).
     */
    if ( is_ssl() && 'https' !== substr( $image_baseurl, 0, 5 ) && parse_url( $image_baseurl, PHP_URL_HOST ) === $_SERVER['HTTP_HOST'] ) {
        $image_baseurl = set_url_scheme( $image_baseurl, 'https' );
    }

    /*
     * Images that have been edited in WordPress after being uploaded will
     * contain a unique hash. Look for that hash and use it later to filter
     * out images that are leftovers from previous versions.
     */
    $image_edited = preg_match( '/-e[0-9]{13}/', wp_basename( $image_src ), $image_edit_hash );

    /**
     * Filters the maximum image width to be included in a 'srcset' attribute.
     *
     * @since 4.4.0
     *
     * @param int   $max_width  The maximum image width to be included in the 'srcset'. Default '1600'.
     * @param array $size_array Array of width and height values in pixels (in that order).
     */
    $max_srcset_image_width = apply_filters( 'max_srcset_image_width', 1600, $size_array );

    // Array to hold URL candidates.
    $sources = array();

    /**
     * To make sure the ID matches our image src, we will check to see if any sizes in our attachment
     * meta match our $image_src. If no matches are found we don't return a srcset to avoid serving
     * an incorrect image. See #35045.
     */
    $src_matched = false;

    /*
     * Loop through available images. Only use images that are resized
     * versions of the same edit.
     */
    foreach ( $image_sizes as $identifier => $image ) {
        // Continue if identifier is unwanted
        if ($identifier === 'unwanted-identifier') {
            continue;
        }

        $is_src = false;

        // Check if image meta isn't corrupted.
        if ( ! is_array( $image ) ) {
            continue;
        }

        // If the file name is part of the `src`, we've confirmed a match.
        if ( ! $src_matched && false !== strpos( $image_src, $dirname . $image['file'] ) ) {
            $src_matched = $is_src = true;
        }

        // Filter out images that are from previous edits.
        if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) {
            continue;
        }

        /*
         * Filters out images that are wider than '$max_srcset_image_width' unless
         * that file is in the 'src' attribute.
         */
        if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width && ! $is_src ) {
            continue;
        }

        // If the image dimensions are within 1px of the expected size, use it.
        if ( wp_image_matches_ratio( $image_width, $image_height, $image['width'], $image['height'] ) ) {
            // Add the URL, descriptor, and value to the sources array to be returned.
            $source = array(
                'url'        => $image_baseurl . $image['file'],
                'descriptor' => 'w',
                'value'      => $image['width'],
            );

            // The 'src' image has to be the first in the 'srcset', because of a bug in iOS8. See #35030.
            if ( $is_src ) {
                $sources = array( $image['width'] => $source ) + $sources;
            } else {
                $sources[ $image['width'] ] = $source;
            }
        }
    }
    return $sources;
}

WordPress adds scrset attributes via a filter attached the the the_content hook.

add_filter( 'the_content', 'wp_make_content_images_responsive' ); line 141 of wp-includes/default-filters.php.

You can remove this filter via the remove_filter function like so:

remove_filter( 'the_content', 'wp_make_content_images_responsive' );

The above will remove srcset attributes site-wide so you may want to look at using the template hierarchy or conditional tags to remove the filter only where needed.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1749257707a317671.html

最新回复(0)