Transparente PNGs im Internet Explorer 6 einsetzen

schreibt rene am 25. Juni 2009 in Ergänzungen. Kommentar verfassen, Trackback

Bei der Gestaltung einer Website sind sie sehr hilfreich, PNG 24-Dateien mit Alphakanal, die fein abgestufte Transparenzen erlauben. Ob als Layoutgrafik für weiche und flexible Schatten oder für Buttons verwendet, die sich jedem Hintergrund anpassen können, bieten sie im Regelfall viele Vorteile und erweitern die Möglichkeiten, was im Webdesigns umgesetzt werden kann. Die gute Nachricht: Mehr und mehr Internetnutzer greifen auf Browser zurück, die den Alphakanal korrekt darstellen können.

Das Problem

Die schlechte Nachricht: Je nach Messung und statistischer Auswertung nutzen immer noch ca. 10 - 20 % den Internet Explorer 6 (Stand: Juni 2009), der einzige noch relevante Browser, der nativ PNG-Grafiken nicht im vollen Funktionsumfang unterstützt (und auch in vielen anderen Aspekten versagt). Zwar zeigt der IE6 PNGs an, jedoch wird jeder (semi-) transparente Pixel anstatt mit dem eigentlichen Hintergrund mit einer statischen, türkisähnlichen Hintergrundfarbe gerendert. Dieser Umstand ist weder schön noch ästhetisch tolerierbar. Das Ignorieren des Browsers ist häufig auch keine Lösung, da die wenigstens Website-Betreiber mindestens 1/10 ihrer Besucher verprellen möchten.

Fehlerhafte Darstellung eines PNGs mit Alphamaske

Um sich des Problems zu entledigen, existieren mehrere Wege. Zum einen ließe sich im IE6 gänzlich auf transparente PNGs verzichten und stattdessen GIFs einsetzen. Da diese aber nur die Zustände durchsichtig oder Vollfarbe kennen, entsteht an Rändern meist eine unschöne Pixelkante.

Stufiger Transparenz-Rand bei einem GIF

Die gängige Lösung

Nun könnte man meinen, der IE6 ist schon ein altes Stück Software (erschienen am 27. August 2001) und der damalige Stand der Browser-Technik (de facto erhielt dessen Renderengine in all den Jahren nie eine nennenswerte Aktualisierung) war einfach noch nicht so weit. Doch kurioserweise bewegt der proprietäre Filter AlphaImageLoader den IE6 zu einer vollständigen Darstellung der PNG-Transparenz. Warum dies nicht gleich nativ eingebaut wurde, liegt wohl irgendwo tief in der Microsoft’schen Produktphilosophie verborgen.

Die Anwendung des Filters erfolgt in einer per Conditional Comments nur für den IE6 sichtbar gemachten CSS-Datei (siehe hierzu Kapitel 10 im Buch Webdesign mit Photoshop) und der Anweisung:

#button {
	background-image: none;
	filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true', sizingMethod='image' src='./button.png');
}

Dabei wird das eigentliche Hintergrundbild mit der AlphaImageLoader-Methode ersetzt. Dies hat unter anderem zur Folge, daß weitere Hintergrundattribute wie repeat und position keine Wirkung mehr zeigen. Leidlich entgegenwirken lässt sich dem durch die sizingMethod zugewiesenen Werte. Zur Verfügung stehen image, crop und scale.

Die drei sizingMethod-Zustände des AlphaImageLoaders image, crop, scale.

  • image reduziert das HTML-Element auf die Größe der Grafik
  • crop setzt das Bild ohne Skalierung in das HTML-Element an der linken oberen Ecke beginnend
  • scale verzerrt die Grafik auf die Größe des HTML-Elements

Mit der letztgenannten Methode lässt sich die Wiederholung des Hintergrundes simulieren. Zumindest funktioniert dies bei Grafiken, die in eine Dimension nur einen Pixel messen und in der anderen die jeweilige Größe des HTML-Elements einnehmen. Die Zerrung des 1 px großen Seite wirkt wie eine echte Wiederholung der Grafik. Glücklicherweise ist dies auch ein häufig aufkommender Anwendungsfall.

