Make WordPress Core


Ignore:
Timestamp:
11/18/2024 07:50:06 PM (13 days ago)
Author:
flixos90
Message:

Media: Avoid images with sizes=auto to be displayed downsized in supporting browsers.

Based on the user agent stylesheet rules outlined in https://html.spec.whatwg.org/multipage/rendering.html#img-contain-size, images that have sizes=auto while applying width: auto or width: fit-content would be constrained to only 300px width.

This changeset overrides said user agent stylesheet rule with a much larger constraint, to avoid the problem.

Additionally, it introduces a filter wp_img_tag_add_auto_sizes which can be used to opt out of the functionality, as an additional measure.

Props joemcgill, flixos90, dooperweb, SirLouen, azaozz, mukesh27, apermo.
Fixes #62413.
See #61847, #62345.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/media.php

    r59406 r59415  
    11381138        }
    11391139
     1140        /** This filter is documented in wp-includes/media.php */
     1141        $add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true );
     1142
    11401143        // Adds 'auto' to the sizes attribute if applicable.
    11411144        if (
     1145            $add_auto_sizes &&
    11421146            isset( $attr['loading'] ) &&
    11431147            'lazy' === $attr['loading'] &&
     
    19861990 */
    19871991function wp_img_tag_add_auto_sizes( string $image ): string {
     1992    /**
     1993     * Filters whether auto-sizes for lazy loaded images is enabled.
     1994     *
     1995     * @since 6.7.1
     1996     *
     1997     * @param boolean $enabled Whether auto-sizes for lazy loaded images is enabled.
     1998     */
     1999    if ( ! apply_filters( 'wp_img_tag_add_auto_sizes', true ) ) {
     2000        return $image;
     2001    }
     2002
    19882003    $processor = new WP_HTML_Tag_Processor( $image );
    19892004
     
    19942009
    19952010    // Bail early if the image is not lazy-loaded.
    1996     $value = $processor->get_attribute( 'loading' );
    1997     if ( ! is_string( $value ) || 'lazy' !== strtolower( trim( $value, " \t\f\r\n" ) ) ) {
     2011    $loading = $processor->get_attribute( 'loading' );
     2012    if ( ! is_string( $loading ) || 'lazy' !== strtolower( trim( $loading, " \t\f\r\n" ) ) ) {
     2013        return $image;
     2014    }
     2015
     2016    /*
     2017     * Bail early if the image doesn't have a width attribute.
     2018     * Per WordPress Core itself, lazy-loaded images should always have a width attribute.
     2019     * However, it is possible that lazy-loading could be added by a plugin, where we don't have that guarantee.
     2020     * As such, it still makes sense to ensure presence of a width attribute here in order to use `sizes=auto`.
     2021     */
     2022    $width = $processor->get_attribute( 'width' );
     2023    if ( ! is_string( $width ) || '' === $width ) {
    19982024        return $image;
    19992025    }
     
    20282054    list( $first_size ) = explode( ',', $sizes_attr, 2 );
    20292055    return 'auto' === strtolower( trim( $first_size, " \t\f\r\n" ) );
     2056}
     2057
     2058/**
     2059 * Prints a CSS rule to fix potential visual issues with images using `sizes=auto`.
     2060 *
     2061 * This rule overrides the similar rule in the default user agent stylesheet, to avoid images that use e.g.
     2062 * `width: auto` or `width: fit-content` to appear smaller.
     2063 *
     2064 * @since 6.7.1
     2065 * @see https://html.spec.whatwg.org/multipage/rendering.html#img-contain-size
     2066 * @see https://core.trac.wordpress.org/ticket/62413
     2067 */
     2068function wp_print_auto_sizes_contain_css_fix() {
     2069    /** This filter is documented in wp-includes/media.php */
     2070    $add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true );
     2071    if ( ! $add_auto_sizes ) {
     2072        return;
     2073    }
     2074
     2075    ?>
     2076    <style>img:is([sizes="auto" i], [sizes^="auto," i]) { contain-intrinsic-size: 3000px 1500px }</style>
     2077    <?php
    20302078}
    20312079
Note: See TracChangeset for help on using the changeset viewer.