Open-Source Webdesign

BootScore ohne verwischte Beitragsbilder

Chili zum Schärfen

Drei­mal habe ich bereits über die unschar­fen Bil­der von bootS­core sin­niert. Das Pro­blem war ein­fach: bootS­core bet­tet in Zusam­men­ar­beit mit Word­Press Bil­der der Grö­ße ‘medi­um’ in die Bei­trags­lis­ten ein. Und das sogar auf gro­ßen Bild­schir­men, wo die Brow­ser viel mehr Platz fül­len müs­sen, als es die Bil­der selbst könn­ten. Folg­lich ver­grö­ßern die Brow­ser die zu klei­nen Bil­der — und machen sie damit unscharf. Oder, anders aus­ge­drückt: bootS­core bie­tet ein her­vor­ra­gen­des ‘Respon­si­ve Design’, wenn es um die Tex­te geht. Was die Bil­der angeht, (noch) nicht. Aber es gibt Aus­we­ge für ein bootS­core ohne ver­wisch­te Bei­trags­bil­der.

[ de | en ]

Hintergrund

bs blurred featured image 1

Dazu hat­te ich vor Mona­ten zwei Demos gebaut — bei­de ein­ge­rich­tet auf einem fast rei­nen Word­Press 6.11 und einem rei­nen bootS­core, wie es selbst instal­liert wer­den will2. Nun habe ich davon Screen­shots gezo­gen: Links die Bei­trags­lis­te, wie sie von der index.php eines unmo­di­fi­zier­ten bootS­core erzeugt wird. Rechts die Bei­trags­lis­te, wie sie von archive-masonry.php3 aus der Vor­la­ge eines ansons­ten unmo­di­fi­zier­ten bootS­core gene­riert wur­de.

bs blurred featured image 1

In bei­den Lis­ten ist das ‘Fea­tured Image’ auf gro­ßen Bild­schir­men unscharf. Rechts etwas weni­ger, weil der Unter­schied zwi­schen dem zur Ver­fü­gung gestell­ten Platz und der Grö­ße des ein­ge­bet­te­ten Bil­des gerin­ger ist. Ich hat­te dafür zwei Lösun­gen skiz­ziert, eine tra­di­tio­nel­le­re und eine radi­ka­le­re:

  • Die tra­di­tio­nel­le Lösung bringt Word­Press dazu, beim Hoch­la­den ein zusätz­li­ches Thumb­nail zu erzeu­gen, des­sen Brei­te mit 560px zwi­schen den Stan­dard­grö­ßen ‘mit­tel’ und ‘groß’ liegt.4. Und sie fragt in den Vor­la­gen nicht mehr nach der Grö­ße ‘medi­um’, son­dern nach der selbst defi­nier­ten Grö­ße bsTeaser.
  • Die radi­ka­le Lösung nutzt die Funk­tio­nen des Tags <img>, wie sie unter HTML‑5 akti­viert wur­den. Damit wird dem Brow­ser mit­ge­teilt, wel­che Bil­der zur Ver­fü­gung ste­hen und bis zu wel­cher Stel­le jedes ein­zel­ne ver­wen­det wer­den soll. Letzt­end­lich wählt der Brow­ser aber auf der Grund­la­ge die­ser Infor­ma­tio­nen das rich­ti­ge Bild aus.
bs solved featured image

Der Punkt bei den Lösun­gen ist also der:

  • Bei der tra­di­tio­nel­len Lösung ent­schei­den immer noch wir — die Web­site-Redak­teu­re — sta­tisch und vor­ab, wel­ches Bild in den Bereich ein­ge­bet­tet wer­den soll — auch wenn wir des­sen tat­säch­li­che Grö­ße des ‘Respon­si­ve Designs’ gar nicht vor­ab ken­nen (kön­nen).
  • Bei der radi­ka­len Lösung ent­schei­det der Brow­ser, weil er die Grö­ße des tat­säch­lich vor­han­de­nen, ‘Respon­si­ve Design’-bedingten Plat­zes kennt. Und er kann ent­schei­den, weil wir ihm vor­her gesagt haben, wel­che Bil­der mit wel­chen Abmes­sun­gen ver­füg­bar sind.

