Ein Gastbeitrag von Christian „Schepp“ Schaefer
Runde Ecken im Internet Explorer – das ist ein Thema, das uns jahrelang beschäftigt hat, um das es aber nahezu still geworden ist, da sich mittlerweile einige Techniken zur Simulation derselben als Best-Practices herausgeschält haben. Heute stelle ich Euch eine neue Technik vor.
Welche Techniken stehen denn bisher zur Auswahl?
Ignorieren
Man zieht sich auf den Standpunkt des „Progressive Enhancements“ zurück und kümmert sich erst gar nicht um eine Lösung für den IE.
Die „Mountaintop Corners“
Vorteil: Schnelle Farbänderungen am Objekt selbst sind problemlos möglich
Nachteil 1: Keine Eckentransparenz, funktioniert also nicht auf texturierten Seitenhintergründen, sondern nur auf flächigen, einfarbigen.
Nachteil 2: Für jede Farbänderung des Hintergrunds müssen neue Eck-Grafiken erstellt werden
„Sliding Doors“ Verfahren
Vorteil: Volle Eckentransparenz, funktioniert also auf texturierten Seitenhintergründen
Nachteil 1: Für jede Farbänderung am Objekt selbst müssen neue Grafiken erstellt werden
Nachteil 2: Nicht in zwei Achsen gleichzeitig flexibel dimensionierbar
VML Image Replacement
Dieses Verfahren ist das Jüngste von allen, und erfährt gerade in der letzten Zeit durch JavaScript-Extensions à la CSS3-PIE eine hohe Aufmerksamkeit. Hierbei wird per JavaScript oder IE-Behavior/.htc-Datei ein Script in die Seite eingebunden, das nach dem Laden der Seite die Stylesheets nach border-radius
-Anweisungen durchforstet und HTML-Elemente mit dieser Eigenschaft durch on-the-fly-berechnete VML-Vektorgrafiken ersetzt (vergleichbar mit sFIR oder cúfon).
Vorteile:
- Eckentransparenz, funktioniert also auf texturierten Seitenhintergründen
- Hintergrund des Objekts muss nicht einfarbig sein
- Flexibel dimensionierbar
- Schnelle Farbänderungen möglich
Nachteile:
- Arbeitete in den ursprünglichen Implementierungen statisch, reagiert also nicht auf Farb- oder Dimensionsänderungen beim Hover-Zustand, geschweige denn durch dynamisches Scripting.
- Zieht die Renderperformance des Browser stark in den Keller.
- Und weitere Nachteile
Wir stellen fest: Jede Technik für sich hat ganz spezifische Vor- und Nachteile. Die VML-Methode bedeutet für uns Webentwickler die wenigste Arbeit, fügt sich aber nicht in den bekannten Seitenkontext ein, bleibt unberechenbar und unperformant. Die Arbeit mit Grafiken dagegen ist berechenbarer und performant (wenn man mal HTTP-Requests ausblendet), ist jedoch unflexibel und arbeitsintensiv.
Müssen wir uns damit zufrieden geben? Haben wir keine besseren Methoden?
Doch, die haben wir! Wir bedienen uns dazu des mehr oder minder im Dornröschenschlaf befindlichen proprietären IE-Chroma-Filters.
Greenscreening im Browser
Den Chroma-Filter muss man sich wie einen Color-Keyer vorstellen, der alle Bereiche eines Objekts, die in einer speziellen Farbe eingefärbt sind, aus diesem herausstanzt. Das Ganze ähnelt also den Bluebox- oder Greenscreen-Verfahren bei Film und Fernsehen, bei denen Darsteller vor einfarbigen Leinwänden agieren, die dann transparent gemacht werden und eine virtuelle Szenerie durchscheinen lassen.
Mit folgendem Code können wir veranlassen, dass alle cyanfarbenen Teile eines Objekts transparent werden:
filter: progid:DXImageTransform.Microsoft.Chroma(color='cyan'); /* IE 6/7 Syntax */
-ms-filter: "progid:DXImageTransform.Microsoft.Chroma(color='cyan')"; /* IE 8 Syntax */
Anstatt „cyan“ könnte man auch #00FFFF
schreiben, und Cyan wurde als Farbe gewählt, weil kein Mensch mit klarem Verstand diese Farbe auf seiner Seite einsetzen würde.
Das Interessante am Chroma Filter ist, dass er auch solche Farbflächen beim Ausstanzen berücksichtigt, welche von Kindelementen des den Chroma-Filter-tragenden Elements stammen.
Deshalb könnte man ein Art roten Rahmen mit 10px Breite mit folgendem HTML erzeugen:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chroma Demo</title>
<style>
.foo {
width: 120px;
background-color: red;
filter: progid:DXImageTransform.Microsoft.Chroma(color='cyan'); /* IE 6/7 Syntax */
-ms-filter: "progid:DXImageTransform.Microsoft.Chroma(color='cyan')"; /* IE 8 Syntax */
}
.bar {
height: 100px;
margin: 10px;
background-color: cyan;
}
</style>
</head>
<body>
<div class="foo">
<div class="bar"></div>
</div>
</body>
</html>
Die komplette Fläche von .bar
würde aus dem Filter-tragenden .foo
herausgestanzt, da vollständig cyanfarben, und man könnte in der Mitte durchgucken.
Das wollen wir nun für unsere Runden Ecken weiter ausbauen. Wir erstellen eine Hintergrundgrafik von 2048 × 2048 in Photoshop, die voll transparent ist, bei der nur die Bereiche in den vier Ecken cyanfarben eingefärbt sind, welche den Bereich außerhalb der runden Ecken liegend darstellen (also das, was ich später ausstanzen will):
Dann erstelle ich das Objekt, dessen Ecken ich gerne rund hätte, indem ich einige DIVs ineinander verschachtele…
<div class="chroma_base">
<div class="chroma_topleft">
<div class="chroma_topright">
<div class="chroma_bottomright">
<div class="chroma_bottomleft">Drag me!</div>
</div>
</div>
</div>
</div>
…um dann meine Hintergrundgrafik .chroma_topleft
bis .chroma_bottomleft
zuzuweisen, jeweils mit unterschiedlicher Positionsverankerung:
.chroma_topleft,
.chroma_topright,
.chroma_bottomright,
.chroma_bottomleft {
background-image: url(chroma14px.gif);
background-color: transparent;
background-repeat: no-repeat;
}
.chroma_topleft {background-position: left top;}
.chroma_topright {background-position: right top;}
.chroma_bottomright {background-position: right bottom;}
.chroma_bottomleft {background-position: left bottom;}
(Anmerkung: Die obigen Anweisungen sollte man per Conditional Comments ausschließlich den IEs <= 8 servieren)
Der aktuelle Zwischenstand (rechte Seite zu Illustrationszwecken abgedunkelt):
.chroma_base
bekommt als Root-Element den Chroma-Filter und ein position: relative;
(oder absolute), damit alles in den älteren IEs sauber funktioniert. Dazu all die Styles, die mein Objekt abseits der Runden Ecken noch so haben soll, zum Beispiel Ausmaße und ein Hintergrundbild:
.chroma_base {
position: relative; /* Needed for IE 6/7 */
width: 200px;
line-height: 50px;
text-align: center;
background: #600118 url(gradientdark.png) repeat-x left top;
color: #FFF;
-moz-border-radius: 14px;
-webkit-border-radius: 14px;
border-radius: 14px;
filter: progid:DXImageTransform.Microsoft.Chroma(color='cyan'); /* IE 6/7 Syntax */
-ms-filter: "progid:DXImageTransform.Microsoft.Chroma(color='cyan')"; /* IE 8 Syntax */
}
Fertig ist die Laube und heraus kommt dies:
Das Schöne dabei ist: nun kann man jederzeit hingehen und nicht nur die Ausmaße sondern auch den Hintergrund ändern, alles ausschließlich per CSS, ohne Rückgriff auf Photoshop. Desweiteren beobachte ich, dass wenn Seiten einen border-radius
einsetzen, dass dieser aus Konsistenzgründen meist seitenweit denselben Radius hat. Ergo erschlägt man möglicherweise mit dieser einen Photoshop-Grafik direkt alle Fälle von border-radius
auf seiner Seite.
Die Lösung funktioniert sogar, wenn sowohl Seitenhintergrund als auch Objekthintergrund strukturierte Texturen sind. Und sie beißt sich auch nicht mit dynamischen Effekten à la Hover.
Funktioniert das denn auch mit einem Border?
Ja, das tut es! Dazu muss man allerdings die Grafik anpassen, wie auch noch ein paar Styles hinzufügen. Und wir verlieren etwas an Flexibilität und Eleganz.
Legen wir mal einen soliden Border von 2px Breite in der Farbe #808080
zugrunde. Die Grafik müssen wir dann an den Ecken folgendermaßen ergänzen:
Dem Root-Element geben wir diesen Border per CSS:
.chroma_base {
border: #808080 2px solid;
}
Darüber hinaus müssen wir dem ersten Kind-Element noch Styles überbügeln, die es über den, das Root-Element umgebenden Rahmen schieben lässt.
Für alle IE (per Conditional Comments):
.chroma_topleft {
margin: -2px; /* root border-width * (-1) */
}
Und zusätzlich für IE6 und IE7 (ebenfalls per Conditional Comments):
.chroma_base * {
position: relative; /* Needed so that border-overlaping works in IE 6/7 */
width: 204px; /* root width + (2 * root border-width) */
}
Zusammen mit einem helleren Hintergrund ergibt das folgendes Resultat:
Ebenfalls kann man hier jederzeit nicht nur die Ausmaße sondern auch den Hintergrund ändern, ohne Photoshop starten zu müssen. Die Bildbearbeitung müssen wir allerdings dann bemühen, wenn wir die Border-Farbe ändern wollen, da sie in der Chroma-Grafik fest „verdrahtet“ ist. Wir verlieren in der Border-Variante zudem die Option, dem Element eine fluide (%) Breite zu verpassen, zumindest wenn sie in IE6 und 7 funktionieren soll.
Ich nenne die Technik die „Chroma Corners“ und habe Euch ein Live-Beispiel unter folgender Adresse abgelegt:
http://www.peterkroener.de/test/chroma/ (Download ZIP).
Desweiteren habe ich das Ganze in ein kleines Softwarepaket gegossen, das aus einer proprietären IE-Behavior (.htc) und einem PHP-Script zur automatischen Generierung der Eckgrafiken besteht, die sich zusammen um all das Beschriebene kümmern – für Euch also kein Handschlag mehr zu tun als dies (mit angepastem .htc-Pfad):
-moz-border-radius: 14px;
-webkit-border-radius: 14px;
border-radius: 14px;
behavior: url(chromacorners.htc); /* relative path from HTML-file! */
Und zu guter letzt liegt darauf basierend auch schon ein Turbine-Plugin bereit, das in das nächste Release hineinwandern wird.
Über den Autor
Christian Schaefer ist Jahrgang '78, hat seine Wurzeln bei Köln, lebt seit 2004 unbehelligt in Düsseldorf, und wird von jedermann außer den Eltern „Schepp“ genannt. Und das ist auch gut so. Es verschlug ihn 1998 ohne Studium direkt in eine 3D-Firma in Köln. Dort entwickelte er virtuelle Figuren für Messen und TV. Selbstständigmachung Anfang 2004 und Verlagerung des Fokus' auf die Webentwicklung. Sieht seine Schwerpunkte bei der Frontend-Entwicklung, hat aber auch kein Problem mit Backends und dem Architekten großer Sites in PHP und MySQL. Fertige CMSe nerven ihn. Frameworks sind OK. Nebenbei unterstützt er technisch den Kölner Multimediatreff, hat gerade ein Videotraining biblischen Ausmaßes fertiggestellt. Er twittert unter dem Account derSchepp und mag alles was sich um Essen dreht.
Kommentare (9)
Thomas Scholz ¶
4. Oktober 2010, 07:36 Uhr
Großes Kino, Christian! Danke.
Könnte man eventuell mit einem weiteren Filter die Rahmenfarbe erfassen und ändern?
Ole ¶
4. Oktober 2010, 07:44 Uhr
Das ist ein sehr interessanter Ansatz. Allerdings aus meiner Sicht mit einem optischen Nachteil. Es ist wohl nicht möglich mit dieser Methode semi-transparente Ecken zu zaubern? Dieser "Treppen Gif Effekt" sieht einfach unschön aus.
Wenn man allerdings darüber hinwegsehen kann, ist das aber sicherlich ein guter IE-Fallback...
Schepp ¶
4. Oktober 2010, 07:46 Uhr
Zitat Thomas Scholz:
Dank Dir sehr!
Das will ich nicht ausschließen. Aber der direkte Weg funktionierte bei meinen Versuchen leider nicht - also zwei solcher Konstruktionen mit unterschiedlichen Farbkeys ineinander zu verschachteln.
Joker ¶
4. Oktober 2010, 07:50 Uhr
Das bläht den Code aber ganz schön auf, wenn man das öfters auf einer Seite macht...
Schepp ¶
4. Oktober 2010, 08:01 Uhr
Zitat Ole:
Geglättete Kanten funktionieren leider nicht, da der Filter nur exakt eine farbe keyen kann.
Du kannst die Kanten aber mithilfe eines anderen Tricks glätten, und zwar indem Du das Element größer anlegst und einen kleinskalierenden Matrix-Filter an den bestehenden Chroma-Filter anhängst, z.B.
Ist aber zugegebenermaßen recht deftig.
Schepp ¶
4. Oktober 2010, 09:46 Uhr
Zitat Joker:
Das tuts, ja. Aber davor ist auch keine der anderen Techniken gefeit (die VML-Variante erzeugt genauso neue DOM-Elemente). Und je nach Situation besser als nix.
Axel ¶
4. Oktober 2010, 12:54 Uhr
Was ist mit Raphaël? Das wäre doch auch eine Alternative, und die kam hier doch soweit ich weiß auch vor kurzem vor.
Schepp ¶
4. Oktober 2010, 13:04 Uhr
Zitat Axel:
Raphaël ist als Lösung noch ungeeigneter als die reine VML-Lösung, da es mit denselben Nachteilen daherkommt, gleichzeitig aber noch die „guten“ Browser mit unnötigen SVG-Routinen zumüllt. Zudem funktioniert die oben beschriebene Technik auch ohne JavaScript (sowohl die manuelle Variante, wie auch die .htc), was bei Raphaël nicht so ist.
Chris ¶
4. Oktober 2010, 19:18 Uhr
Vllt wäre es gut nocht zu erwähnen, dass es die "Raphael-Variante" gibt (darüber wurde erst neulich ein Beitrag geschrieben). Hierbei wird mit Hilfe des entwickelnden JS SVG inline eingebunden. Auf seiner Seite hat er dadurch die "runden Ecken" umgesetzt:
http://raphaeljs.com/
Nachteil:
- Geht ohne JS nicht
- "Bläht" den Quelltext auf (wobei vergleichsweise die "div-Varianten" und die super-extra-browserspezifischen fummeleinen auch nicht besser sind)
Ansonsten..finde ich persönlich "runde Ecken" nervig und den hype darum, seitdem jemand zeigen musste was mit CSS 3.x mögliche wäre wenn es doch alle Hersteller einbinden würden und wenn es Standard wäre, etwas nervig.
Frei nach dem Motto: "Früher gings auch ohne und man kann auch ohne gut aussehende Seiten bauen".
Schönen Abend und Gruß
Chris