Abbrechen
Suche starten
Diese Suche basiert auf Elasticsearch und kann mehrere tausend Seiten in Bruchteilen einer Sekunde durchsuchen.
Mehr erfahrenBilder in TYPO3 v10 werden gewöhnlich über einen Fluid-ViewHelper gerendert. Hierbei kommt der media-ViewHelper zum Einsatz, der je nach Ressource (Bild oder Video) das entsprechende HTML-Markup rendert. Das für uns relevante Fluid-Markup befindet sich in der Datei typo3/sysext/fluid_styled_content/Resources/Private/Partials/Media/Rendering/Image.html:
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:media
class="image-embed-item"
file="{file}"
width="{dimensions.width}"
height="{dimensions.height}"
alt="{file.alternative}"
title="{file.title}"
loading="{settings.media.lazyLoading}"
/>
</html>
Das ganze Markup kommt sehr leichtgewichtig daher - was mich positiv überrascht hat. Die Dokumentation zum media-ViewHelper https://docs.typo3.org/other/typo3/view-helper-reference/master/en-us/typo3/fluid/latest/Media.html zeigt neben den hier dargestellten Argumenten noch weitere, wie z.B. das neue Argument loading.
Das Argument loading ist ab v10.3 für den media-ViewHelper verfügbar und wird standardmäßig mit dem Wert lazyH verwendet. Über die Konstante, die hierfür von fluid_styled_content eingeführt wurde styles.content.image.lazyLoading kann das loading-Argument angepasst werden (lazy, eager oder auto). Zum loading-Attribut gibt es hier eine Erklärung: https://web.dev/native-lazy-loading/#the-loading-attribute
<div id="c1" class="frame frame-default frame-type-image frame-layout-0">
<div class="ce-image ce-center ce-above">
<div class="ce-gallery" data-ce-columns="1" data-ce-images="1">
<div class="ce-outer">
<div class="ce-inner">
<div class="ce-row">
<div class="ce-column">
<figure class="image">
<img class="image-embed-item" title="Demo Bild Title Text" alt="Demo Bild Alt Text" src="/fileadmin/_processed_/6/e/csm_image_01_a55d08e819.jpg" loading="lazy" width="600" height="337">
</figure>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Wie zu sehen wurde auch das bereits erwähnte loading-Attribut mit dem Wert lazy gerendert. Das HTML-Konstrukt um den img Tag entstammt weiteren Fluid-Templates, die sich zum Großteil hier befinden: typo3/sysext/fluid_styled_content/Resources/Private/Partials/Media/. Schauen wir uns den media-ViewHelper mal genauer an.
Dem media-ViewHelper fehlen Argumente wie srcset oder sizes. Das Attribut srcset ist aber notwendig damit wir das src-Attribut eines Bildes durch ein Set von Bildquellen überschreiben können.
Um nun beide Argumente integrieren zu können, benötigen wir ein eigenes Fluid-Partial, dass das Original überschreibt (...Partial/Media/Rendering/Image.html). Hierfür habe ich mir eine eigene kleine Extension (responsive_images_demo) über https://www.sitepackagebuilder.com/ erstellt - basierend auf TYPO3 v10 und Fluid Styled Content.
styles {
templates {
layoutRootPath = EXT:responsive_images_demo/Resources/Private/Layouts/ContentElements/
partialRootPath = EXT:responsive_images_demo/Resources/Private/Partials/ContentElements/
templateRootPath = EXT:responsive_images_demo/Resources/Private/Templates/ContentElements/
}
}
Mein eigenes Image-Partial befindet sich unter typo3conf/ext/responsive_images_demo/Resources/Private/Partials/ContentElements/Media/Rendering/Image.html und überschreibt automatisch das Original (typo3/.../Partial/Media/Rendering/Image.html).
Der media-ViewHelper wird mit Hilfe des ViewHelpers uri.image und desArguments additionalAttributes um die Attribute srcset und sizes ergänzt:
<f:media
class="image-embed-item"
file="{file}"
width="{dimensions.width}"
height="{dimensions.height}"
alt="{file.alternative}"
title="{file.title}"
loading="{settings.media.lazyLoading}"
additionalAttributes="{srcset: '{f:uri.image(image: file, maxWidth: 768)} 768w,
{f:uri.image(image: file, maxWidth: 990)} 990w,
{f:uri.image(image: file, maxWidth: 1200)} 1200w,
{f:uri.image(image: file, maxWidth: 1440)} 1440w,
{f:uri.image(image: file, maxWidth: 1900)} 1900w',
sizes: '(min-width: 1200px) 50vw, 100vw'}"
/>
Die gezeigten srcset- und sizes-Angaben sind hier beispielhaft. Für welche Gerätecharakteristiken Ihr die entsprechenden Auflösungen bereitstellen wollt, ist natürlich Euch überlassen.
Und so sieht nun die HTML-Ausgabe im Frontend aus:
<img
srcset="/fileadmin/_processed_/6/e/csm_image_01_8159d1e3b0.jpg 768w,
/fileadmin/_processed_/6/e/csm_image_01_19d1039365.jpg 990w,
/fileadmin/_processed_/6/e/csm_image_01_9cee8957cf.jpg 1200w,
/fileadmin/_processed_/6/e/csm_image_01_922756210c.jpg 1440w,
/fileadmin/_processed_/6/e/csm_image_01_0e137c815f.jpg 1900w"
sizes="(min-width: 1200px) 50vw, 100vw"
class="image-embed-item"
title="Demo Bild Title Text"
alt="Demo Bild Alt Text"
src="/fileadmin/_processed_/6/e/csm_image_01_a55d08e819.jpg"
loading="lazy"
width="600"
height="337"
>
Die Attribute width und height können über folgende Konstanten angepasst werden:
Der Standardwert in TYPO3 v10.4 ist für maxW → 600 und für maxWInText → 300.
Eine alternative Variante um Responsive Images anstelle unter zu Hilfenahme von f:media oder f:image zu rendern, kann die Verwendung eines ganz gewöhnlichen img Tags in Kombination mit dem f:uri.image ViewHelper sein:
<img
class="image-embed-item lazy"
data-src="{f:uri.image(image: file, treatIdAsReference: 1, maxWidth: 1168)}"
data-srcset="{f:uri.image(image: file, treatIdAsReference: 1, maxWidth: 768)} 768w,
{f:uri.image(image: file, treatIdAsReference: 1, maxWidth: 990)} 990w,
{f:uri.image(image: file, treatIdAsReference: 1, maxWidth: 1200)} 1200w,
{f:uri.image(image: file, treatIdAsReference: 1, maxWidth: 1440)} 1440w,
{f:uri.image(image: file, treatIdAsReference: 1, maxWidth: 1900)} 1900w"
data-sizes="(min-width: 1200px) 1168px, 100vw"
alt="{file.alternative}"
title="{file.title}"
width="{dimensions.width}"
height="{dimensions.height}"
/>
Im Beispiel erhalten die Attribute src, srcset und sizes das data-Präfix, das oft für lazy loading Skripte, wie https://github.com/verlok/lazyload, benötigt wird.
Das picture Tag kann als weitere Variante, wie auch das gezeigte img Tag Beispiel mit dem f:uri.image ViewHelper ausgestattet werden:
<picture>
<source
media="(min-width: 990px)"
srcset="{f:uri.image(image: file, maxWidth: 1200)}"
/>
<source srcset="{f:uri.image(image: file, maxWidth: 768)}" />
<img src="{f:uri.image(image: file, maxWidth: 768)}" alt="{file.alternative}" />
</picture>
In der Vergangenheit wurden Responsive Images sehr häufig durch TypoScript gerendert, aber später durch die steigende Popularität von Fluid wurde dies mehr und mehr verdrängt. Nichtsdestotrotz hat das Rendern der Responsive Images durch TypoScript immer noch seine Daseinsberechtigung, vor allem wenn die Site zum Großteil (noch) durch TypoScript gerendert wird. TypoScript ist ein mächtiges Werkzeug und bietet große Flexibilität beim Rendern. Manchmal lassen sich mit wenigen Zeilen TypoScript Elemente einfacher umsetzen, als mit verschachtelten Fluid-Konstrukten. Allein der Blick in die Dokumentation zum TypoScript IMAGE Objekt zeigt das Potenzial: https://docs.typo3.org/m/typo3/reference-typoscript/master/en-us/ContentObjects/Image/Index.html
Die nächsten TypoScript-Beispiele zeigen nur die Bereiche, die für Responsive Images relevant sind. Die genannte IMAGE-Dokumentation beinhaltet vollständige Beispiele, sowie deren HTML-Ausgabe.
Das Beispiel zeigt ein typisches IMAGE-Objekt, das durch diverse Properties erweitert wurde, sodass es z.B. das srcset-Attribut (###SRCSETCANDIDATE###) erhält:
10 = IMAGE
10 {
file = fileadmin/example.jpg
file.width = 3141
layoutKey = default
layout {
[...]
srcset {
element = <img src="###SRC###" srcset="###SOURCECOLLECTION###" ###PARAMS### ###ALTPARAMS### ###SELFCLOSINGTAGSLASH###>
source = |*|###SRC### ###SRCSETCANDIDATE###,|*|###SRC### ###SRCSETCANDIDATE###
}
[...]
}
{
small {
width = 800
srcsetCandidate = 800w
mediaQuery = (min-device-width: 800px)
dataKey = small
}
[...]
}
}
20 < 10
20.layoutKey = srcset
[...]
Das IMAGE Objekt kann z.B. als ein wiederverwendbares TypoScript-Objekt lib.responsiveImage definiert werden:
lib.responsiveImage {
default = IMAGE
default {
file {
import.current = 1
treatIdAsReference = 1
}
altText.field = alternative
titleText.field = title
params = class="image-embed-item"
layoutKey = srcset
layout {
[...]
srcset {
element = <img src="###SRC###" srcset="###SOURCECOLLECTION###" sizes="100vw" ###PARAMS### ###ALTPARAMS### ###SELFCLOSINGTAGSLASH###>
source = |*|###SRC### ###SRCSETCANDIDATE###,|*|###SRC### ###SRCSETCANDIDATE###
}
}
sourceCollection {
mobile {
maxW = 314
srcsetCandidate = 314w
dataKey = mobile
}
[...]
}
}
}
[...]
renderObj < lib.responsiveImage.default
renderObj {
[...]
sourceCollection {
tablet {
width = 768
srcsetCandidate = 768w
mediaQuery = (max-device-width: 768px)
dataKey = tablet
}
[...]
}
}
Oder in einem Fluid Template:
<f:cObject
typoscriptObjectPath="lib.responsiveImage.default"
data="{file.uid}"
/>
Seit einigen TYPO3-Versionen (v7.6) existiert das Crop-Feature, das Redakteuren ein Werkzeug an die Hand gibt, um einen Ausschnitt eines Bildes festzulegen.
Die beiden nächsten Code-Abschnitte sollen einen möglichen Weg aufzeigen, zum Einen die Crop-Varianten anzupassen, die im Backend für die Bild-Manipulation zur Verfügung stehen, und zum Anderen wie auf die Ausschnitte zugegriffen werden kann.
Die crop Variante default, die TYPO3 bereits von Haus aus mitliefert, sowie zusätzliche Varianten können über TCEFORM angepasst werden:
TCEFORM {
sys_file_reference.crop.config.cropVariants {
default {
title = Alle (Standard)
selectedRatio = NaN
allowedAspectRatios {
NaN {
title = Frei
value = 0.0
}
[...]
4:3 {
title = 4:3
value = 1.333333
}
}
}
card {
title = Card
selectedRatio = 16:9
allowedAspectRatios {
16:9 {
title = 16:9
value = 1.777777778
}
}
}
}
}
Über die Eigenschaft allowedAspectRatios können verschiedene Seitenverhältnisse angegeben werden. So erhält der Redakteur für ein Bild unterschiedliche vordefinierte Seitenverhältnisse, um z.B. schneller für gewisse Layoutvorgaben das passende Seitenverhältnis auszuwählen.
Im obigen Beispiel wurde neben der default Variante, die hier überschrieben wird, die neue Variante card hinzugefügt. Wird nur eine neue Variante, wie im Beispiel die card Variante definiert, dann wird dem Nutzer im Backend auch keine default Variante zur Verfügung gestellt.
Im Fluid-Template wird über das Argument cropVariant des f:uri.image ViewHelpers auf die entsprechende Variante zugegriffen. In diesem Beispiel auf card:
<img
class="lazy"
data-src="{f:uri.image(src: file, treatIdAsReference: 1, maxWidth: 768, cropVariant: 'card')}"
data-srcset="{f:uri.image(src: file, treatIdAsReference: 1, maxWidth: 768, cropVariant: 'card')} 768w,
{f:uri.image(src: file, treatIdAsReference: 1, maxWidth: 1900, cropVariant: 'card')} 1200"
data-sizes="..."
alt="..."
[...]
/>
Als Ergänzung möchte ich noch den Weg über TCA nennen: https://docs.typo3.org/m/typo3/reference-tca/master/en-us/ColumnsConfig/Type/ImageManipulation.html
Ein Blick in die TCA-Dokumentation lohnt sich, weil u.a. auch die Verwendung der coverArea gezeigt wird, um z.B. Bild-Bereiche für den Redakteur aufzuzeigen, die im Frontend einen Textbereich enthalten können, der das Bild später überdeckt oder die focusArea Eigenschaft, die Koordinaten speichert (focal point), die z.B. für JavaScript-Plugins wie https://github.com/jonom/jquery-focuspoint verwendet werden können.
Wer sich Tipparbeit beim Integrieren der Responsive Images in Fluid oder TypoScript sparen möchte oder vielleicht mehr Funktionalität benötigt, als die Fluid-ViewHelper wie f:media oder f:image anbieten, kann sich ja immer nach TYPO3-Extensions umsehen.
In der TYPO3-Community werden für das Rendern von Responsive Images häufig die beiden nachfolgenden TYPO3-Extensions verwendet:
Die vhs TYPO3-Extension bietet eine Vielzahl nützlicher ViewHelper an, darunter befindet sich der v:media.image ViewHelper, der Ähnlichkeiten mit den bekannten ViewHelpern f:media oder f:image aufweist. Ein erster Blick auf den vhs-ViewHelper zeigt schon die Einfachheit, mit der sich z. B. die unterschiedlichen srcset-Angaben definieren lassen:
<v:media.image
src="path/to/media.jpg"
width="123"
height="123"
[...]
treatIdAsReference="1"
srcset="314, 768, 990, 1200"
srcsetDefault="768"
/>
Die v:media.image ViewHelper Referenz führt noch einige weitere interessante Argumente auf: https://fluidtypo3.org/viewhelpers/vhs/master/Media/ImageViewHelper.html
Neben vhs ist die TYPO3-Extension sms_responsive_images eine weitere Empfehlung. Auch hier ist die Fluid-Konfiguration relativ simpel und hat so einige Features parat:
<sms:image image="{image}" srcset="400, 600, 800, 1000" />
<sms:image image="{image}" srcset="1x, 2x" />
<sms:image
image="{image}"
sizes="(min-width: 1200px) 600px, (min-width: 900px) 800px, 100vw"
/>
<sms:image
image="{image}"
breakpoints="{
0: {'cropVariant': 'desktop', 'media': '(min-width: 1000px)', 'srcset': '1000, 1200, 1400, 1600'},
1: {'cropVariant': 'mobile', 'srcset': '400, 600, 800, 1000, 1200, 1400, 1600'}
}"
/>
<sms:image image="{image}" srcset="400, 600" lazyload="true" />
Die Extension rendert ein <img> oder <picture> Tag, je nachdem welche Argumente verwendet werden. So z.B. wird ein picture-Tag bei der Verwendung des breakpoints Arguments gerendert.
In der Extension-Dokumentation findet Ihr neben den hier gezeigten Beispielen noch weitere: https://extensions.typo3.org/extension/sms_responsive_images
Ab TYPO3 v10.3 ist es nun auch möglich bei den ViewHelpern <f:image>, <f:media> und <f:uri.image> für das Argument fileExtension die Option webp anzugeben:
<picture>
<source srcset="{f:uri.image(image: file, treatIdAsReference: true, fileExtension: 'webp')}" type="image/webp"/>
<source srcset="{f:uri.image(image: file, treatIdAsReference: true, fileExtension: 'jpg')}" type="image/jpeg"/>
<f:image alt="{file.alternative}" image="{file}" treatIdAsReference="true"/>
</picture>
Hierbei sollte vorher überprüft werden, ob die eingesetzte ImageMagick-Version die WebP-Konvertierung unterstützt.
Weiterführende Links zum Einsatz von WebP in Verbindung mit TYPO3: