Haben Sie diese nette Technik gesehen, um das <picture>-Element mit <source media=""> zu verwenden, um ein animiertes Bild (oder nicht) basierend auf einer prefers-reduced-motion-Media-Query bereitzustellen?
Nachdem wir dies in unserem Newsletter geteilt hatten, erhielten wir eine interessante Antwort von Michael Gale
Was ist mit Leuten, die ihre animierten GIFs lieben, aber einfach nicht wollten, dass die UI überall herumzoomt? Müssen sie jetzt eine Wahl zwischen Inhalt und UI treffen?
Ich fand das eine ziemlich interessante Frage.
Außerdem wird mein Gehirn heutzutage jedes Mal, wenn ich <img src="gif.gif"> sehe, in das Territorium von *WAS IST MIT MP4?!* getriggert, da ich richtig davon überzeugt bin, dass Videos im Web in jeder Hinsicht besser sind als GIFs. Es stellt sich heraus, dass einige Browser Videos direkt im <img>-Element unterstützen und, ob Sie es glauben oder nicht, Sie können Fallbacks dafür schreiben, mit – Trommelwirbel, bitte – auch für das <picture>-Element!
Versuchen wir, all diese Dinge zu kombinieren.
Hinzufügen einer MP4-Quelle
Das Einfache ist das Hinzufügen einer zusätzlichen <source> mit dem Video. Das bedeutet, wir benötigen drei Quellmediendateien
- Eine alternative nicht-animierte Grafik, wenn
prefers-reduced-motionaufreducegesetzt ist. - Ein animiertes GIF als Standard.
- Ein MP4-Video als Ersatz für das GIF, wenn der Fallback unterstützt wird.
Zum Beispiel:
<picture>
<source srcset="static.png" media="(prefers-reduced-motion: reduce)"></source>
<source srcset="animated.mp4" type="video/mp4">
<img srcset="animated.gif" alt="animated image" />
</picture>
Unter Standardbedingungen in Chrome werden nur das GIF heruntergeladen und angezeigt

Unter Standardbedingungen in Safari werden nur die MP4 heruntergeladen und angezeigt

Wenn Sie prefers-reduced-motion: reduce in Chrome oder Safari aktiviert haben (auf meinem Mac gehe ich zu Systemeinstellungen → Bedienungshilfen → Anzeige → Bewegung reduzieren), laden beide Browser nur die statische PNG-Datei herunter.

