Search code examples
phphtmlwordpressresponsive-designresponsive-images

WordPress: Use <picture>-tag with wp_get_attachment_image


I want to use the <picure>-tag with the function wp_get_attachment_image. At the moment I'm getting an <img>-tag with srcset. That's nice but is there any way to change it to a <picure>-tag with multiple sources in it? Like this:

<picture>
  <source media="(min-width: 56.25em)" srcset="large.jpg 1x, [email protected] 2x">
  <source media="(min-width: 37.5em)" srcset="medium.jpg 1x, [email protected] 2x">
  <source srcset="small.jpg 1x, [email protected] 2x">
  <img src="fallback.jpg" alt="">
</picture>

I need that because I want to display a second version of the image. So I can have horizontal and vertical images in one <picture>-tag. Like this:

<picture>
  <source media="(min-width: 38em)" srcset="art-direction-horizontal.jpg">
  <source srcset="art-direction-vertical.jpg">
  <img src="art-direction-vertical.jpg" alt="">
</picture>

Solution

  • Since 5.6.0, We get a way to wrap img elements.

    apply_filters( 'wp_get_attachment_image', $html, $attachment_id, $size, $icon, $attr );
    

    The filter does not extract post_id but attachment_id. So if you want to activate the function systematically, You should link an attachment and its mobile image via post meta.

    function wrap_wp_get_attachment_image_with_picture_tag( $html, $attachment_id, $size, $icon, $attr ){
        if ( is_admin() || $size == 'medium' || $size == 'thumbnail' ) return $html;
        if ( $mobile_id = get_post_meta( $attachment_id, '_meta_key_of_mobile_picuture_id', true ) ){
            $mobile_srcset = wp_get_attachment_image_srcset( $mobile_id, 'medium_large' );
            $html = '<picture><source media="( max-width : 782px )" srcset="'.$mobile_srcset.'">'.$html.'</picture>';
        }
        return $html;
    }
    add_filter( 'wp_get_attachment_image', 'wrap_wp_get_attachment_image_with_picture_tag', 10, 5 );