Unterschiedliche Bilder für verschiedene Bildschirmgrößen ausgeben

Es ist schon etwas länger her, da ist auf „A list apart“ einen Artikel zum Responsive Web Design erschienen. Was mich damals am meisten fasziniert hat, war das Headerbild, welches sich abhängig von der Bildschirmgröße veränderte. Ein genialer Effekt und einfach umzusetzen. Nicht ganz so einfach, wenn das auch für Laien halbwegs bedienbar sein soll. Also habe ich mir dazu mal schnell einen kleinen Shortcode geschrieben.

Zuerst war noch die Frage ob ich das Ganze mit srcset oder mit dem Picture-Element umsetze. Aber ein Blick in den Quelltext bei „A list apart“ zeigte das Picture-Element und als ich dann beim Mozilla Developer Network noch eine Rubrik Art Direction in der genau diese Technik ebenfalls mit dem Picture-Element beschrieben wurde, war meine Entscheidung klar.

Der Shortcode ist sehr simpel und lässt sich sicher kürzer schreiben. Aber für das einfachere Erfassen habe ich es mal in dieser langen Form belassen.

Zuerst werden die möglichen Attribute definiert mobile, tablet, desktop und desktop-wide. Für diese vier Viewport-Größen können Bild-IDs angeben werden. Wer diese IDs schnell einsehbar haben möchte, der kann sich zum Beispiel das Plugin Reveal-IDs installieren.

    $atts = shortcode_atts(
        array(
            'mobile' => '',
            'tablet' => '',
            'desktop' => '',
            'desktop-wide' => '',
        ),
        $atts,
        'respimg'
    );

Danach wird das Array mit den Bilddaten gespeichert und zwar jede der vier Größen, sofern die ID gesetzt wurde. Dabei wird die Originalgröße benutzt.

    if ( $atts['mobile'] ) {
        $imageurl[1] = wp_get_attachment_image_src( absint( $atts['mobile'] ), 'full' );
    }

Nun wird die Ausgabe zusammengebaut. Erst das Picture-Element öffnen inklusive einer Klasse für ein Styling, dann werden die Bildquellen mit einem Media Query angegeben. Alles bis 767 Pixel bekommt die Mobile-Version. Von 768 bis 1024 Pixel wird die Tablet-Version ausgegeben. Über 1024 bis 1440 Pixel kommt eine Desktop-Version. Und über 1440 Pixel wird eine breite Desktop-Version ausgegeben. Das Bilddaten-Array, welches per wp_get_attachment_image_src besteht aus URL [0] sowie Breite [1] und Höhe [2]. Am Ende wird das zweitgrößte Bild, also die Desktop-Version noch als Wert für das IMG-Element gesetzt, sofern Browser das Picture-Element nicht verstehen und diesen Fallback nutzen müssen.

    $html_output = '';

    $html_output .= '<picture class="respimg">';
    $html_output .= '  <source media="(max-width: 767px)" srcset="'. $imageurl[1][0] . '">';
    $html_output .= '  <source media="(min-width: 768px) and (max-width: 1024px)" srcset="'. $imageurl[2][0] . '">';
    $html_output .= '  <source media="(min-width: 1025px) and (max-width: 1440px)" srcset="'. $imageurl[3][0] . '">';
    $html_output .= '  <source media="(min-width: 1441px)" srcset="'. $imageurl[4][0] . '">';
    $html_output .= '  <img src="'. $imageurl[3][0] . '" width="'. $imageurl[3][1] . '" height="'. $imageurl[3][2] . '" class="respimg-img">';
    $html_output .= '</picture>';

    return $html_output;

Wenn alles klappt und du einen modernen Browser nutzt, dann sollte hier meine Website in einem Smartphone, einem Tablet, einem Laptop oder einem iMac angezeigt werden.. Je nachdem wie groß dein Viewport gerade ist. Dabei wurde folgender Code genutzt (die IDs müssen natürlich angepasst werden):

[respimg mobile="1116" tablet="1117" desktop="1119" desktop-wide="1118"]

Und hier nochmal der gesamte Quelltext am Stück:

/**
 * Art Direction Shortcode for responsive Images ====================================================================================
 * Usage: [respimg mobile="" tablet="" desktop="" desktop-wide=""]
 * Each attribute gets his own media id
 */
