Ich schraube im Moment an einem Projekt, bei dem ein Designer vielen Elementen einfarbig teiltransparente Hintergründe verordnet hat. Nun gibt es ja dank CSS3 Möglichkeiten, so etwas in Form einfacher Farbangaben (RGBa oder HSLa) einzubauen – allerdings ist es natürlich wie immer so, dass diese Features mit einem eklatanten Mangel an Browserunterstützung zu kämpfen haben. Schuldig im Sinne der Anklage ist neben dem Internet-Explorer-Clan auch Opera.
Warum keine PNG-Datei?
Theoretisch könnte man zur Lösung dieses Problems einfach ein 1×1 Pixel großes teiltransparentes PNG hernehmen und als Hintergrundbild verwenden. Das würde in Opera funktionieren und im IE könnte man sich das Ganze mit dem AlphaImageLoader zurechthacken. Gänzlich problemlos wäre das freilich nicht:
- Es müsste pro zusätzlicher Hintergrundfarbe mit einer zusätzlichen Bilddatei jongliert werden, für die auch bei jedem Seitenaufruf ein zusätzlicher HTTP-Request anfallen würde
- Die Verwendung des AlphaImageLoaders blockiert beim betroffenen Element bekanntlich interaktive Kindelementen (Links, Formulare), die dann nicht mehr benutzbar sind ohne ihrerseits mit position und z-index versehen zu sein
Je nach Art der Seite und Einsatzgebiet des Hintergrundes sind das durchaus Dinge, auf die man gerne verzichten kann. Also ran an die Trickserei.
Internet Explorer 6 und 7
Die Lösung ist beim IE die Verwendung eines Filters, der anders als der AlphaImageLoader keine negativen Effekte auf Kindelemente hat:
#test {
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99FF0080,endColorstr=#99FF0080);
}
Mit dem Gradient Filter zeichnet man einen Farbverlauf, der praktischerweise Transparenz unterstützt. Bei einem Farbwert wie beispielsweise #99FF0080
bestimmen die ersten beiden Stellen (in diesem Fall 99
) die Transparenz, der Rest ist eine altbekannte Hex-Farbangabe. Und wenn man einen Gradient mit zwei identischen Farbangaben notiert, erhält man eine schöne, gleichmäßige transparente Hintergrundfarbe.
So haben sich die Microsoft-Programmierer den Einsatz ihres Filters vielleicht nicht unbedingt vorgestellt, aber trotzdem bekommt man so einen schönen transparenten Hintergrund im IE 6 und 7.
Opera und alle anderen Browser
Bei den übrigen Browsern (Safari, Chrome, Firefox, Opera, IE8) gibt es diverse Möglichkeiten, teiltransparente Hintergrundfarben zu notieren – zum Beispiel verstehen Firefox und Safari bekanntlich die RGBa-Syntax aus CSS3. Eine einzige Möglichkeit wird aber von allen übrigen Browsern unterstützt: PNG-Grafiken als Base64-Codierte Data-URI.
Data-URIs erlauben es, den Inhalt einer eigentlich externen Datei in codierter Form innerhalb von HTML- und CSS-Dokumenten zu notieren. Das sieht dann meist so oder ähnlich aus:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAblQTFRFKQkAMhMAuDgAwUIAwkMAxUUAyEkAzEwA0FAA0lIA01QA1FQA2FgA3FwA3V0A318A4GAA4GEA42MA5WUA5mYA6GgA6WkA6moA////wUIA6moAAAAAAAAAAAAAAAAAFwQAHQoAoyMAxkYAw0QA6WkA6moAfxsAlTIAujoA1FQA01MA4GAAxkYA52gA6moApykAuz0A3l4A4WEArS0ArzAAsTIAszQAtjYAuDgAuToAuzwAyUoAzU0A0VEA1VUA2VkA3V0A4WEA4WIA5GQA5WUA5WYA52cA6GgA6WkA2m8exlET12IR8YUd7Ycl+6E964Ul+Z897IQi/aI8/aM8430X54Eb6oQe7ogi8owm8o4o85Is9JIs9ZUv9pAq9pUv95kz+Jkz+MaU+ZMt+Z03+ciW+pQu+p03+qFI+sye+6E7+8ub/JYw/KE7/M6g/Zcx/aQ+/aRL/aU//adR/cyc/cyd/eLG/erX/pgy/qdB/qhC/qlT/qpV/s6d/t/A/uLG/uvY/5kz/58//6ZN/6lD/6tW/79//7+A/9au/9ev/+DB/+TI//bt//fv//n0//r0//v3//z4//36////JF/UQAAAAFR0Uk5TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDxcaHjU1ampzc3ODg5mZra26urq8vMbGzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNHS3d309Pf3+fn5O/LV9QAAANBJREFUGBlVwb1Lw0AYB+B7P3rJpdU4lYLQRUQncRb8/0dd62YHUcEaS+Oby93lp+ggPg+t3H8kyya09ENe7LMoNZe+ZmEvPjyMmz1T8JJTHCxmXFXBKbV1vp2eDkUXwV33z0rf7qqj8xKTMwaUiMnyWFaL/sMEUCHJN6mbzPloCjCRzh7H4xPpRIdxghJ5DN08zA46Twyo7D1fuF3xhjOU96KIAc5ZXg5gICaRdlrbzrptilv0b69sMd0LSxXqajaWONGaq9DgV7YIOiVyf4AvU0l0TgH1sPoAAAAASUVORK5CYII%3D" alt="Das Feed-Icon dieser Website">
Wirkt auf den ersten Blick etwas unhandlich, hat aber durchaus so seine Daseinsberechtigung. Die englische Wikipedia hat einen guten Artikel zu diesem Thema. Die Vorteile kurz zusammengefasst:
- Keine zusätzlichen HTTP-Requests
- Gerade bei kleineren Dateien höhere Übertragungsgeschwindigkeit
- Die Internet Explorer 6 und 7, die mit PNGs eh nur Probleme bekommen würden, unterstützen Data-URIs gar nicht erst.
Problematisch (weil unübersichtlich) kann es werden, wenn man seinen Stylesheet im Übermaß mit Data-URIs vollstopft, was sich aber mit ein wenig vorausschauender Planung verhindern lassen sollte. Jedenfalls kann man mit Data-URIs PNGs einfügen, ohne dass die IE-Familie Ärger macht oder viele HTTP-Requests entstehen. Man erstelle sich einfach eine 1×1 Pixel große PNG-Datei mit der gewünschten Farbe und Transparent, konvertiere sie mit einem der zahlreichen Online-Konverter (z.B. diesem hier) in einen Datenstrom und binde das Ganze als CSS-Hintergrund ein:
#test {
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kFEhY5DjqCiFwAAAANSURBVAjXY/jP0FAPAAWAAf+rb6k5AAAAAElFTkSuQmCC);
}
Und fertig sind in allen Browsern funktionierende teiltransparente Hintergründe fast ohne PNG-Dateien – hier eine Testseite zum ausprobieren.
Lohnt sich das denn?
Nun bleibt natürlich die nicht ganz unberechtigte Frage, ob sich der ganze Aufwand lohnt. Das ist natürlich in erster Linie davon abhängig, wie sehr das Design auf transparente Hintergründe angwiesen ist – wenn das nicht so sehr der Fall ist, kann man sich die Mühe auch sparen und einfach abwärtskompatibles CSS3-RGBa verwenden:
#test {
background:#FF0080;
background:rgba(255, 0, 128, 0.5);
}
Wenn ein Browser RGBa nicht versteht, verwendet er statt dessen die zuletzt deklarierte Hintergrundfarbe, also in diesem Fall ein ganz normaler Hexcode. Falls man nur den älteren Internet Explorern die transparenten Hintergründe vorenthalten möchte, kann man anstelle des RGBa-Hintergrundes auch das codierte PNG verwenden und sich einfach den Gradient-Filter sparen.
Ansonsten finde ich diesen Trick nicht jetzt nicht so kompliziert, vorausgesetzt man plant ihn von Anfang an ein.
Kommentare (25)
Felix de Ruiter ¶
2. Juni 2009, 09:48 Uhr
Schöner Artikel, Peter! =)
Zu Opera: Zummindest Opera 10 (Preview) unterstützt RGBa und HSLa. :-)
JPanther ¶
2. Juni 2009, 10:58 Uhr
Solche Barrieren nerven langsam.
Momentan hab ich zwar mit ganz anderen Problemen zu kämpfen doch finde ich es peinlich das sich die Browser-Entwickler nicht an einheitliche Standards halten. Sicherlich wollen es einge auch einfach nicht und konzipieren ihre eigenen Normwerte. (IE)
Mein Motto:
Miteinander statt gegeneinander! Nicht nur in unserer realen Gesellschaft, sondern auch im Internet!
Gerrit van Aaken ¶
2. Juni 2009, 11:26 Uhr
Schick, schick! Danke.
Niels ¶
2. Juni 2009, 12:28 Uhr
Hast du vielleicht ein Beispiel parat, wie ein solches komplexes Design aussehen könnte? Mir fällt da grad nix dazu ein :-\ Also nichts, wo man die Transparenz auch irgendwie nur-so-als-ob aussehen lassen kann...
Thomas Kandler ¶
2. Juni 2009, 14:00 Uhr
Feine Sache. Danke für den Beitrag. :)
Peter ¶
2. Juni 2009, 14:03 Uhr
Danke für all die netten Kommentare!
Zitat Niels:
Also im konkreten Fall waren es Hintergründe eines Drop-Down-Menüs. Die hätte man natürlich nicht unbedingt transparent machen müssen, aber wenn man es hinkriegen kann, warum nicht?
Ingo ¶
2. Juni 2009, 15:36 Uhr
Kann man eigentlich CSS-Sprites mit resize kombinieren, um bei der "klassischen Methode" http-requests zu sparen?
ChrisB ¶
2. Juni 2009, 16:39 Uhr
Die Verwendung von 1X1 Pixel grossen Grafiken ist übrigens gar nicht so empfehlenswert - weil der Browser davon mehr "Kopien" erstellen muss, um damit eine grosse Fläche vollzukacheln. Das kann sich durchaus negativ auf die Performance auswirken - insb. in früheren Opera-Versionen war das teilweise ziemlich stark zu spüren, Scrolling wurde ruckelig, aber auch in anderen Browsern; insb. wenn wie hier noch Alphatransparenz hinzukommt, die der Rendering-Engine eh schon etwas "mehr" abverlangt. Eine grosszügiger dimensionierte Grafik ist in der Hinsicht empfehlenswerter. Und bzgl. Dateigrösse sollte sich der Unterschied bei bspw. 100 Pixln im Quadrat kaum bemerkbar machen - wenn eh alles eine Farbe ist, lässt sich das ja sehr sparsam komprimieren.
David Hellmann ¶
2. Juni 2009, 17:14 Uhr
Hm finde die PNG Hacks einfach nur nervig. Eine einfache Möglichkeit ist das png einfach in Fireworks abzuspeichern da das PNG8 mit Alphakanal speichern kann. Bei simplen Grafiken wie hier (einfarbig) kein Problem und geht super.
Einfaches Beispiel wäre zum Beispiel für 4 verschiende Backgroundfarben eine Datei von 4030 x 1px anzulegen und jeweils 1000px mit der farbe nach wahl zu füllen und 10px abstand dazwischen zu lassen. Dann hätte man nur einen HTTP-request und die grafik sollte auch sehr klein sein.
Das ganze dann mit repeat-y kacheln und fertig ist der Spaß.
Oder hab ich irgendwo einen Denkfehler?
Peter ¶
2. Juni 2009, 17:22 Uhr
Zitat Ingo:
Ich bin mir nicht sicher, ob ich verstehe was du meinst. Resize von was?
Zitat David Hellmann:
Minimal – eigentlich geht es ja gerade darum, den PNG-Filter eben nicht verwenden zu müssen. Und hinzu kommt, dass diese PNGs (die man auch ohne Fireworks mit pngquant hinkriegt) im IE6 nicht transparent sind. Das ist manchmal ganz praktisch, aber hier soll es ja um teiltransparente Hintergrundfarben in allen Browsern gehen.
Ingo ¶
2. Juni 2009, 18:54 Uhr
> Ich bin mir nicht sicher, ob ich verstehe was du meinst. Resize von was?
1px PNGs werden normal per resize auf die gewünschte Größe aufgeblasen, so wie du sie brauchst. Ist die Frage ob sich das mit CSS-Sprites (Ausschnitt vom Riesen-PNG) beißt.
David hat aber schon ne gute Lösung beschrieben: einfach den Kompressor machen lassen ;-)
Martin ¶
2. Juni 2009, 22:50 Uhr
Vielen Dank! Habe es sofort erfolgreich angewandt!
Marvin ¶
3. Juni 2009, 10:41 Uhr
schöne Lösung, müsste man glatt mal ausprobieren. Ich allerdings achte nicht mehr (bzw. nur noch wenn es unbedingt gefodert wird) auf den 6er. Wenn dem alle so viel Aufmerksamkeit schenken, dauert der Fall doch nur noch länger :)
Nico ¶
3. Juni 2009, 12:05 Uhr
Ich finde es einfach nur schrecklich sowas, warum man immer rumfummeln muss damit es dann auch in jedem Browser funktioniert. Wieso arbeiten die nicht mal etwas zusammen.
Erinnert mich auch immer wieder an die Anschlüsse für das Front Panel vom Gehäuse eines Computers, anstatt mal dort einen Standard einzubringen neeein 6 einzelne kleine Stecker die immer irgendwie reingefummelt werden müssen und dann auch noch immer unterschiedlich angeordnet sind.
datenkind ¶
3. Juni 2009, 16:43 Uhr
Mhhh, Datenströme.
Auf jeden Fall eine gute Idee. Hab mich mit dem Kram nur kurzfristig auseinandergesetzt und nie so richtig kapiert, wofür es gut sein könnte. Aber jetzt ist das klarer. Fein fein.
Tim Baumann ¶
6. Juni 2009, 14:29 Uhr
Tolle Technik, vielen Dank dafür!
Aber:
Die Frage stellt sich nun nicht mehr, weil ich einen kleinen Generator dafür gebaut habe. Er liefert das CSS fertig für Copy & Paste. Der Aufwand ist nun nicht höher als rgba zu verwenden.
Da wäre noch zu erwähnen, dass der IE8 anscheinend den
filter
immer noch kennt, darum musste ich auf nen Hack zurückgreifen, bei dem die Eigenschaft nur von IE6 und 7 interpretiert wird.Viel Spaß mit dem Tool!
Peter ¶
6. Juni 2009, 14:57 Uhr
Ach Mist, du hattest mir das Ding ja auch zwecks Veröffentlichung gemailt. Ist leider in meiner täglichen E-Mail-Flut untergegangen, sorry. Aber verbloggen werde ich es kommende Woche trotzdem mal, steht jetzt extra in groß auf meiner ToDo-Liste.
Andreas Hecht ¶
8. Juni 2009, 02:35 Uhr
Nicht uninteressant, um das mal so auszudrücken :-)
Vielen herzlichen Dank!
Ingo Chao ¶
8. Juni 2009, 19:56 Uhr
Bill Brown, http://www.theholiergrail.com/sandbox/rgba-cross-browser.php
Martin ¶
12. Juni 2009, 11:59 Uhr
Toller Artikel über die Kombination der verschiedenen Techniken:) kommt gleich in meine Delicious Bookmarks
Frank Hartmann ¶
12. November 2009, 10:09 Uhr
Einfach fantastisch!!!!!
Habe lange nach einer Lösung für IE8 gesucht und schwupps, mit diesem Tipp von Peter bzw. dem superklasse Tool von Tim hat es in genau 10 Sekunden mein Problem gelöst.
Wahnsinn!
Ich danke euch beiden!!!
Gruß, Frank
Frank Hartmann ¶
25. November 2009, 11:47 Uhr
Hallo,
es geht nicht mehr. Habt Ihr es auch bemerkt, oder spinne ich?
Vor 2 Wochen hatt es prima geklappt und jetzt öffne ich die unveränderte Website in IE8 und die Buttons sind nicht mehr transparent. (sondern wieder hellgrau - der vorhandene CSS-Wert für #nav, der durch die Transparenz in IE( per Hack * html #nav überschrieben wird)
Haben die ein Software-Ubdate über den IE8 gebügelt, das diese tolle Lösung verhindert? Bin ich verrückt?
Es geht um die Seite [Link auf Wunsch des Autors gelöscht]
CSS siehe:
[Link auf Wunsch des Autors gelöscht]
Danke für eure Hilfe!
Gruß, Frank
Tim ¶
25. November 2009, 14:06 Uhr
Hallo Frank,
ich habe deinen Fehler gefunden: du willst in deinem CSS dem IE8 die halbtransparente Farbe mit dem data-uri-Hintergrundbild verpassen. Dazu nutzt du den Star-Hack. Wie du aber auf dieser Testseite sehen kannst, interpretiert der IE8 diesen nicht mehr. Nimm doch statt Hacks lieber Conditional Comments, dann kann dir sowas nicht mehr passieren.
Schöne Grüße
Tim
Mario Bellino ¶
23. April 2010, 07:23 Uhr
Vielen Dank für den Beitrag und insbesondere @Tim, Danke für das Tool! Habe 2 Seiten damit umgesetzt, jedem, dem ich die Seiten zeige ist begeistert. Leider kann ich nicht 1:1 die Werte von meinem Grafiker übernehmen (z.B. 80% Transparenz), man muss ein bisschen rumprobieren, bis das Ergebnis so aussieht wie der Entwurf. Trotzdem geht es viel einfacher und besser.
Ciao,
Mario
Philipp ¶
18. März 2011, 15:16 Uhr
Was zum Henker mache ich denn falsch, wenn der gradient Filter zum RGBA simulieren nur im IE9 läuft, aber nicht in 6,7 und 8? Ich zweifel langsam an meiner Intelligenz...
background: rgba(164,164,164,0.95);
filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#11A4A4A4', endColorstr='#88A4A4A4');
zoom: 1;
Ich habe jetzt alles probiert, aber es klappt einfach nicht. Woran kann das nur liegen? Bin ich blind oder blöd?