Aufzählungszeichen mit CSS für Ausgeschlafene

Veröffentlicht am 28. Juli 2007

In Listen Grafiken als Aufzählungszeichen zu verwenden ist eigentlich kein Problem. Mit der CSS-Eigenschaft list-style-image lassen sich beliebige Grafiken als Bullets einsetzen, was auch von allen wichtigen Browsern unterstützt wird. Wenn man seine Liste mit dieser Anweisung eine eigene Aufzählungsgrafik verpassen möchte, wird das funktionieren, ohne wenn und aber. Allerdings ist dies unter Umständen nicht gut genug. Dieser Artikel soll zeigen, warum man seine Aufzählungszeichen nicht immer mit list-style-image umsetzen sollte.

Eine Alternative

Wenn wir einmal so tun, als gäbe es list-style-image nicht, wäre es nicht schwer, eine andere auf CSS basierende Lösung zu finden. Man müsste der fraglichen Liste einfach die Standard-Aufzälungszeichen stehlen, das gewünschte Bild als nicht-wiederholende Hintergrundgrafik der <li>-Elemente einsetzen und den Content der <li> einfach per Padding etwas einrücken.

Eine solche Konstruktion könnte in etwa wie folgt aussehen:

ul {
    list-style:none;
}
ul li {
    background:url('bullet.gif') no-repeat left center;
    padding-left:16px;
}

So weit, so logisch. Dass sich das Endergebnis dieses Stylesheets weitgehend mit dem deckt, was auch list-style-image ausgeben würde, ist klar. Viel komplizierter ist diese Methode auch nicht. Aber warum sollte man sie dem altbewährten list-style-image vorziehen?

Das Problem mit list-style-image

Alle Browser unterstützen list-style-image. Aber so etwas bedeutet, wie jeder leidgeprüfte CSSler weiß, noch lange keine einheitliche Darstellung. Bei Aufzählungszeichen fällt das besonders deutlich auf, denn hier kocht wirklich jeder Browser sein eigenes Süppchen und verschiebt die Bullets je nach Lust und Version.

Dieses Problem kennt die Methode mit der Hintergrundgrafik nicht! Dort sitzt die Grafik bei jedem Browser an der gleichen Stelle, was je nach Programm schon einen recht drastischen Unterschied ausmachen kann.

Aufzählungszeichen in verschiedenen Browsern
Oben: list-style-image
Unten: Hintergrundbild

Obrige Grafik ist aus dieser Demoseite entstanden, wo beide Methoden in den verschiedenen Browsern verglichen werden können.

Ein weiterer Vorteil: PNG für alte Internet Explorer

Der Internet Explorer 6 unterstützt transparente PNGs nur, wenn man etwas nachhilft. Allerdings funktioniert dieses Nachhelfen nicht bei Aufzählungszeichen, sondern nur bei <img>-Elementen und eben Hintergrundbildern. Ein weiteres Argument für die alternativen Aufzählungszeichen, allerdings sollte nicht vergessen werden, allerdings sollte nicht vergessen werden, dass IE-taugliche PNG-Hintergründe diversen Einschränkungen unterliegen.

Fazit

Die CSS-Eigenschaft list-style-image wird von allen Browsern unterstützt, aber nicht einheitlich dargestellt. Das muss keinesfalls ein Problem sein, nur wenn man seine Aufzählungszeichen exakt platzieren möchte, ist die Hintergrund-Methode die Lösung. Auch wenn transparente PNGs als Bullets zum Einstz kommen sollen (und auch noch im IE6 gut aussehen sollen), kommt man an dieser Methode nicht vorbei.

Drop-Down-Menü mit CSS und (fast) ohne Javascript

Veröffentlicht am 11. Juli 2007

Das Navigationsmenü von Kram-hochladen.de funktioniert zuverlässig in allen Browsern - sogar im Internet Explorer. Augenscheinlich sogar ohne Javascript und nur mit CSS, was aber, wenn man die IE betrachtet, nur bedingt stimmt. Aufgrund mehrfacher Anfragen habe ich dieses kompaktes Tutorial für die bei KH eingesetzte Art der Navigation geschrieben.

