Code-Beispiel: "Fotorahmen" für Bilder per CSS

Ich präsentiere hier mal eine kleine Bastelei, die Bildern (mehr oder weniger) beliebiger Größe einen realistischen Foto-Look verpasst. Da ich nicht so der ganz besonders kreative Kopf bin, hab ich die Foto-Optik natürlich nicht selbst erdacht. Mein Dank gilt also einzig und allein Edvard Erlandsson, dem Ersteller des genial einfachen und im Ergebnis sehr effektvollen Tutorials Realistic Photo Print.

In einem ersten Versuch vor diversen Jahren hatte ich mich bereits einmal an dem Tutorial versucht; daraus resultierten die Bilder rechts oben auf diesen Seiten. Zugegeben - das Ergebnis ist verbesserungswürdig und sieht im Tutorial auch besser aus. Das soll hier aber keine Rolle spielen.

Zu Beginn erstmal das gewünschte Ergebnis: Bild ohne Rahmen Bild mit Rahmen Links das Original-Bild ohne Rahmen, rechts die verspielte Version (natürlich nur für Browser, die etwas mit CSS3 anfangen können).

Die Fragestellung

Entscheidend ist, dass der Aufwand des Erstellens solcher Bilder bei vielen Fotos recht hoch ist. Natürlich bastelt man sich eine einzige Vorlage, in die das tatsächliche Motiv dann immer wieder reinkopiert wird. Allerdings bedeutet das immer noch, jedes Mal den Umweg über Photoshop und das Exportieren des Ergebnisses in Kauf nehmen zu müssen. Außerdem verändert man damit das Original, obwohl es sich ja eigentlich nur um eine gestalterische Erweiterung handelt. Im Grunde "verstößt" dieses Vorgehen also gegen den Grundsatz der Trennung von Inhalt und Präsentation (auch wenn das Bild vielleicht keinen echten Inhalt transportiert - so wie auf diesen Seiten hier). Dies aber nur am Rande - eigentlich geht es hier natürlich um den Aufwand, der ja in allen Lebenslagen immer so gering wie möglich ausfallen sollte.

Die Fragestellung lautet also: Wie können Bilder (beliebiger Größe) dynamisch mit dem Look des verlinkten Tutorials versehen werden, ohne dass dabei "gephotoshoppt" oder überhaupt das Originalbild geändert werden muss?

Bisher hätte es sicher irgendwelche mehr oder weniger aufwändigen Wege entweder serverseitiger (GD-Lib von PHP vielleicht?) oder clientseitiger Natur per Javascript (keine Ahnung, wie man Grafiken hier bearbeiten und kombinieren kann) gegeben. Mit Sicherheit wäre zumindest der einmalige Aufwand hier aber recht hoch gewesen; außerdem belastet ein solches Vorgehen natürlich auch entweder den Server oder den Client über Gebühr. Wie auch immer: Dank CSS3 und der wunderbaren border-image ist das auch alles überflüssig!

Der Blanko-Rahmen

Aber fangen wir doch erstmal mit dem Material an. Mit Hilfe des Photo-Print-Tutorials ist es sehr einfach möglich, einen inhaltsfreien Rahmen zu erstellen. Ich erläutere das hier nicht im Einzelnen; man kann das Ganze ja an einem beliebigen Bild durchkaspern und dann die Inhaltsebene löschen oder ausblenden. Mein Ergebnis sieht folgendermaßen aus: Blanko-Rahmen

Im Gegensatz zum Tutorial ist das "Foto-Äußere" hier transparent gehalten, sodass der Rahmen auf beliebigen Hintergründen genutzt werden kann - zumindest moderne Browser dürften damit kein Problem haben. Und für andere ist der ganze Kram hier eh nicht gedacht - schließlich reden wir ja von CSS 3.

Die CSS-Regel(n)

Der CSS-Part dieser Geschichte ist wirklich denkbar einfach. Allerdings sollte man sich kurz Zeit nehmen, die border-image-Eigenschaft zu verstehen. Die genauen Verhaltensweisen will ich hier allerdings nicht erläutern (s. Link oben - außerdem gibt es im Netz einen Haufen gute Texte dazu). Ich halte mich an das Fotorahmen-Beispiel. Erstmal aber ein bisschen CSS:

