Der folgende Beitrag ist ein Gastbeitrag von Fabrice Weinberg. Fabrice gehört zu der Sorte Mensch, die gerne die neuesten Entwicklungen in CSS und Webtechnologien erforscht. Dieser Beitrag ist keine Ausnahme!
Ich möchte mir die Media Fragments URI-Spezifikation ansehen. Insbesondere den Teil über die räumliche Dimension. Der zeitliche Teil wurde letztes Jahr in Chrome und Firefox implementiert, aber die räumliche Dimension wird zum Zeitpunkt des Schreibens in keinem aktuellen Browser unterstützt.
Um es klarzustellen: Dieses Thema ist hochgradig experimentell. Die einzige Möglichkeit, es heute zu nutzen, wäre die Verwendung des von mir geschriebenen Polyfills, der nur in Chrome und Firefox funktioniert. Grundsätzlich gilt: Verwenden Sie es nicht in der Produktion!
Um Ihnen eine Vorstellung davon zu geben, worum es geht: Sie können sich die zeitliche Dimension als einen Offset vorstellen, ab dem der Audio-/Video-Tag seinen Inhalt abzuspielen beginnt. Ein funktionierendes Beispiel finden Sie hier.
Die räumliche Dimension ist dasselbe Konzept, aber für Bilder. Wir können den genauen Teil eines Bildes beschreiben, den wir anzeigen möchten.
Wie funktioniert es?
Die Media Fragments URI ist eine Syntax, mit der es möglich ist, nur einen bestimmten Ausschnitt eines Bildes auszuwählen. Sie sieht so aus:
#xywh=160,120,320,240 # => results in a 320x240 box at x=160 and y=120
#xywh=pixel:160,120,320,240 # => results in a 320x240 box at x=160 and y=120
#xywh=percent:25,25,50,50 # => results in a 50%x50% box at x=25% and y=25%
Im Wesentlichen ein Hash, den Sie an Medien-URLs anhängen.
Beispiel
Wenn Sie diese „Fragmente“ an eine Bild-URL anhängen, wie hier:
http://placekitten.com/500#xywh=160,120,320,240
Das Ergebnis würde so aussehen:
Wie in der Spezifikation angegeben, erhalten wir ein Bild von 320×240 Pixeln Größe mit einem Offset von 160×120 zur oberen linken Ecke.
Wofür ist das gut?
Eine Verbesserung für CSS-Sprites
Ich würde nicht sagen, dass es „besser“ ist, Media Fragments anstelle von CSS-Sprites zu verwenden. Vielmehr erweitert es die Möglichkeiten, indem es ein häufiges Problem überwindet. Es ist nicht möglich, einen wiederholenden Hintergrund zu erstellen, der auf mehr als einer Achse mit regulären Bild-Sprites wiederholt wird. Selbst eine Achse ist kompliziert.
Mit Media Fragments könnten wir ein wiederholtes background-image aus einem Bild innerhalb eines Sprites erstellen.
Eine Demo
Für das Bild in der Demo habe ich dieses Muster mit einigen Twitter Bootstrap-Icons kombiniert. Die traditionelle Technik für CSS-Sprites wird für Icons verwendet und ein Media Fragment für den wiederholten Hintergrund.
Bildanimationen
Ein weiterer Anwendungsfall ist die Möglichkeit, Bildanimationen zu erstellen, wie im Artikel Animated GIFs the Hard Way von Jon Skinner für die Produktseite von Sublime Text 2 diskutiert. Aber ich glaube nicht, dass dies in der Produktion nutzbar ist, da ich zustimme, dass JavaScript besser für diese Art von Animationen geeignet ist. Ich mag es einfach, CSS an seine Grenzen zu bringen.
Erstellen des Polyfills
Auf der Suche nach einer Lösung, um Media Fragments URI in aktuellen Browsern zu testen, suchte ich nach einer Möglichkeit, sein Verhalten zu simulieren. Sie können den vollständigen Polyfill in einem Beispiel-Pen sehen.
Firefox
Die Lösung für Firefox war recht einfach. Eine CSS-Funktion namens -moz-image-rect tut genau das, was wir wollen, und sie wurde seit März 2011 in Firefox (damals Version 4) implementiert.
WebKit
Für WebKit gibt es eine großartige Sache namens CSSCanvas (-webkit-canvas drawing). Man kann es sich wie ein background-image vorstellen, das ein canvas ist und mit JavaScript angesprochen werden kann. Aber das Schlechte daran ist, dass es keine veröffentlichte Spezifikation für diese Funktion gibt, sodass sie eine Zeit lang WebKit-spezifisch bleiben wird (obwohl Firefox etwas Ähnliches hat: -moz-element). Es gibt auch einen Fehler in der aktuellen Google Chrome-Version (23) Bug 16199, der in Google Chrome Canary behoben ist. Dieser Fehler beeinträchtigt den Polyfill nicht, da es nur ein Problem mit der korrekten Aktualisierung des Canvas bei animierten Inhalten gibt.
Codebeispiel
div {
background: -webkit-canvas(name_of_canvas);
}
Verwenden Sie dann dieses Canvas als Zeichenkontext in JavaScript.
var ctx = document.getCSSCanvasContext("2d", "name_of_canvas", 100, 100);
Was wir hier getan haben, ist, den Zeichenkontext für das in unserem CSS definierte Canvas mit dem Namen „name_of_canvas“ abzurufen und seine Breite und Höhe jeweils auf 100 Pixel zu setzen.
Hier ist ein funktionierendes Beispiel (aus offensichtlichen Gründen nur für WebKit)
Schlussfolgerungen
Am Ende habe ich diese beiden Kerntechniken kombiniert, um den Polyfill zu erstellen. Wenn jemand eine Möglichkeit kennt, die Browserunterstützung zu erweitern, würde ich mich freuen, davon zu hören.
Warum so viel Aufwand?
Ich spiele gerne mit neuen Dingen. So neu, dass sie noch nicht einmal im Browser sind! Ich hoffe, Sie tun das auch. Das war's für jetzt. Wenn Sie Fragen haben, beantworte ich diese gerne in den Kommentaren.
Vielen Dank an Tim Pietrusky für Kommentare und Korrekturen früherer Versionen dieses Tutorials.
Das sieht wirklich nützlich aus, danke für das Teilen. Es erinnert mich irgendwie an die Art und Weise, wie WordPress Bilddateien verkleinert und eine neue URL für die verkleinerte Version generiert.
Super cool!! danke.
Diese Technik bringt neue und innovative Wege hervor, wie Websites Bandbreite verschwenden können. Sie begnügen sich nicht mehr damit, 8-Megapixel-Bilder in 100×100 Pixel große Thumbnails zu quetschen (natürlich mit dem Browser), sondern können nun Dinge ausschneiden, die sie nie brauchen werden, ohne einen dieser lästigen Bildbearbeitungsprogramme öffnen zu müssen!
Ich widerspreche – wenn man Ihrer Logik folgt, sollten wir alle scharfen Werkzeuge abschaffen, weil sich manche Leute damit verletzen (oder andere verletzen)… richtig?
Es geht nicht um das „Werkzeug“, sondern darum, wie man es benutzt – sicher, manche Leute werden seltsame und/oder schlechte Wege finden, es zu benutzen, aber das macht diese Technik nicht nutzlos.
Ich frage mich, ob Server hier helfen könnten. Es wäre ziemlich magisch, wenn sie nur den angeforderten Teil des Bildes servieren würden.
@Chris
Nein, Server können hier nichts machen. Alles nach dem # wird nicht an den Server gesendet und kann dort nicht verarbeitet werden.
Tomasz, ich sage nicht, dass es NUR für dumme Dinge verwendet wird oder dass es abgeschafft werden sollte… nur, dass es definitiv passieren wird.
Es wäre einfach, ein PHP-Skript (und ich bin sicher, jede andere serverseitige Sprache) zu schreiben, das Bilder basierend auf diesen Parametern liefert, damit Sie keine Bandbreite verschwenden. Auf einer stark frequentierten Website würde dies jedoch zu einer erheblichen zusätzlichen Verarbeitung auf dem Server führen.
Großartige Sachen, danke fürs „Spielen mit neuen Dingen“.
Sehr cool, wird nützlich sein, um responsive Bilder anzuzeigen, ohne ein zugeschnittenes Bild für kleinere Bildschirme hochladen zu müssen. Obwohl dann immer noch das Bandbreitenproblem besteht…
Andererseits kann das Hochladen mehrerer zugeschnittener Bilder für kleinere Bildschirme zu mehr HTTP-Aufrufen führen, was für Mobilfunknetze ebenfalls ein Problem darstellt (Latenz macht es langsamer).
Ich freue mich darauf, dies auszuprobieren, sobald es etwas Mainstream-tauglicher ist. Vorerst müssen wir uns damit zufriedengeben, die Coolness zu genießen =)
Sehr interessant! Danke für das Teilen.
Danke! Aber ich frage mich – muss der Browser das ganze große Bild cachen und mir dann den zugeschnittenen Bereich anzeigen? Ich frage, weil wenn nicht – dann könnte es für Media Queries verwendet werden.
Ich konnte aus der Empfehlung nicht ganz erkennen, ob Media Fragments es uns auch ermöglichen werden, einen bestimmten Frame/Framebereich aus animierten GIFs/animierten PNGs auszuwählen? Wenn ja, fallen mir mindestens zwei Möglichkeiten ein, wie das genutzt werden könnte
a) Die Leistung eines einzelnen Bildes bei der Reduzierung von HTTP-Aufrufen weiter zu verbessern, indem mit GIFs und PNGs in 4 Dimensionen gesprited wird.
b) Ein einzelnes animiertes GIF oder PNG sowohl für den Basis- (nicht animierten) als auch für den Hover- (animierten) Zustand von animierten Schaltflächen zu verwenden. Theoretisch könnte man vielleicht sogar vom aktuellen Frame bei Mouseout zu einem anderen Frame zurückkehren.