HTML-Struktur

Die Struktur der Navigation setzen wir sinnvollerweise als Liste in HTML um.

<ul id="navi">
  <li><a href="#">Willkommen</a></li>
  <li><a href="#">Über uns</a>
    <ul>
      <li><a href="#">Angebot</a></li>
      <li><a href="#">Geschichte</a></li>
      <li><a href="#">Jobs</a></li>
    </ul>
  </li>
  <li><a href="#">Projekte</a>
    <ul>
      <li><a href="#">Alpha</a></li>
      <li><a href="#">Beta</a></li>
      <li><a href="#">Gamma</a></li>
    </ul>
  </li>
  <li><a href="#">Impressum</a></li>
</ul>

In Sachen HTML ist damit auch schon die Arbeit getan, der Rest ist (fast) komplett mit CSS zu erledigen.

Gestaltung mit CSS

Bevor wir uns an die Funktionalität machen, wird die Liste zunächst optisch etwas zweckdienlicher gestaltet. Vor allem müssen die Listen von ihren üblichen Formatierungsmerkmalen (Aufzählungszeichen, Margins usw.) befreit werden. Wer schlau ist und einen Reset-Stylesheet benutzt, kann sich diesen Schritt natürlich sparen.

#navi, #navi ul {
    list-style-type:none;
    margin:0;
    padding:0;
}

Als nächstes werden die Oberpunkte der Navigation (im Beispiel: Willkommen, Über uns, Projekte und Impressum) horizontal angeordnet und in Form gebracht.

#navi li {
    width:128px;
    float:left;
}

Aufklapp-Funktion mit CSS

Um das Auf- und Einklappen des Menüs zu realisieren, bedienen wir uns der Pseudoklasse :hover. Die Listen mit den Unterpunkten werden ganz einfach ausgeblendet und nur dann angezeigt, wenn ihr Elternelement (das <li> des Oberpunktes) einen Mouseover meldet.

#navi li ul {
    display:none;
}
#navi li:hover ul {
    display:block;
}

Das wäre es eigentlich auch schon... gäbe es da nicht den immer noch verbreiteten Internet Explorer 6.

IE-Tauglichkeit mit HTC

Der IE6 unterstützt :hover ausschließlich für Links. Wie so oft hilft in solchen Fällen ein HTC-Script, mit dem man dem Browser nicht nur PNG-Unterstützung, sondern auch andere moderne Features beibringen kann - so auch :hover-Support für alle Elemente. Das unter LGPL stehende Script whatever:hover ist genau das, was wir brauchen.

Der Einbau erfolgt im Idealfall mittels einem mit Conditional Comments eingebundenen IE-Stylesheet.

body {
    behavior:url("csshover.htc");
}

Schon unterstützt der Internet Explorer :hover als hätte er es immer schon gekonnt. Die Navigation ist damit einsatzbereit.

Schlussbetrachtungen

Wie es die Überschrift des Artikels schon verrät, ganz ohne Javascript geht es eben nicht - eine HTC-Datei enthält nichts anderes als spezialisiertes JS. Das bedeutet auch, dass das Menü in einem Internet Explorer mit abgeschaltetem Javascript streikt.

Damit die Navigation auch schön aussieht, ist natürlich weiteres Styling nötig. Insbesondere müsste das Menü so positioniert werden, dass bei Aus- und Einklappen nicht darunter liegende Elemente verschoben werden. Eine andere Anordnung oder noch tiefere Verschachtelung ist natürlich auch immer möglich.

Wie so eine Navigation aussehen kann, lässt sich auf dieser Beispielseite (mit reichlich kommentierten CSS) betrachten.

Externe Links ohne automatische Inhalte auszeichnen

Veröffentlicht am 10. Juni 2007