img.frameExample { border-width: 15px; border-color: transparent; border-image: url(../images/frame.png) 15 15 15 15 stretch stretch; }

Die Rahmenbreite und -farbe (bzw. -transparenz) sollten keine Fragen aufkommen lassen. Der Klassenname "frameExample" ist natürlich unterirdisch schlecht; aber auch das ist unbedeutend. Entscheidend ist die letzte CSS-Eigenschaft mit ihren Werten: Neben dem Pfad zum Rahmenbild werden hier noch Abmessungen und Verhaltensweisen festgelegt.

Die vier 15er-Werte lassen sich am besten anhand der folgenden Grafik erläutern (wobei ich hier mal einen weißen Hintergrund für das Foto-Äußere gewählt habe): Blanko-Rahmen mit Hilfslinien Das Bild wird also offensichtlich durch vier Linien in neun Teile geteilt (die 15 Pixel sind bei dieser Grafik nicht exakt abgemessen - es geht ja mehr ums Prinzip). Angefangen wird - wie bei anderen CSS-Eigenschaften auch - oben; dann geht es im Uhrzeigersinn auf die rechte, die untere und zuletzt die linke Seite.

Von den neun Feldern sind nur die acht äußeren von Bedeutung. Dabei werden die Ecken natürlich für die "Border-Ecken" und die Geraden für die Stücke dazwischen verwendet. In diesem Beispiel empfiehlt es sich also, die Pixelgrößen des Rahmens (border-width) gleich den Pixelgrößen des Rahmenbildes (also die verschiedenen 15er-Werte von border-image) zu wählen, damit es hier nicht zu ungewollten Verzerrungseffekten kommt.

Entscheidend für die dynamische Anpassung an die jeweilige Bildgröße ist aber das Verhalten der "Rahmengeraden". Die beiden "stretch"-Werte sorgen hier dafür, dass diese Geraden jeweils in die Länge gezogen werden. So ist gewährleistet, dass die verschiedenen Schattenkanten an den richtigen Stellen wieder andocken und ein flüssiger Gesamteindruck entsteht.

Natürlich funktioniert das heute noch nicht in aller Pracht in allen Browsern, da border-image nicht endgültig unterstützt wird. Allerdings haben die meisten Hersteller das Ganze bereits mit ihren Präfixen umgesetzt, sodass folgende zusätzliche CSS-Regel für eine breite Verwendbarkeit sorgt:

img.frameExample { -webkit-border-image: url(../images/frame.png) 15 15 15 15 stretch stretch; -moz-border-image: url(../images/frame.png) 15 15 15 15 stretch stretch; -ms-border-image: url(../images/frame.png) 15 15 15 15 stretch stretch; -o-border-image: url(../images/frame.png) 15 15 15 15 stretch stretch; }

Ich packe derartigen Kram gerne in eine eigene CSS-Datei namens "experimental.css" und versehe meine eigentlichen CSS-Ressourcen ausschließlich mit den präfix-losen Eigenschaften. Das ist aber natürlich nur eine persönliche Vorliebe.

Ergebnis

Browser, die damit umgehen können, müssten Original und gerahmte Version nun entsprechend unterschiedlich darstellen: Bild ohne Rahmen Bild mit Rahmen

Anmerkungen

Natürlich kann das Rahmenbild gerne von allen genutzt werden. Für den praktischen Einsatz empfiehlt sich sicher noch eine Verkleinerung der Dateigröße; ich habe hier erstmal keinerlei Optimierungen vorgenommen. Man könnte dies wohl erstmal über kleinere Abmessungen erreichen; allerdings dürfte das beim Einsatz für große Inhaltsbilder durch das "Stretchen" vielleicht den Gesamteindruck trüben.

Der seltsame Gelbschleier ist eigentlich überflüssig; hier sollte wohl mal ein Lichteinfall und/oder eine gewisse Vergilbung erreicht werden. Im Tutorial ist das sehr viel dezenter, ich war hier etwas achtlos. Sieht nicht so toll aus. Aber egal.

Verwendung findet das Ganze übrigens auch auf meinen neuen Galerieseiten unter http://monochromophob.de. Es gibt dort derzeit noch sehr wenig öffentliche Bilder; das wird sich allerdings hoffentlich bald ändern.

Letzte Änderung: 17. November 2010