Lösung

  • Füge für bei­de Lösun­gen die Zei­le add_image_size('bsTeaser', 560, 0, false ); in Dei­ne functions.php ein.
  • Für die tra­di­tio­nel­le Lösung erset­ze in allen für Dich rele­van­ten Tem­pla­tes get_the_post_thumbnail(null, 'medium') durch get_the_post_thumbnail(null, 'bsTeaser').
  • Für die radi­ka­le Lösung füge in Dei­ne functions.php fol­gen­de Zeile(n) ein:
/*
 * Applay the better html-5 based image tag structure (with srcset and sizes) 
 * (C) 2023 Karsten Reincke
 * SPDX-License-Identifier: MIT
 *
 * Created in accordance with 
 * a) https://developer.wordpress.org/reference/functions/wp_get_attachment_image_src/
 * b) https://straightvisions.com/en/news/howtos-en/gutenberg-and-responsive-image-sizes/
 */
function html5ThumbnailHtml($html, $post_id, $post_thumbnail_id, $size, $attr) {
  $id = get_post_thumbnail_id($post_id); // gets the id of the current post_thumbnail (in the loop)

  $columnSize=", 400px"; 
  if (is_single($post_id)) $columnSize=""; // take the complete screen for visualization  

  $smSrc="";
  $smSize="";
  $mdSrc="";
  $mdSize="";
  $lgSrc="";
  $lgSize="";
  $flSrc="";
  $flSize="";
  $bsSrc="";
  $bsSize="";
  $defImg=null; 

  $smImage=(array) wp_get_attachment_image_src($id, 'thumbnail');
  if ($smImage!=null) {
    $smSrc=$smImage[0] .' '. $smImage[1] .'w';
    $smSize='(max-width: ' . $smImage[1] . 'px) ' . $smImage[1] .'px';
  }

  $mdImage=(array) wp_get_attachment_image_src($id, 'medium');
  if ($mdImage!=null) {
    $mdSrc=$mdImage[0] . ' ' . $mdImage[1] .'w';
    $mdSize='(max-width: ' . $mdImage[1] . 'px) ' . $mdImage[1] .'px';
  }

  $bsImage=(array) wp_get_attachment_image_src($id, 'bsTeaser');
  if ($bsImage!=null) {
    $bsSrc=$bsImage[0] . ' ' . $bsImage[1] .'w';
    $bsSize='(max-width: ' . $bsImage[1] . 'px) ' . $bsImage[1] .'px';
  }

  $lgImage=(array) wp_get_attachment_image_src($id, 'large');
  if ($lgImage!=null) {
    /*
     * There seems to be a bug in wp_get_attachment_image_src($id, 'large'):
     * the function returns a wrong width (640): Solution: hardcode
     * values in accordance with the definition under settings
     */
    $lgSrc=$lgImage[0] . ' ' . '1024w';
    $lgSize='(max-width: ' . '1024px) '  .'1024px';
    $defImg=$lgImage[0];
    //$lgSrc=$lgImage[0] . ' ' . $lgImage[1] .'w';
    //$lgSize='(max-width: ' . $lgImage[1] . 'px) ' . $lgImage[1] .'px';
  }

  $flImage=(array) wp_get_attachment_image_src($id, 'full');
  if ($flImage!=null) {
    $flSrc=$flImage[0] . ' ' . $flImage[1] .'w';
    $flSize='(max-width: ' . $flImage[1] . 'px) ' . $flImage[1] .'px';
    if(!($defImg)) $defImg=$flImage[0];
  }

  $srcSet="";
  $sizeSet="";
  if ($smSrc) {
    $sep=' ';
    if ( ( ($mdSrc)||($bsSrc) )||( ($lgSrc)||($flSrc) ) ) $sep = ', ';
    $srcSet=$smSrc . $sep;
    $sizeSet=$smSize . $sep;
  }

  if ($mdSrc) {
    $sep=' ';
    if ( ($bsSrc) || ( ($lgSrc)||($flSrc) ) ) $sep = ', ';
    $srcSet=$srcSet . $mdSrc . $sep;
    $sizeSet=$sizeSet . $mdSize . $sep;
  }

  if ($bsSrc) {
    $sep=' ';
    if ( ($lgSrc) ||($flSrc) ) $sep = ', ';
    $srcSet=$srcSet . $bsSrc . $sep;
    $sizeSet=$sizeSet . $bsSize . $sep;
  }

  if ($lgSrc) {
    $sep=' ';
    if ($flSrc) $sep = ', ';
    $srcSet=$srcSet . $lgSrc . $sep;
    $sizeSet=$sizeSet . $lgSize . $sep;
  }
  if ($flSrc) {
    $srcSet=$srcSet . $flSrc;
    $sizeSet=$sizeSet . $flSize;
  }
  $alt=get_post_meta($id, '_wp_attachment_image_alt', TRUE);
  $class = $attr['class']; // gets classes passed to the post thumbnail, defined here for easier function access

  $html = '<img src="' . $defImg . '" ' . 
         'alt="' . $alt . '" ' . 
         'srcSet="' . $srcSet . '" ' .
         'sizes="' . $sizeSet . ' ' . $columnSize .'" ' .
         'class="' . $class . '" />';
  return $html;
}
add_filter('post_thumbnail_html', 'html5ThumbnailHtml', 99, 5);