Links, die von der eigenen Seite fortführen, kann und sollte man gesondert markieren. Das kommt der Usability zugute und ist auch aus rechtlicher Sicht zumindest nicht schädlich. Auf meiner Seite hier sind externe Links mit einem kleinen Pfeil am Ende gekennzeichnet. Realisiert ist das Ganze mit CSS2-Selektoren, die natürlich im Internet Explorer nicht funktionieren, aber ansonsten sehr bequem sind. So weit, so unspektakulär.

Interessant wird es, wenn man sich einmal ansieht, wie derartige Grafikanhängsel meist eingefügt werden. Oft wird an dieser Stelle weiter fortschrittliches CSS verwendet und man greift zu automatischen Inhalten. Das sieht dann in der Regel so oder ähnlich aus:

/* Erst mal allen Links, die mit http:// beginnen eine Grafik verpassen... */
a[href^="http://"]:link::after, a[href^="http://"]:visited::after {
    content:url("link_normal.png");
}
a[href^="http://"]:hover::after, a[href^="http://"]:active::after {
    content:url("link_hover.png");
}

/* ...und die dann wieder da entfernen, wo es nach dem http:// mit der Adresse MEINER Website weitergeht */
a[href^="http://www.seite.de"]:link::after,
a[href^="http://www.seite.de"]:visited::after,
a[href^="http://www.seite.de"]:hover::after,
a[href^="http://www.seite.de"]:active::after {
    content(" ");
}

Diese Methode funktioniert an sich auch ganz prächtig, aber einiges stört bei diesen mit content:url("") eingefügten Bildern ganz gewaltig: Link und Bild können durch einen Zeilenumbruch voneinander getrennt werden. So steht dann in der einen Zeile ein externer Link ohne Markierung und in der nächsten eine Markierung ohne Link. Hinzu kommt, dass das Entfernen von eingefügten Inhalten problematisch ist, denn je nach Browser ist entweder content:" ";, content:""; oder content:none; die einzige Lösung, die nicht ungewollte Leerstellen oder seltsames Verhalten der Links mit sich bringt.

Die Lösung: Vergessen wir die automatischen Inhalten und nehmen doch wieder Hintergrundbilder zur Hand.

/* Erst mal allen Links, die mit http:// beginnen eine Grafik verpassen... */
a[href^="http://"]:link, a[href^="http://"]:visited {
    padding-right:16px;
    background-image:url("link_normal.png");
    background-repeat:no-repeat;
    background-position:bottom right;
}
a[href^="http://"]:hover, a[href^="http://"]:active {
    padding-right:16px;
    background-image:url("link_hover.png");
    background-repeat:no-repeat;
    background-position:bottom right;
}

/* ...und die dann wieder da entfernen, wo es nach dem http:// mit der Adresse MEINER Website weitergeht */
a[href^="http://www.seite.de"]:link,
a[href^="http://www.seite.de"]:visited,
a[href^="http://www.seite.de"]:hover,
a[href^="http://www.seite.de"]:active {
    background-image:none;
    padding:0;
}

Das führt bei weniger Notwendigkeit für noch nicht ganz ausgereifte CSS2-Implementierungen zum optisch fast identischen Ergebnis, allerdings ohne das Problem bei Zeilenumbrüchen. Nachteilig ist, dass man diese Technik (logischerweise) nicht mit Hintergrundgrafik-Unterstreichungen kombinieren kann. Wer Zeichen statt Grafiken verwenden möchte (z.B. →) kommt ebenfalls an automatischen Inhalten und den damit verbundenen Problemen nicht vorbei.

PNG ohne Reue: Die Einschränkungen

Veröffentlicht am 12. April 2007

Als ich in meinen letzten Post zum Thema PNG verfasste, habe ich geschickterweise komplett vergessen, auf die Einschränkungen und wichtigen Details der PNG-Lösung hinzuweisen beziehungsweise eines dieser Probleme überhaupt zu recherchieren. Dies soll hier nachgeholt werden.

.HTC, Windows XP SP2 & Apache