Als Dreingabe des inkompatiblen Verhaltens lässt der IE6 bei derart behandelten Elementen keine Interaktion mit den darin befindlichen Inhalten zu, so daß Links nicht mehr klickbar und Formularelemente nicht mehr nutzbar sind. Abhilfe schafft oft aber doch recht unzuverlässig das Zuweisen einer relativen Positionierung:

#button a {
	position: relative;
}

Neben diesen schwerwiegenden weil stellenweise unkontrollierbaren Nachteil kommt ein weiteres Ärgnis hinzu: Relative Pfade beziehen sich nicht wie in CSS-Anweisungen sonst üblich auf die Stylesheet-Datei, sondern nehmen das aufgerufene HTML-Dokument als Ausgangspunkt. Das mag im ersten Moment wenig fatal klingen, doch kommt man schnell in Verlegenheit, sollte sich die Pfadtiefe ändern:

http://www.domain.tld/erste-ebene/
http://www.domain.tld/erste-ebene/zweite-ebene/
http://www.domain.tld/erste-ebene/zweite-ebene/dritte-ebene/ usw.

Eine auf das HTML-Dokument bezogene relativer Pfad wie ./../layout/hintergrund.png ist schon mit der zweiten Ebene überfordert. Würde dieser sich hingegen auf die Lage der CSS-Datei beziehen, ist es egal, wie tief der URL-Pfad reicht, da sich die Bilder und Stylesheets immer an der gleichen Stelle befinden.

Natürlich lässt sich das Dilemma mit der Angabe eines absoluten Pfades wie http://www.domain.tld/layout/hintergrund.png leicht umgehen. Doch bleibt der schale Beigeschmack, diesen bei einer Domainänderung (z.B. beim Veröffentlichen der Website vom lokalen Speicher auf den Webspace) anpassen zu müssen.

Ein komfortabler Weg

Zumindest die Pfadinkonsistenz lässt sich mit einem kleinen Trick leicht umgehen, der im Laufe eines Webentwicklerlebens Zeit und Nerven spart. An dieser Stelle machen wir uns eine weitere nicht standardkonforme Technik des Internet Explorers zunutze, die Eigenschaft _behavior, mittels derer sich JavaScript-Code direkt in CSS-Anweisungen ausführen lässt. Das sollte nun nicht kruder klingen, als die ganze Situation allgemein schon ist. Anstatt also für jedes Element Hintergrundbilder einzeln mit einem absoluten Pfad zu ersetzen, genügt es dieses Script für alle relevanten Selektoren zu definieren:

#button, #button-2, #button-3 {
	_behavior: expression(  /* IE6 only - transparency with proper handling of relative URLs */
		this.__src = this.__src ? this.__src : this.currentStyle.backgroundImage.split('"')[1],
		this.style.background = "none",
		this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.__src + "', sizingMethod='image')");
}

Es wird das jeweilige Hintergrundbild, das vorher in der Haupt-Stylesheet-Datei festgelegt wurde als absoluter Pfad ausgelesen und in den AlphaImageLoader geschrieben. Nebenher blendet das Script das ursprüngliche Hintergrundbild aus, um Interferenzen zu vermeiden. Diese Zeilen müssen wie gesagt nur ein einziges Mal in den für den IE6 optimierten Stylesheets auftauchen (sofern keine andere sizingMethod gebraucht wird), da es keine elementbezogenen Angaben enthält.

Zum Thema browserübergreifende Transparenzen gibt es weitere Ansätze und Konzepte. Einen kleinen Auszug findet Ihr unter:

24ways.org: Transparent PNGs in Internet Explorer 6
peterkroener.de: Teiltransparente Hintergrundfarben …
PNG Fix Plugin for jQuery
Yatil.de: Nicht vom IE6 unterdrücken lassen!

[Post to Twitter]  [Post to Delicious] 

Eine Antwort zu “Transparente PNGs im Internet Explorer 6 einsetzen”

  1. Wow, so viel arbeit nur für die Transparenz.

    Leider ist es bei mir notwendig, da 30%!!!!! meiner Besucher noch IE6 benutzten ;(

    Aber danke für den hilfreichen Artikel, werde mich jetzt dran setzten.

    geschrieben am 25. Oktober 2009 um 00:30 Kommentar-Link

Eine Antwort hinterlassen