function art_direction_shortcode( $atts, $content = null ) {

    // Attributes
    $atts = shortcode_atts(
        array(
            'mobile' => '',
            'tablet' => '',
            'desktop' => '',
            'desktop-wide' => '',
        ),
        $atts,
        'respimg'
    );
   
    if ( $atts['mobile'] ) {
        $imageurl[1] = wp_get_attachment_image_src( absint( $atts['mobile'] ), 'full' );
    }

    if ( $atts['tablet'] ) {
        $imageurl[2] = wp_get_attachment_image_src( absint( $atts['tablet'] ), 'full' );
    }

    if ( $atts['desktop'] ) {
        $imageurl[3] = wp_get_attachment_image_src( absint( $atts['desktop'] ), 'full' );
    }

    if ( $atts['desktop-wide'] ) {
        $imageurl[4] = wp_get_attachment_image_src( absint( $atts['desktop-wide'] ), 'full' );
    }

    $html_output = '';

    $html_output .= '<picture class="respimg">';
    $html_output .= '  <source media="(max-width: 767px)" srcset="'. $imageurl[1][0] . '">';
    $html_output .= '  <source media="(min-width: 768px) and (max-width: 1024px)" srcset="'. $imageurl[2][0] . '">';
    $html_output .= '  <source media="(min-width: 1025px) and (max-width: 1440px)" srcset="'. $imageurl[3][0] . '">';
    $html_output .= '  <source media="(min-width: 1441px)" srcset="'. $imageurl[4][0] . '">';
    $html_output .= '  <img src="'. $imageurl[4][0] . '" width="'. $imageurl[4][1] . '" height="'. $imageurl[4][2] . '" class="respimg-img" alt="">';
    $html_output .= '</picture>';

    return $html_output;

}
add_shortcode( 'respimg', 'art_direction_shortcode' );

Habe ich was übersehen? Sollte ich etwas ergänzen oder verbessern? Ich freue mich über Hinweise in den Kommentaren!

3 Antworten auf Unterschiedliche Bilder für verschiedene Bildschirmgrößen ausgeben

  1. Hallo Torsten,
    Der Code sieht sehr interessant aus und ich möchte ihn gerne auch mal in einem Projekt benützen. Bei mir funktioniert das Umswitchen des Bildes, wenn ich den Viewport verändere. Meine erste Frage wäre nämlich sonst gewesen, was passiert, wenn jemand eine Seite zuerst im Tab im Hochformat lädt und dann das Tab auf Querformat dreht. Interessant ist hier, dass auch nach dem Verkleinern des Viewports das desktop.png als Bild angegeben wird, obwohl mir das mobile.png angezeigt wird. Hier stimmt offensichtlich die Information des Browser nicht mehr.
    Schade ist, dass diese Lösung nur in den modernsten Browsern funktioniert aber sehr gut finde ich, dass es ohne Javascript läuft.

    • Was meinst du genau damit, dass das Desktop-Bild ausgegeben wird? Wo siehst du das? Der IMG-Tag zeigt ja immer die Desktop-Version, der Wert wird aber je nach Viewport durch das srcset überschrieben.

      Die Unterstützung für diese Technik ist doch schon ganz ordentlich und zudem auch ziemlich browserübergreifend.

      • Den „desktop“-Bildnamen sehe ich nur mit Firebug oder der Grafik-Info. Wenn z.B. mittels Javascript der Wert überschrieben wird, dann zeigt das Firebug auch an aber hier bei der Lösung bleibt es auf desktop.png stehen, das ändert sich nicht obwohl das sichtbare Bild sich ändert.
        Vielleicht täusche ich mich da auch, aber wenn es so ist, dass der Dateiname bleibt aber das Bild intern im Browser getauscht wird, wäre da eine Information nicht nach außen getragen worden.

        Beim IE wird es erst ab 13 (Edge) unterstützt https://www.w3schools.com/tags/tag_picture.asp
        Und bei Android gibt es noch sehr viele Geräte mit 4.2, 4.3 und 4.4 Android Browsern, die das leider nicht anzeigen. Aber die Tendenz ist glücklicherweise steigend und auch diese Android-Mobilgeräte werden langsam alt. Mein Android-Tab hat zwar 2560 Pixel aber der alte Browser würde das auch nicht anzeigen können, erst der Firefox oder Chrome.
        Das hatte mich bisher davon abgehalten, das -Tag zu benützen. Aber jetzt scheint es doch gut zu funktionieren.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.