Dies wäre so zu lesen:

  • Zuerst holt der Algo­rith­mus die id des ‘Fea­tured Image’ und setzt die unge­fäh­re Brei­te einer Spal­te, die ent­steht, wenn das Fens­ter grö­ßer als die Brei­te des größ­ten Bil­des ist.
  • Dann fragt er die Grö­ßen aller defi­nier­ten Bil­der ab und erzeugt dar­aus die Kür­zel Bild-Pfad Brei­te, Bild­brei­te und Zustän­dig-für-Platz­Brei­te.
  • Schließ­lich ent­ste­hen dar­aus die Lis­te der zur Ver­fü­gung ste­hen­den Bil­der und die Lis­te, wel­che Bild­brei­te bis zu wel­cher Platz­brei­te zustän­dig ist.
  • Und zuletzt wird das als img-Tag mit srcSet- und size-Lis­te umge­wan­delt.

Für das Fea­ture Image die­ses Arti­kels wird dem Brow­ser also die fol­gen­de Zei­le vor­ge­legt:

Auf die­ser Basis ent­schei­det der Brow­ser selb­stän­dig, wel­ches Bild er wann wo ein­passt. Und so sieht die aktu­el­le all­ge­mei­ne Metho­de für Respon­si­ve Images in einem Respon­si­ve Design aus. Natür­lich habe ich mir das nicht selbst aus­ge­dacht. Nicht ein­mal selbst von der Theo­rie in die Pra­xis umge­setzt. Viel­mehr ich in fol­ge im Wesent­li­chen drei Quel­len


Und in welchem Zusammenhang …

… steht das mit unse­rer Migra­ti­on zu bootS­core? Nun, ein­mal ange­fan­gen mit Ver­bes­se­run­gen der Bild­be­hand­lung, wer­den der Web-Desi­gne­rin auch die ver­wisch­ten ‘pri­mä­ren Bei­trags­gil­der’ auf­fal­len. Sie wird Lösun­gen aus­pro­bie­ren und ver­fei­nern. Und sie wird sie u.U. auch mit neu­en HTML‑5 Tech­ni­ken ange­hen. Denn damit wird eine aus­ge­fal­le­ne­re Bild­stra­te­gie samt inte­grier­ter Lizenz­er­fül­lung und das eige­ne Logo erst rich­tig sinn­voll. Wie auch immer: Bil­der brin­gen Far­be ins Lese­le­ben. Zuletzt soll­te all das also auch in ein eige­nes Farb­kon­zept ein­ge­bun­den sein. Zu die­ser The­ma­tik trägt auch die­ser Post etwas bei.


Im Übri­gen: Män­ner sind mit­ge­meint.

  1. als zusätz­li­che Erwei­te­rung brauch­te ich nur Bet­ter Search Replace []
  2. ich habe die ‘Fea­tured Images’ in der Grö­ße 1280*720 hoch­ge­la­den und zuge­wie­sen []
  3. mit dem aus­ge­rich­te­ten Bereich <header>...</header> []
  4. Bis­lang hat­te ich 600x600 emp­foh­len. Jetzt, nach eini­gen Dis­kus­sio­nen, eini­gem Nach­le­sen und aus­gie­bi­gen Tests, den­ke ich, dass ein 16:9 Bild mit einer Brei­te von 560px aus­rei­chend ist. []
To top