Metax brachte mich darauf, nochmal zu recherchieren wie es um die Kompatibilität von .htc-Files steht. Dort gibt es in der Tat eine Lücke, denn der Apache Webserver liefert .htc-Dateien mit einem MIME-Type aus, den der Internet Explorer 6 unter Windows XP mit installiertem Service Pack 2 nicht annimmt. Dort wird text/x-component verlangt, der Apache aber sendet www/unknown.

Wie man das Problem (per .htaccess oder Serverkonfiguration) löst, kann man beim Support von Microsoft erfahren. Nutzer von Microsoft-Servern sollten sich hierüber keine Gedanken machen müssen.

Wie konfiguriere ich mein Hintergrund-PNG?

Eine nicht unberechtigte Frage von Jeena Paradies. Sie lässt sich auch (leider) sehr einfach mit gar nicht beantworten. Denn das was etwas leichtfertig als PNG für CSS-Hintergründe betitelt wurde, ist eigentlich kein richtiges CSS-Hintergrundbild:

(AlphaImageLoader Filter) displays an image within the boundaries of the object and between the object background and content, with options to clip or resize the image.

Eine mit dem Filter geladene Grafik kann man also nicht ohne weiteres positionieren oder kacheln - sie ist kein Hintergrundbild. Aus diesem Grund muss auch im IE-Stylesheet der eigentliche Hintergrund entfernt werden, sonst bekommt man das Hintergrundbild und das für den IE geladene PNG zu sehen.

Was an dieser Stelle vielleicht man ganz sinnvoll wäre, ist eine kurze Erklärung zum AlphaImageLoader und dem was dieser überhaupt kann. Hier nochmal das Beispiel aus dem ersten Artikel:

/* AlphaImageLoader in Aktion */
#element {
    width: 640px;
    background: none;
    filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale, src='bild.png');
}

Wie zu sehen ist, kennt der Filter drei Parameter. Während enabled und src wohl keiner Erklärung bedürfen, ist sizingMethod etwas interessanter, denn hier kann man etwas am Erscheinungsbild des Angezeigten verändern. Der Parameter kann einen von drei Werten annehmen:

crop: Clips the image to fit the dimensions of the object.
image:Default. Enlarges or reduces the border of the object to fit the dimensions of the image.
scale: Stretches or shrinks the image to fill the borders of the object.

Die einzigen Darstellungsoptionen die es gibt sind eine einfache Anzeige des Bildes links oben im betroffenen Element (crop) und ein Strecken des Bildes auf die Dimensionen des Elements (scale). Der andere Wert (image) reduziert das Element auf die Maße des Bildes und ist vermutlich in Sachen Hintergrund nur bedingt zu gebrauchen.

Also: Einen normalen gekachelten Hintergrund mit transparenten PNGs gibt es im Internet Explorer nicht. Man kann den AlphaImageLoader allerdings für Hintergrundbilder verwenden, wenn es sich um eine einfache Anzeige eines sich nicht wiederholenden, nicht positionierten Bildes handelt oder wenn das Strecken des PNGs eine optisch vertretbare Option darstellt - Bilder die nur 1px breit oder hoch sind sollten sich hierzu eignen. Eine positionierte, einfache Hintergrundgrafik könnte man unter Zuhilfenahme eines entsprechend platzierten Extra-Containers tricksen, in den dann das PNG gezeichnet wird.

Streikende Links

Ganz wichtig: Links in einem Container mit PNG-Hintergrund wie oben beschrieben funktionieren ohne weiteres nicht oder nur bedingt. Das liegt eben daran, dass das PNG irgendwo zwischen Inhalts- und Hintergrundebene umherschwirrt und dabei Links oder zumindest deren Mouseover-Effekte blockiert. Zum Glück lässt sich das recht einfach korrigieren:

/* In die ie.css */
#mein-png-container a {
    position: relative;
    z-index: 1000;
}

Das verändert nichts am Aussehen, bringt aber die Links wieder zum laufen. Weitere Fragen und Probleme bin ich gern bereit zu lösen.