Ich habe Firefox getestet und es scheint nicht zu funktionieren, stattdessen wird weiterhin die GIF-Version heruntergeladen. Firefox scheint prefers-reduced-motion zu unterstützen, aber vielleicht wird es noch nicht auf <source>-Elementen unterstützt? Ich bin mir nicht sicher, was da los ist.
Wäre es nicht ziemlich cool, eine einzige animierte Quelle bereitzustellen und ein Tool die anderen daraus generieren zu lassen? Ich wette, Sie könnten das mit etwas wie Cloudinary verkabeln.
Hinzufügen eines Schalters zur Anzeige der animierten Version
Wie Michael Gale erwähnte, scheint es schade zu sein, dass Sie von der Anzeige der animierten Version vollständig ausgeschlossen sind, nur weil Sie einen Schalter für reduzierte Bewegungen umgelegt haben.
Es sollte einfach genug sein, einen <button> zu haben, der JavaScript verwendet, um die Media-Query zu entfernen und den Browser zu zwingen, die animierte Version anzuzeigen.
Ich bin ziemlich sicher, dass es keinen praktischen Weg gibt, dies deklarativ in HTML zu tun. Wir können diesen Button auch nicht innerhalb des <picture>-Tags platzieren. Obwohl <picture> kein ersetztes Element ist, wird der Browser immer noch verwirrt und mag es nicht. Stattdessen rendert er es überhaupt nicht. Kein großes Ding, wir können einen Wrapper verwenden.
<div class="picture-wrap">
<picture>
<!-- sources -->
</picture>
<button class="animate-button">Animate</button>
</div>
Wir können den Button über dem Bild positionieren. Dies ist nur eine willkürliche Wahl – Sie könnten ihn überall platzieren oder sogar das gesamte Bild tappbar machen, solange Sie denken, dass Sie dies den Benutzern erklären können. Denken Sie daran, den Button nur anzuzeigen, wenn die gleiche Media-Query übereinstimmt
.picture-wrap .animate-button {
display: none;
}
@media (prefers-reduced-motion: reduce) {
.picture-wrap .animate-button {
display: block;
}
}
Wenn der Button geklickt (oder angetippt) wird, müssen wir die Media-Query entfernen, um die Animation zu starten, indem wir eine animierte Quelle herunterladen.
let button = document.querySelector(".animate-button");
button.addEventListener("click", () => {
const parent = button.closest(".picture-wrap");
const picture = parent.querySelector("picture");
picture.querySelector("source[media]").remove();
});
Hier ist das in Aktion
Sehen Sie den Pen
Prefers Reduction Motion Technique PLUS! von Chris Coyier (@chriscoyier)
auf CodePen.
Vielleicht ist das eine gute Komponente?
Wir könnten den Button, das Button-Styling und die Button-Funktionalität automatisch mit einer Web-Komponente einbinden. Hey, warum nicht?
Sehen Sie den Pen
Prefers Reduction Motion Technique als Web Component von Chris Coyier (@chriscoyier)
auf CodePen.
Auf meinem Blog verwende ich etwas weniger Fortgeschrittenes, um GIFs abzuspielen/pausieren. Ich muss es neu schreiben, um
prefers-reduced-motionzu berücksichtigen (und den Button immer anzuzeigen?), aber ich verwende bereits Netlify, um statische Versionen im laufenden Betrieb zu generieren. Mit Hugo muss ich nur eine Datei hochladen, das macht es so einfach.Eine Möglichkeit ist, den Schalter immer anzuzeigen, aber den Schalter die
prefers-reduced-motion-Präferenz respektieren zu lassen.https://twitter.com/cariefisher/status/1142106562745556992
Idealerweise würden Browser eine Option anbieten, die, wenn sie aktiviert ist, automatisch alle GIFs, Videos und andere Animationen auf Webseiten pausiert. Ich denke, da Animation ein Barrierefreiheitsproblem ist, müssen Browser voranschreiten und die richtige Option anbieten, die sicherstellt, dass betroffene Benutzer keine Animationen auf Websites antreffen.
Da ich weiß, dass eine solche Option in den wichtigsten Browsern nicht existiert, würde ich persönlich diesen Ansatz verfolgen
Nur Video verwenden. (Ich habe keine Absicht, jemals wieder animierte GIFs auf meiner Website zu laden, egal aus welchem Grund).
Verwenden Sie JavaScript, um automatisch abspielende Videos dynamisch zu pausieren (und Steuerelemente zum manuellen Abspielen hinzuzufügen), wenn der Benutzer "reduzierte Bewegung" aktiviert hat. Ein pausiertes Video sollte ein ausreichend guter Fallback-Bild sein (obwohl Poster-Bilder für Safari möglicherweise immer noch benötigt werden, nicht sicher).
PS. Möglicherweise dummer Gedanke: Wie cool wäre es, wenn wir HTML-Attribute wie
<video autoplay>deklarativ basierend auf CSS-Media-Queries einstellen könnten. Dann müsste ich in Schritt 2 kein JS verwenden.Wenn Sie animierte GIFs in Videos mit Cloudinary konvertieren möchten, ist die einfachste Methode wahrscheinlich die Verwendung der Fetch API von Cloudinary.
Ich hoffe, das kann helfen
https://nicolas-hoizey.com/2018/08/using-cloudinary-s-fetch-api-to-convert-an-animated-gif-to-a-video.html
Dies ist eine so gute Erweiterung des ursprünglichen Newsletter-Artikels! Ich dachte immer, Twitter hätte es mit seiner Optionsschaltfläche für das Laden von Bildern und Videos auf Knopfdruck verstanden – mit einem kleinen Overlay, das Ihnen sagt, wie groß die Datei sein wird.
Ausgezeichnet für die Nicht-Beeinträchtigung des mobilen Erlebnisses. Aber nicht jede Website kann sich den Luxus von vielen Optionen zum Umschalten usw. leisten.
Ich nehme Ihren Punkt auch, Sime! Ich muss mir angewöhnen, alles von GIF auf Video umzustellen, nur wegen der geringeren Dateigröße. Die einzige andere Überlegung, die mir hier einfällt, ist die Einfachheit, Alt-Text für ein animiertes GIF bereitzustellen im Vergleich zur Bereitstellung eines Videoskripts (vorausgesetzt, das Video hat Ton).