This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Bibliografische Information Der Deutschen Bibliothek Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.ddb.de abrufbar.
Text und Webdesigns: Jens Meiert und Ingo Helmdach, mit Beiträgen von Gerrit van Aaken Lektorat: Michael Gerth, Inken Kiupel, Köln Korrektorat: Oliver Mosler, Köln Fachgutachten: Jørgen W. Lang, Jens Grochtdreis, Moritz Sauer Satz: Conrad Neumann, München Umschlaggestaltung: Michael Henri Oreal, Köln Produktion: Karin Driesen, Köln Belichtung, Druck und buchbinderische Verarbeitung: Media-Print, Paderborn ISBN-13 978-3-89721-712-6 Dieses Buch ist auf 100% chlorfrei gebleichtem Papier gedruckt.
Für meine Eltern, Hermann und Andrea Meiert. Jens Meiert
Mein erster Eindruck von CSS war nicht gerade überwältigend. Ich las den Text auf w3.org und verstand ungefähr so viel wie bei meiner Einkommen steuererklärung. Außerdem waren die meisten Kunden der Agentur, bei der ich damals arbeitete, mit Internet Explorer 4 unterwegs, der noch keine CSS-Unterstützung besaß. CSS wurde interessanter, als die meisten Webbenutzer IE 5 und IE 5.5 hatten und ich auf einen Zeitschriftenartikel stieß, der mir CSS auf eine andere Art und Weise nahebrachte. Der Artikel zeigte das Foto eines Dirigenten und erklärte, dass man mit CSS viel schnellere und einfacher zu verändernde Seiten erstellen kann. Die HTML-Seiten würden kleiner werden und bei einer Änderung des Designs müssten nicht mehr alle HTMLDokumente einer Website geändert werden, sondern nur noch ein einziges CSS-Dokument. Klasse, von diesem Moment an war auch ich auf den CSSZug aufgesprungen. Der große Durchbruch für CSS war dann eine Seite namens CSS Zen Garden. Dave Shea bewies mit diesem Projekt, dass man mittels CSS ein HTML-Dokument vollkommen unterschiedlich darstellen kann, ohne den HTML-Code zu ändern. Dutzende, wenn nicht inzwischen Hunderte von Designer stürzten sich auf diese Gelegenheit, um ihr Können unter Beweis zu stellen. In vielen Verkaufsgesprächen wird der CSS Zen Garden gerne als Beispiel angeführt, da durch die vielen schönen Designs der Vorteil von CSS auch technisch nicht so interessierten Kunden deutlich wird. Der Erfolg von CSS hat allerdings auch eine Kehrseite: Viele der Designs verlassen sich inzwischen darauf, dass im HTML-Code jede Menge Klassen und IDs vorhanden sind, und viele der neueren Designs basieren hauptsächlich auf dem Trick, Texte durch Hintergrundgrafiken zu ersetzen. Manche Designs fügen sogar neue Texte hinzu oder ändern den Text. Mit anderen Worten, CSS wird mehr und mehr zu einem Design- und Inhalte-Ersatz. Anstatt sich darauf zu konzentrieren, was HTML ist, bevor man CSS verwendet, um sich um die Darstellung zu kümmern, wird CSS zu oft als Lösung für alles benutzt. xv
Ein guter CSS-Entwickler braucht um einiges mehr als nur das Wissen, wie man CSS schreibt. Er sollte auch wissen, welche Browser wie versagen, was Benutzer in ihren Browsern verändern müssen, um die Seite lesen zu können (Stichwort Schriftgröße), und welche HTML-Elemente sinnvoll sind, um ein bestimmtes Problem zu lösen. Das ist eine ganze Menge an Wissen und kann sehr langweilig werden. Zum Glück gibt es Lernbeispiele wie dieses Buch, in dem genau diese Prinzipien anhand von Beispielseiten erklärt werden. Schritt-für-Schritt-Erklärungen, wie eine Seite erstellt wird, machen es viel einfacher am Ball zu bleiben. Und wenn man nebenbei die nötigen Tricks und Kniffe lernt, umso besser.
xvi
Vorwort
Einleitung
Einleitung
Dieses Buch beschäftigt sich damit, wie man gutes Webdesign auf der Basis von XHTML und Cascading Style Sheets (CSS) realisiert. 30 praxisnahe Beispiele sollen einen Eindruck vermitteln, wie man mit CSS auf einfache und zugängliche Art anspruchsvolle Designs verwirklichen kann. Ebenso sollen sie veranschaulichen, wie viel Gestaltungsfreiraum CSS bietet und wie viele mögliche Herangehensweisen es gibt, Ideen in die Tat umzu setzen. Beim Schreiben dieses Buchs galt es, einige Finessen im Umgang mit CSS und beim Einsatz bestimmter Techniken herauszustellen. Nur am Rande wird auf besondere Aspekte in Bezug auf Barrierefreiheit eingegangen. Die durchgehende Trennung von semantischer Struktur und der Präsentation gewährleistet jedoch bereits ein gewisses Maß an Zugänglichkeit, und nahe zu alle Beispiele in diesem Buch erfüllen die Barrierefreiheitsrichtlinien des W3C mindestens in Form der »Web Content Accessibility Guidelines« (WCAG) Level A. Gutes Webdesign ist das Produkt aus spezifikationsgetreu verwendetem HTML und CSS, bei deren Entwicklung man auf die Bedürfnisse aller und vor allem Menschen mit Behinderungen eingeht, informativen und dekorativen Bildern sowie erwiesener Benutzerfreundlichkeit. Leider konnte es nicht Aufgabe dieses Buchs sein, die Benutzerfreundlichkeit aller Beispiele über Nutzertests zu garantieren. Der Leser wird jedoch ermutigt, diesem Aspekt bei seiner Arbeit große Bedeutung beizumessen – ein visuell ansprechendes Design, das nicht bedienbar ist und somit nicht funktioniert, ist kein gutes Design.
Technische Hinweise Webdesign mit CSS wendet sich an Webdesigner und Webentwickler, die gute CSS-Kenntnisse besitzen. Vertrautheit mit HTML/XHTML wird vorausgesetzt, und damit nicht nur das Wissen um die Syntax, sondern auch um Validität und Semantik.
xvii
Als Dokumenttyp aller Designs, mit Ausnahme von »Bildunterschriften«, wurde XHTML 1.0 Strict gewählt. Auf HTML 4.01 wurde verzichtet, um von den Vorteilen von XHTML – wie der einfachen, XML-ähnlichen Syntax – zu profitieren. XHTML 1.1 schied als Dokumenttyp aus, da es mit dem MIME-Typ application/xhtml+xml ausgeliefert werden muss, was bei herunterladbaren Dateien wie bei diesem Buch nicht garantiert werden kann. Zudem kann der Internet Explorer keine Dokumente mit diesem MIMETyp parsen. Ein einfacher Austausch der DOCTYPE-Deklaration ist jedoch möglich, alle Codebeispiele validieren auch gegen XHTML 1.1. Alle Designbeispiele in diesem Buch wurden auf Kompatibilität mit folgenden Browserversionen hin getestet: Firefox ab Version 1.5, Internet Explorer ab Version 6.0, Opera ab Version 8.0 und Safari ab Version 2.0. In Browsern wie Mozilla, Netscape Navigator oder Konqueror wurde ebenfalls getestet, aber aufgrund entweder derselben technischen Basis wie Firefox oder der sehr geringen Verbreitung nicht so intensiv wie in den vorher genannten Browsern. Sollten einzelne Designs oder Designabschnitte in einer genannten Browser version nicht funktionieren, wird separat darauf hingewiesen. Aufgrund der Vielzahl der Systeme und einzelnen Browserversionen kann leider keine vollständige Gewähr übernommen werden. Das CSS wird mitsamt etwaiger Besonderheiten detailliert besprochen, beispielsweise wenn Selektoren nicht überall unterstützt werden oder gar CSS-3-Eigenschaften eingesetzt werden. Die Beispiele berücksichtigen pauschal alle Medientypen, auf DruckStylesheets wird somit nicht eingegangen. In allen Beispielen kommt eine Regel zum Einsatz, die »global« alle Innenund Außenabstände zurücksetzt: * { margin: 0; padding: 0; }
Diese Regel stellt sicher, dass browserspezifische Unterschiede bezüglich dieser Abstände eliminiert werden. Sollten Abstände notwendig sein, werden sie explizit angegeben und erklärt. Es gibt auch einige Fälle, in denen nebensächliche Zuweisungen nicht explizit aufgeführt werden – zum Beispiel, wenn ein Innenabstand auf dem body-Element zwar nützlich, aber für das umzusetzende Design nur von marginaler Bedeutung ist. Wird der gesamte CSS-Code am Ende eines Beispiels aufgelistet, findet man diese Regeln dort wieder, ebenso sind sie natürlich in den online verfügbaren Dateien vorhanden. »Hacks« oder »Filter« werden nahezu gar nicht verwendet, es wird höchs tens auf Kindselektoren zurückgegriffen (die per definitionem keine xviii
Einleitung
»Hacks« darstellen), um andere Browser als den Internet Explorer 6 zu adressieren. In der Regel wird darauf im Text eingegangen. In puncto Bildersatz oder »Image Replacement« wird mit der PharkMethode gearbeitet. Sie wird von uns zumeist verwendet, um bestimmte Effekte umsetzen zu können, die über gewöhnlichen Text hinausreichen. Da die Phark-Methode in diesem Buch sehr oft und mit gesonderten Hinweisen zum Einsatz kommt und in Kapitel 19, »Newsletter-Formular«, auch noch etwas ausführlicher auf Bildersatztechniken eingegangen wird, soll hier lediglich auf sie hingewiesen werden. Die große Stärke der PharkMethode liegt in ihrer Einfachheit. Sie erfordert nur ein Hintergrundbild als Textersatz, und der Text selbst wird einfach über einen großen negativen Wert der text-indent-Eigenschaft ausgeblendet. Unsere CSS-Codes unterliegen einer festen Struktur, die erst irritieren kann, dann aber nützlich sein wird. Die Richtlinien, nach denen der Code organisiert ist, bestehen darin, mit universellen Regeln zu beginnen und dann mit Block- sowie Inline-Elementen fortzufahren. Bei kombinierten oder gruppierten Selektoren wird der erste Selektor herangezogen. Innerhalb der Sortierung wird bei Blockelementen von »außen« (zum Beispiel html, body) nach »innen« sowie nach Semantik (zum Beispiel h1 vor p vor div) sortiert. Deklarationen werden alphabetisch geordnet. Ein kleines Beispiel dafür, ohne Deklarationen: * { } html { } body { } h1 { } p { } p, div { } div { } div#nav { } a { } span { }
Unabhängig von den genauen Regeln, die man anwendet, um Stylesheets zu sortieren, erhöht jede Form der Organisation die Übersichtlichkeit und spart Zeit. Ein weiteres Charakteristikum für dieses Buch ist es, dass ebenfalls zur Erhöhung der Übersichtlichkeit und zur leichten, ungefährlichen Erweiterung des Markups oftmals zusätzlicher, nicht zwingend notwendiger Code für Selektoren gebraucht wird. Beispiele hierfür reichen von Navigationslisten, bei denen der Selektor ul#nav anstelle von #nav verwendet wird, bis hin zu komplexen Hilfskonstrukten, wo möglicherweise Selektoren à la div#nav a.aktiv anstelle von .aktiv eingesetzt werden. Das dient dem besseren Verständnis, denn die angewandten Regeln sind so aussagekräftiger und können nach der oben dargestellten Struktur besser sortiert werden.
Einleitung
xix
Zuletzt verdienen noch die Schriftzuweisungen besondere Erwähnung. Die Schriftgröße wird im gesamten Buch in Prozent angegeben und auf dem html-Element angewendet. Die Angabe in Prozent ist sinnvoll, damit die Schrift auch im Internet Explorer 6 skalierbar ist – dieser Browser wird uns doch noch ein wenig erhalten bleiben. Viele Leser sind es zudem gewohnt, Schriften und auch Farben auf dem body-Element zu setzen, ich empfehle jedoch, diese Angaben auf dem Hauptelement vorzunehmen. Das hat drei einfache Gründe: Erstens ist dies grundsätzlich ungefährlich, da Schriften und Farben vererbt werden. Zweitens (und in Bezug auf zum Beispiel Hintergrundfarben) spannt nicht das body-Element, sondern das html-Element den Viewport auf. Und drittens erscheint es nicht unbedingt schlüssig, solch allgemeingültige Zuweisungen erst mittendrin zu treffen. Während Schriftzuweisungen so gehalten sind, dass sie auch im Internet Explorer 6 keine Hürde in Form vereitelter Schriftskalierung darstellen, kann es in Einzelfällen zu Skalierungsproblemen kommen. Diese werden bei den betroffenenen Stellen üblicherweise angesprochen. Sie resultieren in der Regel entweder aus den Einschränkungen durch vorgegebene Maße und Bilder oder aus dem Bemühen, eine Vielzahl von mitunter einfachen Techniken zu illustrieren. Außerdem sollte ein Buch über modernes Webdesign nicht nur »Best Practices«, sondern auch Fallstricke aufzeigen können.
Webseite zum Buch Als Ergänzung zu diesem Buch dient eine spezielle Webseite: http://meiert.com/cssdesign/ Unter dieser Adresse können Sie alle vorgestellten Designs mitsamt Quelltext und Bildern herunterladen. Die CSS- und XHTML-Beispieldateien (aber nicht die Bild-Dateien) können Sie für Ihre eigenen Zwecke frei verwenden. Auf dieser Webseite finden Sie außerdem die Berichtigungen von Fehlern, die wir trotz zahlreicher Lektoratsrunden erst nach dem Druck des Buchs entdecken.
Zur Entstehung dieses Buchs Die meisten Designs wurden in Photoshop entworfen und entstammen der Feder von Ingo Helmdach. Eine Reihe von Beispielen wurde von mir selbst kreiert. Gerrit van Aaken steuerte bereits zur 1. Auflage die Designs der Fotogalerie, der Web-Bücherei, der Navigation »Fischwelten« sowie der Vergleichstabelle bei, bei letzterer auch die Erklärung. Bei der Erstellung der Designs kam neben Photoshop, das auch zum Zurechtschneiden der einzelnen Bilder diente, ein einfacher Editor mit xx
Einleitung
Syntaxhervorhebung zum Einsatz. Für die famosen Blindtexte half ein »Lorem Ipsum«-Generator aus. Zur Validierung wurden sowohl der W3CMarkup-Validierer als auch der W3C-CSS-Validierer eingesetzt. Sofern weitere Prüfungen vorgenommen wurden, geschah dies zumeist über die Analyse-Linkliste von UITest.com. Bei dem vorliegenden Buch handelt es sich um die 2. Auflage von Webdesign mit CSS. Naturgemäß beinhalten Neuauflagen von Büchern einige Änderungen und Neuerungen, und so gestaltet es sich auch hier. Viele optisch überarbeitete Kapitel und vier neue Designs, die auch inhaltlich neue Aspekte bieten wie das hCalendar-Mikroformat oder das »hasLayout«-Konzept, sind die offensichtlichsten Neuerungen. Die weiteren Anpassungen sind vor allem technischer Natur. So wurde unter anderem die Unterstützung für den halbtoten Internet Explorer 5 aufgegeben, während der IE 7 und Firefox 2 neu berücksichtigt wurden. Sowohl Designs als auch Code wurden typografisch verbessert. Der neue Standard-Dokumenttyp für alle Codebeispiele (ehemals XHTML 1.0 Transitional, jetzt XHTML 1.0 Strict), behobene Zeichencodierungsdefizite und das ergänzte »content-style-type«-Metaelement sind weitere technische Verfeinerungen. Betrachtet man das Entwerfen und Entwickeln von Online-Angeboten korrekterweise als Prozess, ist die zweite Auflage dieses Buchs dafür ein gutes Beispiel: Der Anspruch ist eine sinnvolle Überarbeitung, kein hektischer Neubeginn.
Referenzen Unter den folgenden Adressen finden Sie weiterführende Informationen zu den in dieser Einleitung angesprochenen Techniken, Hacks und Werk zeugen: • »Web Content Accessibility Guidelines« 1.0 http://www.w3.org/TR/WAI-WEBCONTENT/ • Mike Rundle: Die Phark-Methode http://phark.typepad.com/phark/2003/08/accessible_imag.html • Jens Meiert: XHTML- und CSS-Code-Richtlinien bei GMX http://meiert.com/de/publications/articles/20060326/ • CSS-Spezifikation: Spezifizierte, berechnete und tatsächliche Werte http://www.w3.org/TR/CSS21/cascade.html#q1 • »Lorem Ipsum«-Generator http://lipsum.org/ Einleitung
xxi
• W3C-Markup-Validierer http://validator.w3.org/ • W3C-CSS-Validierer http://jigsaw.w3.org/css-validator/ • UITest.com: Analyse http://uitest.com/de/analysis/ Zusätzlich zu diesen Links finden Sie jeweils am Ende der Design besprechungen eine Liste mit weiterführenden Quellen zu speziellen Techniken, die für das jeweilige Design eingesetzt wurden. Jens Meiert, September 2005, aktualisiert im Mai 2007
Danksagungen Unser besonderer Dank gilt Michael Gerth, ohne den dieses Buch nicht entstanden wäre, sowie Inken Kiupel. Ebenso danken wir unseren Freunden Marina Bosse, Sabine Riedel, Barbara Christiane Müller, Arne und Jan Hummel, Karsten Gorissen und Benjamin Fiedler. Jens Meiert und Ingo Helmdach
xxii
Einleitung
Seitenvorlagen
In diesem Teil geht es um vollständige Webseiten, deren Realisierung nicht nur von einer einzelnen Technik abhängt. Er soll einen ersten Eindruck von der Vielfalt an Wegen vermitteln, die CSS Webdesignern und Webentwicklern offeriert. Teil I bietet zudem Einblick in bestimmte Vorgehensweisen, vor allem in Bezug auf die Struktur einer Webseite und ihres HTML-Markups.
I In diesem Teil 1 Fließlayout »Porto Seguro« 2 Fotogalerie 3 Web-Bücherei 4 Spaltenlayout »Alias« 5 Fließlayout »World of Fish« 6 Konsole 7 Spaltenlayout »Chat & mehr!« 8 Fließlayout »PC-Shop« 9 Spaltenlayout »Anodesign«
Fließlayout »Porto Seguro« Urlaubszeit! Wir sind von unseren Ferien in Porto Seguro derart begeistert, dass wir dazu gleich eine kleine Website aufsetzen wollen. Unser Anspruch: ein voll flexibles, »fließendes« Layout.
1 Schwierigkeitsgrad: mittel
Abbildung 1-1: Fließlayout »Porto Seguro«
Grundgerüst Das HTML für unsere Website ergibt sich durch die Inhalte. Dazu gehören die »Seiten-Identität« sowie einen Inhaltsbereich mit »Geschichte«, »Brasilien erleben« und »Fotos«. Abbildung 1-2: foto-1.jpg, 78 x 78 Pixel
Über das html-Element definieren wir wie sonst auch Schrift und Schriftfarbe: 12 Pixel Georgia und Schwarz. Die Hintergrundzuweisungen lassen sich rasch erklären: Das html-Element erhält eine generelle Hintergrundfarbe mitsamt einem die Seite am Ende abschließenden Bild, das horizontal wiederholt wird. Unser Design sieht eine ähnliche Darstellung oben vor, nämlich ein ebenfalls horizontal wiederholtes Bild mit zwei »Balken«. Hier Teil I: Seitenvorlagen
möchten wir aber ein anderes Vorgehen demonstrieren und dieses über Rahmen realisieren. So wird der erste Balken über einen 40 Pixel starken Rahmen auf dem body realisiert, während 5 Pixel darunter ein horizontal wiederholter Verlauf folgt. Die Fünf-Pixel-Aussparung benötigen wir für die h1-Überschrift: h1 { background: url(bilder/blickfang.gif) center no-repeat; border-top: 5px solid #FFF; }
Diese schließt nämlich die »Lücke« mit einem fünf Pixel dicken, weißen Rahmen nach oben und erfreut uns mit einem weiteren Hintergrundbild, das zentriert und nicht wiederholt wird. So haben wir nicht nur oben und unten jeweils zwei »Balken«, sondern auch gleich einen »Blickfang« eingebunden, der immer mittig über unserem via body eingebundenen Verlauf sitzt und bei jeder Fenstergröße passt. Damit der Blickfang auch vollständig sichtbar ist und zudem der Text richtig sitzt, müssen wir uns der h1-Überschrift noch etwas intensiver widmen: h1, h2 { font-weight: normal; } h1 { font-size: 4em; height: 150px; margin-bottom: 1.3em; padding: 174px 30% 0 0; text-align: right; }
Zunächst soll die h1-Überschrift mitsamt den ebenfalls vorgesehenen h2Überschriften nicht gefettet sein. Die Schriftgröße von 4em sorgt schließlich für genug Prominenz. Ein Außenabstand von 1.3em nach unten muss ebenfalls her, um etwas Luft zu schaffen. Dann aber: Die Höhe würden wir über height: 324px; festlegen können, wir benötigen aber auch einen Hebel für die richtige Textpositionierung. Hierfür richten wir den Text erst mal rechts aus (text-align: right;) und »drücken« ihn über den Innenabstand 174 Pixel nach unten. 30% Innenabstand nach rechts sorgen dafür, dass der Inhalt der Überschrift mittig sitzt, aber auch je nach Fenstergröße »mitwandert«. Das funktioniert ganz gut, kann aber bei eher kleinen oder sehr großen Fenstergrößen befremdlicher wirken. Darüber sind wir uns im Klaren. Um einen optischen Umbruch zwischen »Porto« und »Seguro« zu erzielen, haben wir mehrere Optionen: Die einfachste ist ein Zeilenumbruch via , der bei uns aufgrund seiner schlechten Beeinflussbarkeit verpönt ist. Die nächste Möglichkeit ist ein weiterer Innenabstand nach links, der Kapitel 1, Fließlayout »Porto Seguro«
Abbildung 1-9: hintergrund-2.gif, 1 x 323 Pixel
Abbildung 1-10: blickfang.gif, 1.024 x 324 Pixel
Hinweis
Die genannten Werte klingen ja alle ganz nett, aber wir müssen dafür ab und an schon mal eine Weile rumprobieren. Und das tun wir in diesem sehr flexiblen Layout auf jeden Fall.
so austariert ist, dass er dem Text zu wenig Platz gibt, um (bei möglichst vielen Fenstergrößen) in einer Zeile zu stehen. Wir könnten aber auch ein span-Element verwenden. Letzteres ist unser Weg, wie auch das HTML andeutete, und diese Entscheidung wird noch durch einen anderen Umstand bedingt: Augenscheinlich stoßen wir auf nur schwer überbrückbare Probleme im Internet Explorer 7, wenn wir zudem die Zeilenhöhe (via line-height) auf unter 1.0 reduzieren wollen – was unser Plan war. So können wir via display: block; und margin-top: -.75em; eine robuste Lösung für beide Herausforderungen erzielen: zwei Zeilen, geringe Zeilenhöhe. h1 span { display: block; margin-top: -.75em; }
Formatierung, 2. Akt
Hinweis
display: inline; verdanken wir
dem Internet Explorer 6 und seinem »Doubled Float-Margin Bug«. Dieser wird hier nur erwähnt, aber in den Referenzen nochmals aufgegriffen.
Nachdem nun die grobe Seitenformatierung mitsamt »Key Visual« (Blickfang) steht, können wir uns der Strukturierung des Inhaltsbereichs widmen. Dafür greifen wir gerne auf die float-Eigenschaft zurück und »floaten« alle div-Elemente innerhalb des zunächst rein strukturell benötigten inhalt-Containers. Dabei legen wir gleichzeitig einen rechten Abstand von 5% fest. div#inhalt div { display: inline; float: left; margin-right: 5%; }
Den einzelnen Abschnitten im Inhaltsbereich verpassen wir nun jeweils eine individuelle Breite, wobei das erste Element, anreisser-1, zudem einen
Teil I: Seitenvorlagen
linken Abstand von 5% erhält, so dass die Abstände zu den Seiten immer 5% betragen: div#anreisser-1 { margin-left: 5%; width: 18%; } div#anreisser-2 { width: 32%; } div#galerie { width: 29%; }
Anschließend stellen wir zwei Probleme fest, die noch gelöst werden müssen: Zum einen »hängt« das html-Hintergrundbild im Opera-Browser knapp unter der h1-Überschrift, was wir dem Fließen der Elemente zu verdanken haben und mittels overflow: hidden; lösen können. Zum anderen haben wir in allen Browsern außer dem Internet Explorer 6 zuwenig Abstand nach unten, was wir über padding-bottom und in einer Kindselektor-Regel verpackt adressieren und somit an die Darstellung im IE 6 angleichen können: * > div#inhalt { overflow: hidden; padding-bottom: 60px; }
Formatierung, 3. Akt Wir tasten uns weiter vor, nun mit dem Bedarf, ein paar allgemeine Zuweisungen zu treffen. Zwischenüberschriften, also h2-Überschriften, sollen eine definierte Größe und Zeilenhöhe haben, mitsamt etwas Abstand nach unten: h2 { font-size: 1.8em; line-height: 1.2; margin-bottom: .55em; }
Ebenso wird der Ruf nach einer Überschriften- sowie Linkfarbe laut: h2, a { color: #02ACCA; }
Absätze mögen Abstand: p { margin: 1em 0; }
Kapitel 1, Fließlayout »Porto Seguro«
Und auch die Links bedürfen noch unserer Aufmerksamkeit:
Dem können wir mit einem Hintergrundbild, das wir über einen kleinen Innenabstand vernünftig platzieren, und Textunterstreichung nur bei Fokus, Hover und aktivem Zustand gerecht werden.
Formatierung, 4. Akt Durch die einfache, da rein auf Inhalte bezogene Struktur der Container für »Geschichte« und »Brasilien erleben« profitieren diese von den zuvor vorgenommenen Definitionen. Der »Fotos«- oder »Galerie«-Bereich ist jedoch noch nicht abgeschlossen. Da wir keinen Eindruck von regulären Listen erwecken wollen, neutralisieren wir diesen: div#galerie ul { list-style: none; }
Unserem Ziel, eine kleine Nebeneinanderstellung diverser Foto-»Thumb nails« zu veröffentlichen, kommen wir näher, wenn wir die einzelnen li‑Elemente fließen lassen. Dies werten wir gleichzeitig auf, indem wir sie mit jeweils einem kleinen Hintergrundbild versehen, das links neben und über dem jeweiligen Foto sichtbar ist – wenn wir über padding einen entsprechenden Innenabstand vorsehen. Mit ein wenig Außenabstand lockern wir auch gleich noch die ganze Komposition etwas auf. div#galerie li { background: url(bilder/hintergrund-foto.gif) no-repeat; float: left; margin: 0 .4em .4em 0; padding: 9px 0 0 9px; }
Abbildung 1-12: hintergrund-foto.gif, 82 x 73 Pixel
Der im vorigen Akt definierte Hintergrund und Innenabstand für Links ist bei Verlinkung der Bilder unangenehmerweise auch in unserer Mini-Galerie sichtbar. Das haben wir jedoch schnell erledigt: div#galerie a { background: none; padding: 0; }
Teil I: Seitenvorlagen
Zum Schluß versehen wir die Bilder mit einem 1 Pixel breiten, schwarzen Rahmen und bedenken noch alle Browser, die unsere li-Außenabstände wegen der Berücksichtigung der Text-Unterlänge nicht auf die gleiche Art interpretieren: a img { border: 1px solid #000; display: block; }
Fast schöner als der Urlaub, unsere »Porto Seguro«-Microsite.
Referenzen • Porto Seguro http://www.portosegurotur.com.br • Position Is Everything: »The IE Doubled Float-Margin Bug« http://www.positioniseverything.net/explorer/doubled-margin.html • Eric Meyer: Bilder, Tabellen und mysteriöse Lücken http://devedge-temp.mozilla.org/viewsource/2002/img-table/
Kapitel 1, Fließlayout »Porto Seguro«
Fotogalerie
Vor uns haben wir ein wunderbares Layout, das eine Fotogalerie darstellt und das wir nicht nur als Screenshot ansehen wollen. Anhand der anstehenden Aufgaben, die uns über horizontale und vertikale Navigationslisten hin zu »fließenden« Inhalten führen, werden wir bei der Umsetzung eine Menge Spaß haben.
2 Schwierigkeitsgrad: schwer
Abbildung 2-1: Fotogalerie
11
Grundlagen Bevor wir überhaupt irgendetwas an HTML schreiben, setzen wir die beiden folgenden CSS-Regeln auf. Zum einen die in der Einleitung erwähnte »CSS-Zurücksetzung«: * { margin: 0; padding: 0; }
Zum anderen das Hintergrundbild der ganzen Webseite sowie die später am häufigsten verwendete Schrift (11 Pixel Verdana in Schwarz): Abbildung 2-2: hintergrund.gif, 16 x 16 Pixel Hinweis
Als effizienzbewusste Webent wickler setzen wir auch in diesem Buch oft auf die Kurzschreibweise von CSSEigenschaften: An Stelle von font-size , line-height und font-family benutzen wir die Kurzschrifteigenschaft font, so wie in diesem Kapitel mit font: 68.75%/1.2 verdana, arial, helvetica, sans-serif;.
Da wir hier eine ganze Webseite basteln, müssen wir gleich zu Beginn schon eine gewisse Struktur schaffen. Mit ein wenig exemplarischem Markup geht es also weiter, wobei wir uns hier nur mit Elementen innerhalb des body beschäftigen:
Dies sollte schon für sich sprechen, auch wenn wir festhalten wollen: Wir leiden nicht an »Div-itis« oder »Div-Ebola« (ein Begriff, den wir wohl Benjamin A. Howell zu verdanken haben). Einen Link »Navigation überspringen«, dem wir uns später noch näher widmen werden, haben wir bereits eingefügt. Und musterhaft ist bereits der Text »Fotogalerie« enthalten, den wir als Überschrift verwenden. Kümmern wir uns erst mal um die Zentrierung der Seite: div#haupt { margin: auto; width: 770px; }
Erstes Leben hauchen wir unserer Seite durch einen vernünftigen Seitenkopf ein. Wie im obigen Codeschnipsel gezeigt, handelt es sich um eine h1Überschrift, und wir setzen die Phark-Methode auf dem a-Element ein, um ein Bild anzuzeigen. In Kapitel 19, »Newsletter-Formular«, gehen wir näher auf »Image Replacement« à la Phark ein.
Prinzipiell hätten wir uns die erste der beiden Regeln sparen und die background-Deklaration ebenfalls unter h1 a einhängen können. Da wir jedoch beim Überfahren mit der Maus unschöne »Flackereffekte« im Internet Explorer beobachten würden, akzeptieren wir die zusätzliche Regel. Bevor wir uns etwas Interessantes für den bislang einzigen wirklichen Textlink auf unserer Seite einfallen lassen, definieren wir, dass alle Links weiß sein sollen. Das übernimmt ein a-Selektor mit der Deklaration color: #FFF;.
Unsichtbares Hilfsmittel »Navigation überspringen« ist unser nächstes Ziel. Wir verwenden diesen Link, um Menschen mit motorischen Einschränkungen (und auch einfache Tastaturnutzer) sowie Blinde zu unterstützen, und wenn wir das bedenken, ist klar, dass wir den Link nicht unbedingt anzeigen müssen. Wir gehen also so vor, dass der Link grundsätzlich über eine von WebAIM vorgestellte (und erwiesenermaßen zugängliche) Methode ausgeblendet, aber beim »Tabben« (beim Verwenden der Tabulator-Taste) angezeigt wird. Das Ausblenden erledigen die folgenden Deklarationen: a#aux { height: 1px; overflow: hidden; position: absolute; top: -999em; width: 1px; }
Kapitel 2, Fotogalerie
13
Diese Zuweisungen gewährleisten ein hohes Maß an Zugänglichkeit, da ein Ausblenden über display oder visibility in vielen Fällen Probleme beim Vorlesen durch Bildschirmlesesoftware verursacht. Der Link wird gewissermaßen »eingedampft« (auf 1 x 1 Pixel Größe, und über die overflow -Eigenschaft wird dies anschließend noch mal sichergestellt) und dann außerhalb des sichtbaren Bereichs positioniert. Mit den Pseudoklassen :focus und :active ermöglichen wir das Einblenden, wenn das Element den Fokus erhält bzw. gerade verwendet wird. Und dazu geben wir noch eine Prise Styling: a#aux:focus, a#aux:active { background: #000; border-bottom: 5px solid; display: block; height: auto; padding: 1em 0; text-align: center; top: 0; width: 770px; }
Mit diesen Zeilen erreichen wir, dass bei Bedarf am Seitenanfang unser nützlicher Link »Navigation überspringen« erscheint, und zwar als prominenter Block, weiß auf schwarz, mit einem abgrenzenden Rahmen, wie wir ihn auch bei dem Hintergrundbild der Überschrift verwenden. (Ja, dort haben wir auf den Einsatz der border-Eigenschaft verzichtet.)
Navigation, Teil 1 Widmen wir uns nun der Topnavigation. In unserem oben vorgestellten Markup-Gerüst haben wir bereits einen Container für sie vorgesehen, nav-1. Unschwer zu erraten, was wir in ihm ablegen:
Was haben wir vor? Wir brauchen vier nebeneinander stehende Reiter, die sich auf unserer Webseite eher rechts befinden. Der jeweils aktive Reiter soll hervorgehoben werden, analog auch jeder Reiter, wenn man mit der Maus über ihn fährt. Wir beginnen mit ein paar generellen Modifikationen. Der Außencontainer erhält einen schwarzen Hintergrund und eine feste Höhe, zudem bietet er uns die Grundlage für die Positionierung unserer Liste:
Dann kommt die Liste dran. Sie wird an die richtige Stelle manövriert, indem wir sie positionieren. Das Ganze geschieht vor allem vor dem Hintergrund, dass der eigentliche Seiteninhalt später ja halbwegs »unter« der Navigation erscheinen soll, die Navigation den Inhaltsbereich also ein Stück weit überdeckt. div#nav-1 ul { left: 292px; list-style: none; position: absolute; }
Kurzen Prozess machen wir auch mit den einzelnen Listenelementen, die wir »floaten«: div#nav-1 li { float: left; height: 26px; margin-right: 5px; width: 109px; }
Dann beginnt die Arbeit mit den einzusetzenden Bildern. Ähnlich wie beim h1-Element setzen wir den Hebel an den Kind-Ankern an und holen die Phark-Methode aus dem Werkzeugkoffer. div#nav-1 li a { display: block; height: 100%; text-decoration: none; text-indent: -999em; }
Die beiden letzteren Deklarationen werden wir später an eine andere Stelle im Stylesheet verschieben, um die Selektoren für h1-Anker und Topnavigationsanker zu gruppieren. Es folgt eine ganze Reihe von Regeln für die jeweiligen Reiter sowie mögliche Zustandswechsel (Fokus, Hover und aktiv). Das Ganze sieht kompliziert aus, ist aber trivial: div#nav-1 li#news a { background: url(bilder/news.gif); } div#nav-1 li#news a:focus, div#nav-1 li#news a:hover, div#nav-1 li#news a:active { background: url(bilder/news-an.gif); }
Abbildung 2-4: news.gif, 109 x 26 Pixel
Abbildung 2-5: news-an.gif, 109 x 26 Pixel
Kapitel 2, Fotogalerie
15
div#nav-1 li#philosophie a { background: url(bilder/philosophie.gif); }
Was ist aber nun mit den aktiven Punkten, wo wie bei »Portfolio« gar kein Link existiert? Die gerade angelegten Regeln, die die an-Bilder definieren, ergänzen wir alle jeweils um einen Selektor, der das entsprechende liElement wählt, also div#nav-1 li#news, div#nav-1 li#philosophie, div#nav-1 li#portfolio und div#nav-1 li#kontakt. Damit der jeweilige Text nicht angezeigt wird, kommt erneut Phark zum Einsatz. Wir haben mittlerweile (und wie zuvor angedeutet) die Fälle, in denen wir so vorgehen (und in denen wir auch Ankern die Unterstreichung versagen), zusammengefasst, und die betreffende Regel sieht nun so aus: h1 a, div#nav-1 li, div#nav-1 li a { text-decoration: none; text-indent: -999em; }
Aktive Reiter werden hier nur dadurch – dafür aber gewissermaßen »automatisch« – gekennzeichnet, dass sie nicht verlinkt sind. Das entbindet uns von zusätzlichen Klassen oder abweichenden IDs, die wir bräuchten, wenn wir verlinkte Reiter als aktiv kennzeichnen müssten. Um Missverständnisse zu vermeiden: Wir verlinken diese Reiter nicht, weil man auf Seiten, auf denen man sich befindet, diese Seite selbst nicht verlinkt – wir tun das nicht etwa, um dadurch Code einzusparen. Dieses Usability-Prinzip beherzigen wir überall in diesem Buch.
16
Teil I: Seitenvorlagen
Navigation, Teil 2 Wieder müssen wir uns erst einmal um etwas Markup kümmern. Noch eine Liste:
Dann geben wir der Navigation wieder einen Hintergrund und Dimensionen. Die Dimensionen benötigen wir, wenn der Hintergrund vollständig angezeigt werden soll. Die Verwendung der Eigenschaften min-height und minwidth aus CSS 2 wäre fein, diese Eigenschaften werden aber nicht von allen aktuellen Browsern unterstützt. Wir geben also alles »fest« in Pixeln an. Die linke Navigation sowie den Inhalt lassen wir »fließen«. Und damit unsere linke Spalte auch schön weiterläuft, bekommt unser haupt-Container ein Hintergrundbild, das sich nur vertikal wiederholt. div#nav-2 { background: url(bilder/nav-hintergrund.jpg); float: left; height: 462px; width: 150px; } div#haupt { background: #FFF url(bilder/nav-schatten.gif) repeat-y; }
Mit einem Rahmen nach unten sorgen wir dafür, dass alle Listenpunkte nach oben und unten abschließen. Mehr als einen Rahmen nach oben müssen wir den li-Elementen nun nicht mehr zuweisen. Den Listenstil setzen wir komplett zurück (das sollten wir mit der Topnavigation zusammenlegen und damit vereinfachen können). »Positioniert« wird die Liste, indem wir einen entsprechenden Außenabstand setzen.
Abbildung 2-12: nav-hintergrund.jpg, 150 x 462 Pixel
Was gilt nun gleichzeitig für »aktive« Listenelemente wie auch »inaktive« Punkte? Weiße Schrift und eine Ausrichtung nach rechts: div#nav-2 li, div#nav-2 li a { color: #FFF; text-align: right; }
Kapitel 2, Fotogalerie
17
Es folgen die Deklarationen, die wir speziell für die Formatierung unserer Listenpunkte benötigen: div#nav-2 li { border-top: 1px solid; font-size: 1.2em; height: 2em; width: 150px; }
Die in ihnen enthaltenen Anker sowie span-Elemente (unser aktiver Punkt, und nun kommt Licht ins Dunkel) erhalten entsprechend modifizierende Zuweisungen: div#nav-2 li a, div#nav-2 li span { display: block; font-weight: normal; height: 100%; padding-right: 18px; text-decoration: none; }
Diese dienen eigentlich nur dem Zweck, den ganzen Listenpunkt auszufüllen (display: block; und height: 100%;), die Schriftstärke zu reduzieren (fontweight: normal;), eine Linkunterstreichung zu vermeiden (text-decoration: none;) – sofern vorhanden – und nach rechts den von uns gewünschten Innenabstand zu erzielen. Aktive Punkte – durch span gekennzeichnet – sollen fett hervorgehoben werden, ebenso wie »gehoverte« Listenpunkte. div#nav-2 li a:hover, div#nav-2 li span { font-weight: bold; }
Aufgrund unserer guten Vorbereitung sind wir schon fast fertig. Als Letztes werfen wir unser durchsichtiges PNG in die Waagschale: div#nav-2 li a:hover, div#nav-2 li span { background: url(bilder/nav-highlight.png); }
Abbildung 2-14: nav-highlight.png, 1 x 1 Pixel (hier vergrößert dargestellt)
Auf diese Weise erzielen wir ein ansprechendes Highlighting sowohl des aktuellen Punkts wie auch der mit der Maus überfahrenen Punkte. Das Ganze funktioniert allerdings nicht im Internet Explorer 6. Das nervt uns wirklich, aber wir sind pragmatisch: In unserer Truhe liegen noch ein paar Kindselektoren herum, die der Internet Explorer 6 auch nicht versteht. Also schrauben wir Folgendes zusammen: div#nav-2 li > a:hover, div#nav-2 li > span { background: url(bilder/nav-highlight.png); }
Damit sind wir bezüglich der linken Navigation aus dem Schneider. Im Internet Explorer 6 werden aktive und »gehoverte« Punkte fett darge-
18
Teil I: Seitenvorlagen
stellt, und in seinem Nachfolger sowie in Browsern, die zum Beispiel auf der KHTML-Engine (Safari, Konqueror) oder auf der Gecko-Engine (Firefox, Mozilla, Netscape) basieren, wird zusätzlich noch unser PNG als Hintergrund angezeigt. Zu guter Letzt noch eine Quizfrage: Was benötigen wir, damit wir auch beim »Durchtabben« und bei der aktiven Linkwahl eine Hervorhebung erzielen? Die Pseudoklassen :focus und :active. Dies kann bei GeckoBrowsern unter Linux teilweise einen Darstellungsfehler beim »Hovern« der Navigation hervorrufen, aber wir schreiben sie erst mal dazu.
Inhalt Weiter zu dem, was unsere Musterseite überhaupt ausmacht: die Inhalte. Als Erstes müssen wir den Inhaltscontainer an seinen Zielort verfrachten. Da wir bereits die linke Navigation »floaten«, gehen wir hier analog vor: div#inhalt { float: left; padding: 10px 0 15px 55px; width: 565px; }
Justierende Deklarationen, die den in Kürze vorgestellten Kindelementen dienen, haben wir auch an Bord. Momentan sind die beiden gefloateten Container höher als der Haupt container, ragen also über diesen hinaus. Somit reichen sowohl die Hintergrundfarbe als auch das Hintergrundbild nicht mehr über die volle Höhe. Wir müssen einen genauen Blick in die Spezifikation werfen bzw. auf Anne van Kesteren hören, worauf wir in Kapitel 20, »KommentarFormular«, noch etwas näher eingehen werden: div#haupt { overflow: hidden; }
Abbildung 2-15: blume-1.jpg, 150 x 100 Pixel
Abbildung 2-16: blume-2.jpg, 150 x 100 Pixel
Dann liegt das Markup an, von dem wir nicht viel verlangen:
2005 PowerShot 1/120s 1600×1200px
2005 PowerShot 1/120s 1600×1200px
2005 PowerShot 1/120s 1600×1200px
2005 PowerShot 1/120s 1600×1200px
Kapitel 2, Fotogalerie
Abbildung 2-17: blume-3.jpg, 150 x 100 Pixel
Abbildung 2-18: blume-4.jpg, 150 x 100 Pixel
19
Interessanter ist, was wir aus dem bisschen Markup machen. Wir wollen je zwei Bilder pro Zeile darstellen, und rechts sollen jeweils noch ein paar Daten zum Bild erscheinen. Auch hier ist es naheliegend, die Container fließen zu lassen. Durch den Zugriff auf die bild-Klasse können wir Ausnahmen bezüglich der Breite der Container definieren, schließlich benötigen wir bei den Bildern etwas mehr Platz. div#inhalt div { float: left; margin: 15px 20px 15px 0; width: 8.5em; } div#inhalt div.bild { margin-right: 5px; width: 150px; }
Nebenbei bemerkt ist es interessant, dass wir den Text ganz ohne Markup wie br-Elemente oder Ähnliches formatieren können. (Das wird zwar bei einer größeren Textskalierung nicht mehr funktionieren, aber das ist hier nicht von Bedeutung.) Wenn wir uns dem beschreibenden Text widmen, fühlen wir uns auch nicht mehr gefordert, ganz im Gegenteil – unsere Regel div#inhalt div erweitern wir um font-size: .9em;. Beim Schatten und der Umrahmung der Galeriebilder wird es wieder interessanter. Wir weisen den Bildcontainern ein Hintergrundbild zu: div#inhalt div.bild { background: url(bilder/schatten.gif) bottom right no-repeat; }
Abbildung 2-19: schatten.gif, 158 x 108 Pixel
Anschließend brauchen wir eine neue Breite für diesen Container, denn sein Inhalt, also jedes Bild, wird nun mit einem Rahmen sowie einem Innenabstand versehen, den wir durch eine Hintergrundfarbe weiß gestalten. div#inhalt div.bild { width: 158px; } div#inhalt div.bild img { background: #FFF; border: 1px solid #979797; padding: 3px; }
Der neuen Höhe, die wir durch Innenabstand und Rahmen erhalten, sowie einem sonst auftretenden Problem mit Opera tragen wir zwischen den Zeilen Rechnung, indem wir unseren fließenden div-Elementen height: 10.8em; zuweisen.
20
Teil I: Seitenvorlagen
Unsere Bilderzuweisungen ergänzen wir nun um die folgenden drei Deklarationen: div#inhalt div.bild img { left: -5px; position: relative; top: -5px; }
Diese Deklarationen kombinieren wir natürlich mit den anderen, bereits definierten Bild-Deklarationen. Das Bild wird nun um jeweils fünf Pixel nach links und nach oben verschoben, wodurch unser Schatten freigelegt wird.
Finale Zu guter Letzt kommt noch die Fußzeile an die Reihe. Wir haben anfangs bereits einen Container dafür vorgesehen, eigentlich muss dort nur noch etwas Text hinein:
Außerdem haben wir zu Anfang einen Link »Navigation überspringen« kreiert und mit einer entsprechenden Formatierung versehen. Das dort verwendete Layout wollen wir auch in der Fußzeile gebrauchen. Da keine der für a#aux:focus und a#aux:active definierten Deklarationen mit unserem Vorhaben kollidiert, können wir der Regel einfach den Selektor div#fusszeile hinzufügen. Zwei Dinge sind noch zu tun: den Fluss der beiden vorangegangenen Elemente (linke Navigation und Inhaltsbereich) festlegen und dafür sorgen, dass die ganze Schrift in Weiß dargestellt wird. div#fusszeile { clear: left; color: #FFF; }
Referenzen • WebAIM: Unsichtbare Inhalte für Screenreader-Nutzer http://www.webaim.org/techniques/css/invisiblecontent/ • CSS-Spezifikation: min-width und max-width http://www.w3.org/TR/CSS21/visudet.html#min-max-widths • CSS-Spezifikation: min-height und max-height http://www.w3.org/TR/CSS21/visudet.html#min-max-heights • CSS-Spezifikation: Kindselektoren http://www.w3.org/TR/CSS21/selector.html#child-selectors Kapitel 2, Fotogalerie
21
Web-Bücherei
In diesem Kapitel stellen wir uns einer neuen Herausforderung, diesmal in Form einer imaginären Bücherei. Dabei sehen wir uns unter anderem mit besonderen Rollover-Effekten und einer Pullquote konfrontiert.
3 Schwierigkeitsgrad: mittel
Abbildung 3-1: Web-Bücherei
23
Bevor wir uns auf sie stürzen, werfen wir einen genauen Blick auf das von uns kreierte Design, um daraus Entscheidungen über die Basisstruktur unseres Dokuments zu treffen:
/> id="nav-1" /> id="nav-2" /> /> />
Bislang sieht das nach einer einfachen Struktur aus. Die ersten Zuweisungen gehen uns leicht von der Hand: html { background: #FFF url(bilder/hintergrund.jpg) repeat-x; color: #493214; font: normal 100%/1.3 'trebuchet ms', arial, helvetica, sans-serif; }
Die h1-Überschrift kommt als Nächstes an die Reihe. Um die Tagline »Spannende Texte online« anders darzustellen, verwenden wir ein spanElement, das wir über den Kontext formatieren.
Jetzt muss ein kleiner Vorgriff in Form eines Seitenhiebs auf den Internet Explorer erfolgen: Es wäre wesentlich einfacher, Klassen anstelle von IDs zu verwenden und somit die Klasse texte noch um die Klasse an zu ergänzen, um für unsere Zwecke angepasste Deklarationen setzen zu können. Der Teil I: Seitenvorlagen
Internet Explorer steigt jedoch zumindest bis Version 6 bei dieser Art der Umsetzung aus, indem er sich beim Standardbild »verschluckt« und das für »Kontakt« definierte Bild anzeigt. Da Bilder zum Einsatz kommen, wenden wir unseren Liebling unter den Bildersatztechniken an, nämlich die Phark-Methode. Zuerst nehmen wir aber die Basisformatierung vor, in der wir die »Listenbullets« deaktivieren (list-style: none;), eine konstante Höhe von 32 Pixeln vorgeben (height: 32px;, wegen dem Internet Explorer sowohl für ul-Elemente als auch für li-Elemente) und die einzelnen Listenpunkte »floaten« (float: left;). Außerdem setzen wir die Breite der einzelnen Punkte. ul#nav-1, ul#nav-1 li { height: 32px; } ul#nav-1 { list-style: none; } ul#nav-1 li { float: left; } ul#nav-1 #startseite, ul#nav-1 #startseite-an { width: 177px; } ul#nav-1 #texte, ul#nav-1 #texte-an { width: 101px; } ul#nav-1 #autoren, ul#nav-1 #autoren-an { width: 156px; } ul#nav-1 #teilnehmen, ul#nav-1 #teilnehmen-an { width: 167px; } ul#nav-1 #kontakt, ul#nav-1 #kontakt-an { width: 149px; }
Diese Vorgehensweise wird in diesem Buch öfter verwendet. Erst nachdem wir die Navigation mit allen Bildern versehen haben, werden wir die Liste richtig ausrichten. Es geht also mit einer ganzen Reihe von Bildern sowie einem Griff in die Trickkiste weiter. Wir machen unsere Links zu Block-Elementen, lassen sie die ganze Höhe einnehmen und verzichten auf eine Unterstreichung. Unsere PharkGeheimwaffe ist ein »Outdent« von 999 Pixeln, was den Text verschwinden lässt. Zusammen mit der bereits definierten Farbänderung ergibt das die folgende Regel: Kapitel 3, Web-Bücherei
25
Abbildung 3-3: nav-1-startseite.gif, 177 x 32 Pixel
Abbildung 3-4: nav-1-startseite-an.gif, 177 x 32 Pixel
Abbildung 3-5: nav-1-texte.gif, 101 x 32 Pixel
Abbildung 3-6: nav-1-texte-an.gif, 101 x 32 Pixel
Abbildung 3-7: nav-1-autoren.gif, 156 x 32 Pixel
Abbildung 3-8: nav-1-autoren-an.gif, 156 x 32 Pixel
Abbildung 3-9: nav-1-teilnehmen.gif, 167 x 32 Pixel
Abbildung 3-10: nav-1-teilnehmen-an.gif, 167 x 32 Pixel
Abbildung 3-11: nav-1-kontakt.gif, 149 x 32 Pixel
Abbildung 3-12: nav-1-kontakt-an.gif, 149 x 32 Pixel
Die einzelnen Listenpunkte versehen wir nun mit den entsprechenden Hintergrundbildern (vereinfacht dargestellt, da wir die zuvor jeweils individuell ergänzten an-Selektoren sowie die Breitenangaben weglassen): ul#nav-1 #startseite { background: url(bilder/nav-1-startseite.gif); } ul#nav-1 #texte { background: url(bilder/nav-1-texte.gif); } ul#nav-1 #autoren { background: url(bilder/nav-1-autoren.gif); } ul#nav-1 #teilnehmen { background: url(bilder/nav-1-teilnehmen.gif); } ul#nav-1 #kontakt { background: url(bilder/nav-1-kontakt.gif); }
Anschließend geht es in die »Selektorenhölle«, wenn wir für die Pseudoklassen :focus, :hover und :active sowie die aktivierten Elemente (an) die zu verwendenden Bilder definieren. Das verdanken wir zum einen dem oben beschriebenen Problem beim Internet Explorer, zum anderen aber unserer »Nummer sicher«-Taktik, in die Selektoren den vollen Kontext reinzunehmen. (In der ersten Regel würde es zum Beispiel reichen, die Selektoren via #startseite :focus zu »komprimieren«.) ul#nav-1 #startseite a:focus, ul#nav-1 #startseite a:hover, ul#nav-1 #startseite a:active, ul#nav-1 #startseite-an { background: url(bilder/nav-1-startseite-an.gif); } ul#nav-1 #texte a:focus, ul#nav-1 #texte a:hover, ul#nav-1 #texte a:active, ul#nav-1 #texte-an { background: url(bilder/nav-1-texte-an.gif); } ul#nav-1 #autoren a:focus, ul#nav-1 #autoren a:hover, ul#nav-1 #autoren a:active, ul#nav-1 #autoren-an { background: url(bilder/nav-1-autoren-an.gif); } ul#nav-1 #teilnehmen a:focus, ul#nav-1 #teilnehmen a:hover, ul#nav-1 #teilnehmen a:active, ul#nav-1 #teilnehmen-an { background: url(bilder/nav-1-teilnehmen-an.gif); }
Das sieht nicht schön aus und wirkt vor allem viel komplizierter, als es eigentlich ist. Rücken wir das Ganze zurecht: ul#nav-1 { margin: 41px 0 0 10px; }
Durch das anfangs gesetzte Hintergrundbild haben wir also geschickt den Effekt erzielt, dass unsere Liste unten optisch mit einer Linie abschließt. Die Alternativen, wie zum Beispiel über einen unteren Rahmen des ul-Elements und eine mögliche Positionierung der Listenelemente über diesem Rahmen denselben Effekt zu erzielen, sind wesentlich komplizierter. Ein Manko haben wir uns aber damit eingebrockt: Bei einer Textskalierung fliegt das Ganze auf.
Navigation, Teil 2 Die zweite Navigation ist eine andere Geschichte. Eine wirklich ganz andere Geschichte, denn wir müssen den Internet Explorer 6 aufgrund mangelnder Unterstützung der :hover-Pseudoklasse, was Elemente außer a anbelangt, sowie aufgrund der ungenügenden PNG-Implementierung leider ausschließen. Wir setzen an anderer Stelle aber voraus, dass die im Menü enthaltenen Punkte auf einer Art Übersichtsseite dennoch zur Verfügung stehen und somit zugänglich sind.
Wir definieren also als Erstes, das Menü für besagten Browser zu entfernen, es aber Browsern anzuzeigen, die den Kombinator > (und gleichzeitig auch :hover bei allen Elementen) verstehen. Bisher wird beides erst ab dem Internet Explorer 7 unterstützt, fortgeschrittene Browser wie Mozilla, Firefox, Opera und Safari sind dazu bereits seit Längerem in der Lage. ul#nav-2 { display: none; } body > ul#nav-2 { display: block; }
Kapitel 3, Web-Bücherei
27
Ab jetzt wird also unter Ausschluss dieses Microsoft-Kindes weitergemacht. Um das Menü an die richtige Stelle zu manövrieren, positionieren wir es. Standardmäßig soll nur ein »Auswahl«-Bild angezeigt werden, das beim »Hovern« dann die eigentlichen Navigationspunkte darstellt. ul#nav-2 { background: url(bilder/nav-2-min.png) no-repeat; left: 0; list-style: none; position: absolute; top: 240px; }
Abbildung 3-13: nav-2-min.png, 29 x 127 Pixel
Außerdem sollen die einzelnen Listenpunkte erst mal »unsichtbar« sein: ul#nav-2 li { visibility: hidden; }
display: none; funktioniert nicht, da das initiale Hintergrundbild ausge-
blendet würde. Es wäre also gar nichts mehr zu sehen. Nun wollen wir beim Überfahren mit der Maus das Menü zu sehen bekommen. Zuerst tauschen wir das Hintergrundbild aus, versehen die Liste mit den benötigten Dimensionen (mit bereits einkalkuliertem Innenabstand) und ziehen die zuvor ausgeblendeten Listenpunkte wieder aus der Tasche: ul#nav-2 { height: 205px; padding-top: 5px; width: 223px; } ul#nav-2:hover { background: url(bilder/nav-2-max.png); }
Abbildung 3-14: nav-2-max.png, 223 x 210 Pixel
ul#nav-2:hover li { visibility: visible; }
Die Dimensionen der Liste setzen wir übrigens deshalb nicht erst in »gehovertem« Zustand, sondern generell, damit wir eine größere »Angriffsfläche« zum Aufklappen bieten. Die Links der Listenpunkte sowie das zur Hervorhebung des ausgewählten Punkts verwendete span-Element erhalten als Nächstes ihre Zuweisungen, die sie mit weißer Farbe, einer angemessenen Zeilenhöhe und mit einem Innenabstand nach links ausstatten. Außerdem werden sie zu nicht unterstrichenen Block-Elementen gemacht. ul#nav-2 li a, ul#nav-2 li span { color: #FFF; display: block; line-height: 1.7;
28
Teil I: Seitenvorlagen
padding-left: 54px; text-decoration: none; }
Um den jeweils aktiven Punkt hervorzuheben, stellen wir einen Pfeil voran: ul#nav-2 li span { background: url(bilder/nav-2-pfeil.gif) 44px 9px no-repeat; }
Links kennzeichnen wir in bestimmten Zuständen mit einer anderen Farbe:
Abbildung 3-15: nav-2-pfeil.gif, 5 x 9 Pixel (hier vergrößert dargestellt)
ul#nav-2 li a:hover, ul#nav-2 li a:active { color: #28B0BF; }
Wir haben uns ein paar Probleme eingebrockt – schließlich ist das alles nicht im populären Internet Explorer sichtbar, und auch was den Zugang über die Tastatur anbelangt, gibt es Defizite –, aber wir konnten diese Herausforderung dennoch meistern.
Zwischenspiel Nachdem wir nun das Gröbste hinter uns haben, widmen wir uns noch den beiden Zwischenüberschriften h2 und h3 in der Dokumentstruktur:
Schlaflos in Schleswig
Ein Kurzroman von Claudia Zink
Die erste Überschrift soll groß und weiß sein, die zweite in einer anderen Farbe und in nicht ganz so prominenter Größe, in Versalien und in Georgia – einer wunderbar lesbaren Schrift, nebenbei bemerkt. Beide Elemente sollen über einen Außenabstand zurechtgerückt werden. h2, h3 { font-weight: normal; } h2 { clear: left; color: #FFF; font-size: 3em; margin: 25px 35px 0; } h3 { color: #28B0BF; font: 1.3em georgia, serif; letter-spacing: .1em; margin: -3px 0 0 110px; text-transform: uppercase; }
Kapitel 3, Web-Bücherei
29
Die Inhalte Wenn wir schon eine »Web-Bücherei« hochziehen, wollen wir auch etwas Feines präsentieren. Das ist selbstredend das Credo bei allem, was wir machen. In unserem Fall befinden wir uns auf einer Seite, die umfangreiche Inhalte in Form von Kurzromanen vorstellt, und exemplarisch machen wir jetzt den von »Claudia Zink« fit. Was springt ins Auge? Der Text soll Abstand zu den Seiten haben und mit einer größeren Zeilenhöhe dezent umformatiert werden: p { line-height: 1.7; margin: 0 110px; }
Eine Sonderrolle kommt dem ersten Absatz zu, dem »Anreißer«. Er soll fett hervorgehoben sein und über eine geringere Zeilenhöhe, aber einen größeren Außenabstand zumindest nach oben und unten verfügen: p#anreisser { font-weight: bold; line-height: 1.3; margin: 1em 0 1em 110px; }
Zum Schluss kümmern wir uns noch um die hervorzuhebende »Pullquote«:
Ich hatte vermutlich mein ganzes Leben verschlafen […]
Dafür werden keine dramatischen Deklarationen benötigt: Abbildung 3-16: zitat.gif, 30 x 21 Pixel (hier vergrößert dargestellt)
Wie wird das alles zusammengehalten? Wir haben dem body-Element zwischenzeitlich noch etwas vorgegeben: body { padding-bottom: 1em; width: 760px; }
Die erste Deklaration sorgt für Abstand nach unten, während die zweite Deklaration uns gewissermaßen eine Grenze nach rechts setzt, gegen die wir unter anderem bei der »Pullquote« fließen. Eine weitere Pullquote befindet sich übrigens in Kapitel 29, »Pullquote«. 30
Teil I: Seitenvorlagen
Spaltenlayout »Alias« In dieser Designübung möchten wir ein zweispaltiges Layout entwerfen, bei dem beide Spalten gleich lang sind. Das ist etwas, das wir natürlich ohne Tabellen erzielen wollen und was uns durch die bis dato mangelnde Unterstützung auch nicht einfach durch den table-cell-Wert der displayEigenschaft ermöglicht wird.
Erste Schritte Machen wir uns erst mal an die Überschrift, deren Größe, unteren Rahmen und Hintergrundbild wir gleich spezifizieren. Für den Text selbst müssen wir uns ein paar Dinge überlegen: Die Schrift soll vier »em«-Einheiten groß sein und der Text soll in Großbuchstaben erscheinen, was wir über fontfamily und text-transform sofort definieren. Die Positionierung des Textes können wir hingegen nicht so einfach über vertical-align vornehmen, da diese Eigenschaft nicht auf Block-Elemente anwendbar ist – also justieren wir den Text über einen Innenabstand nach oben sowie eine Einrückung via text-indent. Da der Internet Explorer den unteren Rahmen aufgrund der global vorliegenden Zeilenhöhe (skaliert auf 1.2) nach unten verschiebt, müssen wir hier etwas nachhelfen und setzen eine Zeilenhöhe von neun Zehntel der Schriftgröße (0.9). Bei all diesen Anpassungen definieren wir auch gleich den Stil der h2Überschriften, für die wie beim h1-Element die Schrift Georgia verwendet werden soll: h1, h2 { font-family: georgia, serif; font-weight: normal; } h1 { background: #193E58 url(bilder/kopf.jpg) no-repeat; border-bottom: 3px solid; font-size: 4em; line-height: .9; padding: 90px 0 0; text-indent: 10px; text-transform: uppercase; width: 750px; }
Der obere Teil der Seite steht also. Verbringen wir nun etwas Zeit mit generellen Definitionen, also Regeln für zum Beispiel Links und Absätze, die ziemlich selbsterklärend sein sollten. div#haupt div { padding: 10px; } p { margin: .7em 0; } a { color: #FFF; }
Dass man besuchte Links idealerweise auch als solche farblich kennzeichnet, wissen wir, lassen dies aber zur Vereinfachung beiseite. Als Nächstes werten wir unseren Informationsblock auf, der das Datum und die Kategorien des Beitrags beschreibt. Dazu nehmen wir uns ein Hintergrundbild mit einem Pfeil und definieren eigentlich nichts anderes als einen Außenabstand, der etwas Distanz zum Text erzeugt, sowie einen Innenabstand, der den Text justiert: div#info { background: url(bilder/pfeil.gif) no-repeat; margin: 1.3em 0; padding: .35em 2.5em !important; }
Die padding-Deklaration wird mit einem !important versehen, da der Selektor div#haupt div eine größere Spezifität besitzt und sonst den Innenabstand »überschreiben« würde. (Detaillierte Informationen dazu finden Sie im Kasten »Spezifität«.)
Kapitel 4, Spaltenlayout »Alias«
Abbildung 4-3: pfeil.gif, 23 x 22 Pixel (hier vergrößert dargestellt)
33
Ein Blick in die Spezifik ation
Spezifität Die Spezifität ist ein wichtiger Bestandteil der Kaskade, und um sie zu erklären, soll zuerst noch einmal die Funktionsweise der Kaskade beschrieben werden. Die Kaskade definiert, wie ein User-Agent den Wert für eine bestimmte Kombination von Element und Eigenschaft finden soll. Er soll dabei laut Spezifikation wie folgt vorgehen: 1. Finde entsprechend dem vorgegebenen Medientyp (zum Beispiel screen) alle Deklarationen, die auf das in Frage kommende Element angewendet werden können. Deklarationen werden angewendet, wenn der Selektor auf das jeweilige Element zutrifft. 2. Sortiere nach Wichtigkeit (normal oder wichtig, wobei wichtige Deklarationen durch !important gekennzeichnet werden) und Ursprung, und zwar in der folgenden, aufsteigenden Reihenfolge: 1. User-Agent-Stylesheets 2. Normale Benutzer-Stylesheets 3. Normale Autoren-Stylesheets 4. Wichtige Autoren-Stylesheets 5. Wichtige Benutzer-Stylesheets
Stylesheets werden bezüglich ihres Ortes als vor den Regeln stehend angesehen, die im eigentlichen, importierenden Stylesheet definiert sind. Die Spezifität eines Selektors wird in der Form a,b,c,d angegeben. Die einzelnen Stellen werden über vier Regeln berechnet (in einfacher Form): • Zähle 1, wenn der Selektor einem style-Attribut und keinem Selektor selbst entspricht, ansonsten 0 (für a). • Zähle die Anzahl von ID-Attributen im Selektor (für b). • Zähle die Anzahl von anderen Attributen und Pseudoklassen im Selektor (für c). • Zähle die Anzahl von Elementnamen und Pseudoelementen im Selektor (für d). Einige Beispiele: Selektor
Spezifität
* {}
0,0,0,0
p {}
0,0,0,1
p:first-letter {}
0,0,0,2
3. Sortiere nach der Spezifität des Selektors: Spezi fischere Selektoren überschreiben allgemeinere. Pseudoelemente zählen als normale Elemente, Pseudoklassen als Klassen.
ul li {}
0,0,0,2
div.warnung {}
0,0,1,1
div.login.fehler {}
0,0,2,1
4. Sortiere nach dem Ort des Vorkommens: Wenn zwei Regeln dasselbe Gewicht, denselben Ursprung und dieselbe Spezifität haben, erhält die als Letztes definierte den Vorrang. Regeln in importierten
#nav {}
0,1,0,0
style=""
1,0,0,0
Zwei Abschnitte, zwei Spalten Nun kommen wir zum eigentlich interessanten Teil, nämlich der Seitenauf teilung. Wir haben einen Hauptabschnitt, in diesem Fall den Blogbeitrag, sowie einen Nebenbereich für die Kommentare, die wir beide nebeneinander stellen wollen. Um wirklich zwei Spalten zu erhalten, lassen wir beide Container »fließen«, versehen sie also mit einem Float nach links sowie einer Breite, denn diese muss bei Flüssen mit angegeben werden. Das Einzige, was wir zudem beachten müssen, ist unser bisheriger Innenabstand für beide Elemente (zehn Pixel auf jeder Seite bei beiden Containern) sowie die Größe des
34
Teil I: Seitenvorlagen
Hintergrundbildes, die uns die Breite für den Kommentarbereich vorgibt (das berücksichtigen wir natürlich bereits im Vorfeld). Im Anschluss definieren wir noch einen unteren Rahmen für den Haupt container; über die border-bottom -Eigenschaft ist das schnell erledigt. Die optische Gestaltung der zweiten Spalte basiert auf einem simplen Trick: Die rechte Spalte, unsere Kommentarfläche, ist gar nicht so hoch wie die linke – ein Element bezieht seine Höhe normalerweise durch die Höhe seiner Inhalte. Sie wirkt in diesem Fall aber so hoch, weil wir den Hauptcontainer mit einem Hintergrundbild versehen, das sich an der Y‑Achse orientiert und so hoch wie das body-Element ist – und nicht wie der Kommentarbereich. Damit unser Hauptcontainer dann auch wirklich so hoch wie die beiden »gefloateten« Kinder ist, holen wir uns noch die Deklaration overflow: hidden; zu Hilfe. (Dies wird noch einmal in Kapitel 17, »Kommentar-Formular«, aufgegriffen.) div#haupt { background: url(bilder/hintergrund.gif) top right repeat-y; border-bottom: 3px solid; overflow: hidden; }
Auch hier sind es nur ein paar wenige Regeln und ein kleiner Kniff, die uns schnell an unser Ziel kommen lassen. Populär gemacht hat dieses Vorgehen übrigens vor wenigen Jahren Dan Cederholm in seinem »A List Apart«Artikel »Faux Columns«.
Referenzen • CSS-Spezifikation: Die Kaskadenreihenfolge http://www.w3.org/TR/CSS21/cascade.html#cascading-order • CSS-Spezifikation: Die Spezifität eines Selektors berechnen http://www.w3.org/TR/CSS21/cascade.html#specificity • Jens Meiert: Eleganter Code durch kontextuelle Selektoren http://meiert.com/de/publications/articles/20050107/ • Dan Cederholm: Faux Columns http://www.alistapart.com/articles/fauxcolumns/
Kapitel 4, Spaltenlayout »Alias«
37
Fließlayout »World of Fish« »World of Fish« stellt ein kleines Informationsangebot zu einem begehbaren Aquarium dar, und dieses Angebot soll von uns mal flugs umgesetzt werden. Im Vorfeld haben wir wie immer ein Konzept erstellt, die Inhalte gesichtet und zurechtgelegt, alles mit den Beteiligten abgestimmt und uns dann alle benötigten Bilder zurechtgeschnitten.
5 Schwierigkeitsgrad: mittel
Abbildung 5-1: Fließlayout »World of Fish«
39
Fangen wir mit dem Hintergrund und der Seitenüberschrift an: html { background: #4F7EC9; color: #FFF; font: 68.75%/1.2 verdana, arial, helvetica, sans-serif; } h1 { background: url(bilder/world-of-fish.gif) top center no-repeat; height: 168px; text-indent: -999em; }
Abbildung 5-2: world-of-fish.gif, 1000 x 168 Pixel
Was machen wir hier mit unserer Überschrift, und wie sieht deren Markup überhaupt aus?
World of Fish
Auch wenn wir eine deutschsprachige Seite umsetzen, verwenden wir hier englischen Text, und der muss entsprechend gekennzeichnet werden. Wie in der Einleitung bereits angesprochen, verwenden wir XHTML 1.0. Damit ist uns die Verwendung des lang-Attributs erlaubt, aber wir gebrauchen es im xml-Namensraum, um theoretisch auch einen raschen, problemlosen Wechsel auf XHTML 1.1 zu ermöglichen. Die Formatierung der Überschrift muss dem Umstand Rechnung tragen, dass wir ein sehr großes Hintergrundbild verwenden, aber auch bei kleineren Auflösungen gut dastehen wollen. Das erledigen wir, indem wir dem h1-Element keine feste (also die volle) Breite vorgeben und ihm ein zentriertes Hintergrundbild zuweisen. So wird bei kleineren Auflösungen alles Relevante zu sehen sein, ohne dass Scrollbalken entstehen.
Navigation Etwas anders wird es nun bei der Navigation und den Inhalten ablaufen.
Die Navigation erhält eine Breite von 761 Pixeln, so dass wir hier erst mal Hand anlegen und den nav-Container mit margin: auto; zentrieren müssen: div#nav { margin: auto; width: 761px; }
Anschließend widmen wir uns der Liste: div#nav ul { list-style: none; width: 470px; } div#nav li { float: left; width: 94px; }
Bevor wir die Liste in Position bringen, kümmern wir uns um die darin enthaltenen Links. Wir weisen ihnen Maße zu, nehmen die Unterstreichung weg, schaffen ihren Text aus dem Weg (wir werden auch hier die von uns favorisierte Phark-Methode einsetzen) und machen ein Block-Element aus ihnen. div#nav li a { background-repeat: no-repeat; display: block; height: 88px; text-decoration: none; text-indent: -999em; }
Hinweis
Das Geheimnis der Deklaration background-repeat: no-repeat;
wird in Kürze gelüftet.
Die Liste schieben wir an die richtige Stelle, indem wir dem Elternelement (div#nav) die Deklaration position: relative; zuweisen und dann absolut dazu die Liste positionieren. div#nav { position: relative; } div#nav ul { left: 146px; position: absolute; top: -84px; }
Im nächsten Schritt folgen die Zuweisungen für die einzelnen Navigations bilder. Um die Bilder bündig zum vom Überschriftenhintergrund beschriebenen Bogen zu machen und die unterschiedliche Höhe der Bilder auszugleichen, justieren wir mit der margin-top-Eigenschaft nach.
Kapitel 5, Fließlayout »World of Fish«
41
div#nav li#tour a { background-image: url(bilder/nav-tour.gif); margin-top: 2px; }
Abbildung 5-3: nav-tour.gif, 94 x 83 Pixel
div#nav li#angebot a { background-image: url(bilder/nav-angebot.gif); margin-top: 7px; } div#nav li#ueber a { background-image: url(bilder/nav-ueber.gif); margin-top: 16px; }
Abbildung 5-4: nav-angebot.gif, 94 x 88 Pixel
div#nav li#wissen a { background-image: url(bilder/nav-wissen.gif); margin-top: 10px; } div#nav li#kontakt a { background-image: url(bilder/nav-kontakt.gif); }
Und damit ist auch klar, warum wir zuvor ein no-repeat für den Link-Hin tergrund gesetzt haben. Abbildung 5-5: nav-ueber.gif, 94 x 86 Pixel
Haken und Ösen
Abbildung 5-6: nav-wissen.gif, 94 x 85 Pixel
Haken und Ösen gibt es auch in diesem Design, diesmal im wahrsten Sinne des Wortes. Den am Haken zappelnden »Jetzt NEU in München«Schriftzug wollen wir an den von der Überschrift gebildeten Bogen heften. Und da wir die gleich im Anschluss folgende »Tagline« über die ganze Breite verwenden, aber einen festen Punkt zur Positionierung benötigen, ergänzen wir den nav-Container:
…
Jetzt NEU in München
Abbildung 5-7: nav-kontakt.gif, 94 x 85 Pixel
Wir setzen erneut die bewährte Phark-Bildersatztechnik ein, um den verwendeten Text durch unser Bild zu ersetzen. div#nav div { background: url(bilder/neu.gif); height: 141px; left: 655px; position: absolute; text-indent: -999em; width: 105px; top: -30px; }
Abbildung 5-8: neu.gif, 105 x 141 Pixel
42
Teil I: Seitenvorlagen
Bevor das untergeht, vereinfachen wir jetzt ein wenig den Code, da wir doch die text-indent-Eigenschaft schon zum wiederholten Male gebrauchen (bislang an drei Stellen): h1, div#nav * { text-indent: -999em; }
Das ist doch gleich platzsparender. Wir machen uns dabei den Umstand zunutze, dass jeglicher in Block-Elementen – nur hierauf können wir textindent anwenden – stehender Text im Navigationscontainer ausgeblendet bzw. ersetzt werden soll. Ein Fall für den universellen Selektor *, den wir im Navigationskontext (div#nav) einsetzen. Zur Integration der Tagline erstellen wir einen entsprechend simplen Hilfscontainer – da sie semantisch keinen wirklichen Absatz darstellt, verwenden wir ein div-Element:
Das begehbare Aquarium in München
Der bereits justierte »NEU«-Haken dient nun als gute Orientierung, um den tagline-Container über die margin-top-Eigenschaft ebenfalls zurechtzurücken. Für das gleichzeitig zu setzende Hintergrundbild definieren wir zudem die entsprechende Höhe: div#tagline { background: url(bilder/tagline-hintergrund.gif) repeat-x; height: 2.7em; margin-top: 47px; }
Nun ist es einfach, die Schrift ebenfalls an unsere Bedürfnisse anzupassen. Wir zentrieren sie horizontal, und um sie vertikal auszurichten, ziehen wir die line-height-Eigenschaft heran. Das ist in erster Linie einfacher, als einen Innenabstand zu spezifizieren. div#tagline { font-size: 1.2em; font-weight: bold; line-height: 1.8; text-align: center; }
Spannender wird es wieder bei dem Wellenbild, das ebenfalls noch in die Tagline soll. Wir könnten einfach ein img-Element heranziehen, aber da dem Bild keine Bedeutung zukommt, scheidet diese Variante aus. Eine andere Möglichkeit wäre es, ebenfalls von der Navigation aus einen Container »herabzuseilen«, der ein Hintergrundbild mitbringt, wobei gleichzeitig ein rechter Innenabstand im tagline-Container gesetzt wird. Oder wir spielen ein wenig mit einem span-Element und hängen hinter den Tagline-Text einfach <span>.
Kapitel 5, Fließlayout »World of Fish«
Abbildung 5-9: tagline-hintergrund.gif, 1 x 36 Pixel (hier vergrößert dargestellt)
43
Abbildung 5-10: tagline-aqua.gif, 51 x 17 Pixel
div#tagline span { background: url(bilder/tagline-aqua.gif) top right no-repeat; display: block; height: 17px; width: 51px; }
Auf diese Weise erhalten wir zunächst ein 51 x 17 Pixel großes Behältnis für unser Bild. Als Block-Element »rutscht« es unter die Tagline, was uns nicht gefällt. Den Hebel setzen wir bei einem entsprechenden Außenabstand an, der gleichzeitig die Zentrierung sowie das »Nach-oben-Holen« durch einen negativen Wert für margin-top übernimmt. Über einen Innenabstand geben wir dem sonst überlappten Text den nötigen Raum. div#tagline span { margin: -1.4em auto 0; padding-left: 340px; }
Das war es aber noch nicht ganz: Damit der um das Bild ergänzte Tagline-Inhalt wirklich zentriert wirkt, muss der Außencontainer etwas Innenabstand erhalten, der die Bildbreite sowie etwas Abstand umfasst: div#tagline { padding-right: 60px; }
Inhalt Für den Inhalt der Webseite bzw. ihrer Homepage sind drei Bereiche vorgesehen, die gleich breit und hoch sein sowie nebeneinander stehen sollen.
Eröffnungsangebot
Lorem ipsum […]
Wissenswertes
Lorem ipsum […]
Fanartikel
Lorem ipsum […]
Um diese Art der Visualisierung zu erreichen, lassen wir die Container fließen. Beginnen wir mit ein paar generellen Regeln. div#inhalt { margin: auto; padding: 25px 0; width: 645px; }
44
Teil I: Seitenvorlagen
div#inhalt div { float: left; width: 195px; }
Mittels auto -Außenabstand zentrieren wir den Inhaltsbereich. Da die Deklarationen der Navigation teilweise identisch sind, fassen wir diese noch zusammen. (Die bei der Navigation angegebene Breite würde aber dann durch die div#inhalt-Regel »überschrieben« werden, während die relative Positionierung hier harmlos ist.) Die umschlossenen div-Elemente stellen wir über die float-Eigenschaft nebeneinander. Wenn es um die Überschriften geht, können wir uns ebenfalls »Synergien« zunutze machen, da die Schrift der Tagline auf dieselbe Art formatiert wurde. Wir fassen also auch hier unsere CSS-Zuweisungen zusammen, sobald wir die von uns gewünschte Darstellung erreicht haben: h2 { background: url(bilder/ueberschrift.gif) no-repeat; font-size: 1.2em; font-weight: bold; height: 2.7em; line-height: 1.8; padding-right: 7px; text-align: right; }
Abbildung 5-11: ueberschrift.gif, 195 x 36 Pixel
Der Umstand, dass die einzelnen Abschnitte im Inhalt jeweils nur einen Absatz umfassen, versetzt uns in die glückliche Lage, nicht noch ein gesondertes Hilfskonstrukt zusammenschrauben zu müssen, sondern einfach den p-Elementselektor nutzen zu können. Über diesen Selektor weisen wir den Absätzen eine Hintergrundfarbe, einen Rahmen (jedoch nicht nach oben) sowie den gewünschten Innenabstand zu (nach oben ebenfalls modifiziert). p { background: #74A9DC; border: 1px solid #EEF5FB; border-top: 0; padding: 7px 14px 14px; }
Fehlt also nur noch eins: Die drei Kästen brauchen etwas Abstand zueinander. div#inhalt div#mitte { margin: 0 30px; }
Hinweis
Wie bei der Tagline ist es auch hier legitim, den Farbkontrast zu hinterfragen. Während wir diese Webseite aber einfach als Test ansehen, würden wir diese Problematik in einer echten Version unbedingt berücksichtigen.
Referenzen • CSS-Spezifikation: Die text-indent-Eigenschaft http://www.w3.org/TR/CSS21/text.html#indentation-prop Kapitel 5, Fließlayout »World of Fish«
45
Konsole
»Konsole« ist eine ausgesprochen schlichte und sicher auch etwas kontroverse »Webseite«. An ihr wollen wir einige Dinge ausprobieren.
6 Schwierigkeitsgrad: einfach
Abbildung 6-1: »Konsole«
47
Die Struktur des Dokuments ist einfach: …
Die ehemalige »Konsole« (der 1. Auflage dieses Buchs) orientierte sich am Aussehen einer »Shell« oder Eingabeaufforderung; die neue Version möchte etwas weniger technisch daherkommen. Dazu starten wir mit einem hellen, freundlichen Hintergrund und schwarzer Schrift; diese in der nicht wirklich unbeliebten – und zudem recht guten – Georgia, mit einer Schriftgröße von 16 Pixel (100%). html { background: #F4FAD8 url(bilder/hintergrund-schlauch.gif) repeat-x; color: #000; font: 100%/1.1 georgia, serif; }
Die beiden Überschriftenebenen sollen die gleiche, relativ große Schriftgröße besitzen und nicht fett formatiert sein. h1, h2 { font-size: 3.5em; font-weight: normal; }
Die h1-Überschrift versehen wir mit einem oben rechts angezeigten und nicht wiederholten Hintergrundbild, das optisch in das html-Hintergrundbild übergeht. Außerdem geben wir ihr eine schwarze Schriftfarbe und versichern uns der für das Hintergrundbild benötigten Höhe, während wir gleichzeitig etwas Abstand zu allen Seiten vorgeben:
Abbildung 6-2: hintergrund-schlauch.gif, 1 x 236 Pixel (hier vergrößert dargestellt)
h1 { background: url(bilder/hintergrund-pflanzen.gif) top right no-repeat; color: #000; height: 216px; line-height: 1.7; padding: 10px; }
Sehen wir uns nun das Markup näher an:
Konsole<span>_
Das wird provokant, wenn wir die folgende Regel hinzufügen: h1 span { text-decoration: blink; }
Für die zweite Überschrift, aber auch für Absätze sowie das abschließende div-Element legen wir eine gemeinsame Breite sowie einen festen Außenabstand fest: Abbildung 6-3: hintergrund-pflanzen.gif, 282 x 236 Pixel
48
Teil I: Seitenvorlagen
h2, p, div { margin-left: 235px; width: 350px; }
Wir widmen uns noch einmal der Zwischenüberschrift, um ihr ein wenig Innenabstand sowie eine geringere Zeilenhöhe zuzuweisen – das sieht bei mehrzeiligen Inhalten besser aus. h2 { line-height: 1.0; padding-bottom: .5em; }
Den Absätzen brauchen wir kaum noch Aufmerksamkeit zu schenken, allerdings interessiert uns der jeweils erste Buchstabe. Für den hält die CSSSpezifikation bekanntlich das Pseudoelement :first-letter bereit, das wir zum Einsatz bringen werden. p:first-letter { font-size: 2.5em; line-height: 0.9; padding-right: .1em; }
Warnung
Abgesehen davon, dass der Internet Explorer den blinkWert bis dato nicht unterstützt, sollte jedem Webdesigner und Webentwickler bewusst sein, dass das »Flackern« und Blinken von Bildschirmelementen in einer Frequenz von 2 bis 50 Hertz und ab einer bestimmten Größe für Menschen mit fotosensitiver Epilepsie gefährlich sein kann. In unserem Fall ist der betroffene Bereich, der Unterstrich, relativ klein, und zudem ist die Frequenz bei den Browsern, die blink unterstützen, sehr gering, so dass unser Vorgehen hier nicht allzu problematisch ist.
:first-letter setzen wir so ein, dass es eine ähnliche Schriftgröße wie
die Überschriften und eine reduzierte Zeilenhöhe erhält sowie mit einem dezenten Innenabstand dem eigentlichen Text etwas Luft gönnt. Bisher haben wir weder Bilder verwendet noch irgendwelche Klassen oder IDs eingesetzt, und das bleibt auch so. Den Seitenabschluss haben wir über einen div-Container gezielt in Position gebracht, und nun kümmern wir uns noch um den Innenabstand: div { padding: 1em 0; }
Bei den Links bringen wir noch etwas Farbe ins Spiel. Wir verwenden ein schickes Grün, das wir bei Fokus und »Hovern« durch ein helles Blau ersetzen. Besuchte Links lassen wir über die :visited-Pseudoklasse einen Tick dunkler erscheinen. a { color: #2F5107; } a:visited { color: #55771C; } a:focus, a:hover { color: #4EB6EA; }
In der Zeit kocht man auch keine Tütensuppe. Kapitel 6, Konsole
Es steht eine knallbunte Chatgemeinschaft an, die wir mit interessanten Techniken zum Leben zu erwecken versuchen.
7 Schwierigkeitsgrad: mittel
Abbildung 7-1: Spaltenlayout »Chat & mehr!«
51
Einer unserer Schwerpunkte wird der Einsatz einer speziellen Technik sein, um ein liquides (das gesamte Browserfenster ausnutzendes) Layout mit zwei festen Außenspalten zu kreieren. Bevor wir aber dazu kommen, stehen wie immer einige andere Punkte an. Der erste sind generelle Zuweisungen auf dem html-Element. Dazu gehören die Schrift und deren Farbe sowie der Hintergrund. Dieser umfasst bereits einen Teil unserer »Spaltentaktik«. Um die linke Spalte nachher – optisch – komplett über die volle Höhe laufen zu lassen, installieren wir ein entsprechendes Hintergrundbild, das sich nur vertikal wiederholt.
Abbildung 7-2: spalte-1-hintergrund.gif, 189 x 1 Pixel (hier vergrößert dargestellt)
Und mit dieser assoziieren wir zwei Bilder, einen großen Hintergrund sowie ein Logo. Man kann bei Logos argumentieren, dass sie eine bestimmte Bedeutung einbringen und einen Inhalt haben. Wir aber wollen unser Markup so kompakt wie möglich halten und verwenden deshalb kein imgElement. In zwei Schritten haben wir den Kopfbereich zurechtgerückt. Im ersten Schritt verwenden wir den Selektor h1. Über diesen legen wir zunächst ein Hintergrundbild sowie eine Hintergrundfarbe an. Die Farbe benötigen wir für Fenster, die über die Breite von 1214 Pixeln hinausgehen. Die beiden weiteren Deklarationen fixieren die Höhe (221 Pixel, um das Hintergrundbild auch in voller Höhe zeigen zu können) sowie die Breite (100%, da das h1-Element über die ganze Breite gehen muss). So funktioniert unser Unterfangen zudem auch bei kleinen Auflösungen. h1 { background: #FFF url(bilder/kopf.jpg) no-repeat; height: 221px; width: 100%; }
52
Teil I: Seitenvorlagen
Im zweiten Schritt folgt der von der Überschrift eingeschlossene Link, der entsprechende Selektor lautet h1 a. Zunächst machen wir aus unserem Link ein 156 x 148 Pixel großes Block-Element.
Abbildung 7-3: kopf.jpg, 1214 x 221 Pixel
display: block; height: 148px; width: 156px;
156 x 148 Pixel deshalb, weil dies die Maße des Logos sind, das wir über die background-Eigenschaft einsetzen. background: url(bilder/logo.gif);
Dann lassen wir den Text mit Hilfe der Phark-Methode verschwinden. Der in einigen User-Agents verbliebenen und lästigen Unterstreichung entledigen wir uns über die text-decoration-Eigenschaft. text-decoration: none; text-indent: -999em;
Abbildung 7-4: logo.gif, 156 x 148 Pixel
Schließlich manövrieren wir noch den zuvor »gestylten« Anker an seinen Platz. left: 37px; position: absolute; top: 61px;
Erst verzichten wir also auf ein img-Element für das Logo, dann weisen wir dem umschließenden Link nur gerade die Maße des Logos zu – beides deutet schon an, dass es hier natürlich eine Reihe von Herangehensweisen gibt. Wir könnten also »echte Bilder« verwenden, und wir könnten dem Link auch gleich den vollen h1-Raum zukommen lassen und das Logo dann als Hintergrundbild über background-position hinschieben. Tun wir aber nicht. Dieser Spielraum ist etwas, auf das man meistens – nicht immer – beim Arbeiten mit HTML und CSS stößt. Und wie verfahren wir auf der Homepage? Schließlich verlinkt man nicht auf Seiten, auf denen man sich schon befindet. Auf der Homepage würden wir anstelle des Elements a einfach ein span-Element einhängen. Und das wird genauso behandelt wie die Links, nämlich (jetzt alles zusammen): h1 a, h1 span { background: url(bilder/logo.gif); display: block;
Die Navigation Das Menü der Webseite besteht aus zwei Teilen, einem linken und einem rechten. Das Markup trägt diesem Umstand dadurch Rechnung, dass es zwei Listen vorsieht.
Der Navigationscontainer ist unser erstes Ziel. Er erhält ein Hintergrundbild, das von der Farbgebung dem rechten Menübereich entspricht, sowie eine Höhe, um die vollständige Darstellung dieses Bildes sicherzustellen. div#nav { background: url(bilder/nav-hintergrund.gif); height: 26px; }
Abbildung 7-5: nav-hintergrund.gif, 1 x 26 Pixel (hier vergrößert dargestellt)
Den beiden Navigationslisten haben wir aus Gründen der Einfachheit keine IDs zugewiesen, sondern sie mit Klassen versehen. Damit weichen wir etwas von unserem üblichen Schema ab, diese IDs und zugehörige Bilderpräfixe in der Form nav-1 oder nav-2 zu benennen. Da wir ja auch noch mit einem nav-Container arbeiten, wird unser Code dadurch etwas einfacher. Nun widmen wir uns den ul-Elementen und entziehen ihnen über die liststyle-Eigenschaft explizit die Listenpunkte: div#nav ul { list-style: none; }
Die Herausforderung, die eine Liste links, die andere rechts darzustellen, gehen wir über »Floats« an. Interessanterweise müssen wir sowohl die ul‑Elemente (um die Listen an die Seiten zu bekommen) als auch die
54
Teil I: Seitenvorlagen
l i‑Elemente fließen lassen (diese sollen ja schließlich ebenfalls nebeneinander stehen). Im Zusammenhang mit der float-Eigenschaft müssen wir jeweils die Breite definieren, und dieser Anforderung entsprechen wir selbstverständlich, zumindest erst mal bei unseren ul-Elementen: div#nav ul.a, div#nav ul.a li, div#nav ul.b li { float: left; } div#nav ul.a { width: 470px; } div#nav ul.b { float: right; width: 188px; }
Damit die einzelnen Listenelemente ebenfalls nebeneinander stehen, ist auch für sie eine Breitenangabe erforderlich. Außerdem ergänzen wir noch die Schriftzuweisungen: div#nav li, div#nav li a { color: #FFF; height: 26px; text-decoration: none; } div#nav li { font-size: 1.1em; font-weight: bold; line-height: 1.95; width: 94px; text-align: center; } div#nav li a { display: block; }
In der ersten Regel landen die Deklarationen, die wir zwingend für die Listenelemente wie auch für die enthaltenen Links benötigen. In der zweiten Regel befinden sich alle Deklarationen, die die Listenelemente alleine brauchen bzw. deren Werte die Darstellung der Links ebenfalls beeinflussen. In der letzten Regel bemühen wir uns in Kombination mit der heightDeklaration aus der ersten Regel darum, dass die klickbare Fläche der Links jeweils das gesamte Listenelement einnimmt. Eine unserer Ideen für diese Chat-Seite bestand darin, aktive Menüpunkte hervorzuheben (wie beim »Hovern«). In diesem Fall gehen wir aber nicht so vor, dass aktive Punkte die »Ausnahme« darstellen und besonders behandelt werden, sondern genau andersherum. Wie? Indem alle li-Elemente das eigentlich hervorhebende, »aktive« Hintergrundbild erhalten:
Kapitel 7, Spaltenlayout »Chat & mehr!«
55
div#nav ul.a li { background: url(bilder/nav-a-button-an.gif); }
Abbildung 7-6: nav-a-button-an.gif, 94 x 26 Pixel
Abbildung 7-7: nav-b-button-an.gif, 94 x 26 Pixel
Abbildung 7-8: nav-a-button.gif, 94 x 26 Pixel
div#nav ul.b li { background: url(bilder/nav-b-button-an.gif); }
Der Standardfall ist jedoch, dass ein Menüpunkt einen Link enthält. Diesen Umstand nutzen wir, indem diese Links den »eigentlichen« Hintergrund erhalten. div#nav ul.a li a { background: url(bilder/nav-a-button.gif); } div#nav ul.b li a { background: url(bilder/nav-b-button.gif); }
Und um jetzt auch noch das »Hovern« mit dem »aktiven« Stil zu verbinden, fügen wir den beiden erstgenannten Regeln die Selektoren div#nav ul.a li a:hover sowie div#nav ul.b li a:hover hinzu: Abbildung 7-9: nav-b-button.gif, 94 x 26 Pixel
div#nav ul.a li, div#nav ul.a li a:hover {} div#nav ul.b li, div#nav ul.b li a:hover {}
Lockern wir die fast abgeschlossene Navigation auf der linken Seite noch durch eine Verzierung auf. Durch einen Innenabstand nach rechts verbreitern wir die Liste und geben ihr dann in diesem Innenabstand das gewünschte Bild.
Abbildung 7-10: nav-a-verzierung.gif, 49 x 26 Pixel
Der Inhalt Der Inhaltsbereich wird durch drei Spalten gebildet, wobei zwei äußere Spalten mit einer festen Breite sowie ein innerer, liquider Inhaltsbereich definiert werden. Das Gerüst bilden drei Container:
Die Umsetzung dieses Spaltenlayouts ist einfach: Die mittlere und eigentliche Inhaltsspalte geht über die volle Breite, aber wir geben ihr einen linken und rechten Außenabstand, der der Breite unserer beiden äußeren Spalten entspricht. Diese beiden Spalten, die zum besseren Zugang auf den eigentlichen Inhalt im Code am Schluss kommen (spalte-1 kommt nur optisch »vor« inhalt), setzen wir anschließend einfach über eine absolute Positionierung ein. 56
Die top-Eigenschaft dient hierbei zur Kompensierung des Kopfbereichs wie auch der Navigation, damit diese nicht durch die beiden Spalten überlappt werden. Da wir dies so zügig hinter uns gebracht haben, kommen nun die einzelnen Bereiche an die Reihe. Die erste Spalte basiert – wie bereits eingangs erwähnt – auf einem optischen Effekt, der dadurch bedingt wird, dass wir rechts einen blauen Streifen runterlaufen lassen. Über diesen legen wir jetzt noch ein Bild, dessen Maße auch die der Spalte diktieren. div#spalte-1 { background: #F2B96E url(bilder/spalte-1.gif); height: 507px; }
Das werden wir nachher natürlich alles noch einmal zusammenfassen.
Die erste Regel ändert, wie man schnell erkennt, den Listenstil in circle ab. Eine kleine Spielerei. Zudem wird – wie bei der h2-Überschrift zuvor – ein Außenabstand nach oben und nach rechts fixiert. Die anderen beiden Regeln schenken den Listen ein Hintergrundbild, das jeweils »oben« anliegt, um 30 Pixel nach rechts verschoben sowie nicht wiederholt wird. Eine Sache ist zu beachten: Es müssen immer genug Mitglieder online sein, besser ausgedrückt: aufgeführt werden. Wir können keine (maximale) Höhe vorgeben, da die Liste ja möglicherweise länger wird (auch wenn die Höhe des spalte-1-Containers eine »natürliche« Grenze darstellt). Eine Mindesthöhe, um die Darstellung der beiden Hintergrundbilder zu gewährleisten, scheitert an der mangelnden Implementierung der min-heightEigenschaft im Internet Explorer 6. Eine realistische Lösung besteht darin, die Höhe der beiden Listen dennoch zu fixieren und sie (mit Hilfe der hinter der Seite stehenden Applikationslogik) mit einem verlinkten Punkt »…« abzukürzen, wenn zu viele Mitglieder online sind. Die letzte Handlung in der ersten Spalte betrifft die Links, die weiß sein sollen: div#spalte-1 a { color: #FFF; }
Weiter zur nächsten Spalte, die wir vor den eigentlichen Inhalten behandeln. Der rechte Abschnitt erhält ebenfalls ein Hintergrundbild und damit auch seine Mindestmaße.
Die hier ebenfalls weiße Schrift sowie die identisch zur ersten Spalte formatierte Überschrift erhalten wir, indem wir die entsprechenden Zuweisungen zusammenlegen: div#spalte-1, div#spalte-2 { color: #FFF; } div#spalte-1 h2, div#spalte-2 h2 { font-size: 1.1em; }
Wir wollen das Markup nicht unterschlagen und warten darin mit einer kleinen Überraschung auf:
Wussten Sie schon?
Lorem ipsum […]
Lorem ipsum […]
Die Überraschung ist das hr-Element – überraschend deshalb, weil wir den beabsichtigten Effekt ebenso über die border-Eigenschaft erzielen könnten, aber auch, weil das hr-Element aus semantischer Sicht nicht unumstritten ist. Andauernde Diskussionen in der W3C-Arbeitsgruppe sowie auf den Verteilern des W3C lassen immer noch keine definitive Aussage zu, ob das in XHTML 2 als Nachfolger designierte separator-Element nicht noch umbenannt oder gar entfernt wird. Die h2-Überschrift erhält von uns einen schöneren Außenabstand: div#spalte-2 h2 { margin: 30px 0 0 35px; }
Dasselbe widerfährt den Absätzen: div#spalte-2 p { margin: 10px 15px 10px 35px; }
Dem Trenner müssen wir eine ganze Reihe von Deklarationen zukommen lassen, soll er auch nur annähernd überall gleich aussehen. hr { border: 0; border-bottom: 1px solid #FFF; height: 1px; margin: 0 10px 0 30px; }
hr ist wirklich nicht so einfach zu formatieren: Zum einen müssen wir die Farbe des Trenners explizit angeben (border-color »erbt« normalerweise den
Wert der Schriftfarbe, aber nicht hier), zum anderen wünscht der Internet Explorer, dass wir die Höhe fixieren. Und auch wenn wir so vorgehen, ist der Abstand zwischen den Absätzen und dem hr-Element nicht überall Kapitel 7, Spaltenlayout »Chat & mehr!«
59
gleich. Dass Opera unseren Außenabstand nicht wirklich berücksichtigt, ignorieren wir einfach. Wir betrachten diese Episode als »Experiment«. Schlussendlich wollen wir diese Webseite und ihre Finessen mit dem verbliebenen Inhaltsbereich abschließen.
Abbildung 7-15: herz.gif, 170 x 135 Pixel Hinweis
Wir legen ausdrücklich nahe, solche Bilder mit einem aussagekräftigeren alt-Text als in unserem Beispiel zu versehen.
Über uns
Lorem ipsum […]
…
˜gibt es nicht viel zu sagen
Lorem ipsum […]
…
Als Erstes benötigen wir etwas Luft. div#inhalt { padding: 20px; }
Dann sollen die Zwischenüberschriften etwas prominenter werden, zumindest größer als ihre Spaltengeschwister. h2 { font-size: 1.3em; }
Die Absätze dürfen an die Überschriften angrenzen, sollen aber nach unten Abstand halten. p { margin-bottom: 1em; }
Auch wenn wir in all den informativen Inhalten noch keine Links verwenden, vergessen wir diese jedoch nicht: a { color: #000; }
Bilder wollen wir grundsätzlich rechts im Text haben, wir lassen sie also fließen – mit einem ein Pixel breiten Rahmen, der seine Farbe von der Schriftfarbe bezieht, und ausreichend Außenabstand nach links und nach unten. img { border: 1px solid; float: right; margin: 0 0 2em 2em; }
In diesem kleinen Finale setzen wir auf Elementselektoren, weil keine kontextuellen Selektoren mehr notwendig sind. Zum einen »überschreiben« wir die verwendeten Deklarationen von h2, p und a ohnehin wieder – einfach dank der höheren Spezifität der Spaltenselektoren. Zum anderen handelt es sich um bislang einmalige Elemente (img). 60
Teil I: Seitenvorlagen
Referenzen • XHTML 2.0-Entwurf: Das separator-Element http://www.w3.org/TR/xhtml2/mod-structural.html#sec_8.9.
Kapitel 7, Spaltenlayout »Chat & mehr!«
61
Fließlayout »PC-Shop« Mit dem »PC-Shop« kommt ein kommerzielles Angebot auf uns zu, das wir exemplarisch realisieren wollen. Ziel der Umsetzung ist es, wie immer mit validem und semantischem Markup sowie kompaktem CSS eine ansprechende, zugängliche Webseite zu erstellen.
8 Schwierigkeitsgrad: schwer
Abbildung 8-1: Fließlayout »PC-Shop«
63
Eine Besonderheit des »PC-Shop«-Layouts besteht darin, dass wir nicht wie in den anderen Abschnitten dieses Buchs Auflösungen ab 800 x 600 Pixeln unterstützen, sondern eine Auflösung von 1024 x 768 Pixeln voraussetzen. Zwar geschieht das hier nur demonstrativ, es gibt aber im Internet einen verstärkten Trend hin zur Optimierung auf größere Auflösungen zu verzeichnen. Während spezialisierte Seiten, deren Publikum in hoher Zahl große Auflösungen verwendet, dies sicherlich verantworten können, kann generell aber noch nicht zu diesem Schritt geraten werden. Internationale Statistiken sprechen nämlich eine andere Sprache. Im März 2007 verwendeten noch 13% der knapp 84 Millionen Besucher von Seiten, die durch TheCounter. com erfasst wurden, eine Bildschirmauflösung von 800 x 600 Pixeln. Den Anfang machen wir über die generelle Definition von Weiß als Hintergrundfarbe, Schwarz als Schriftfarbe und Verdana als bevorzugter Schriftart. html { background: #FFF; color: #000; font: 81.25%/1.2 verdana, arial, helvetica, sans-serif; }
Zudem sorgen wir über das body-Element für einen 10 Pixel großen Außenabstand, der den Seitenelementen Raum verschafft. Aus dem Autor unbekannten Gründen stürzt mit dem Internet Explorer 6 unter Windows XP das ganze System ab, will man einen Innenabstand einsetzen. body { margin: 10px; }
Logo und Werbung Die ersten beiden Elemente auf der »PC-Shop«-Webseite bestehen aus einem Logo und einem Werbebanner:
Abbildung 8-2: logo.gif, 296 x 117 Pixel
Abbildung 8-3: werbung.jpg, 613 x 85 Pixel
64
Teil I: Seitenvorlagen
Das Werbebanner entspricht nicht den Standardmaßen von beispielsweise 234 x 60 Pixeln für ein »Halfsizebanner« oder 468 x 60 Pixeln für ein »Fullbanner«, da es sich dabei um eine Sonderaktion des Shops handelt. Um die »echten« Bilder, die wir hier verwenden, von dem Standardrahmen zu befreien, den die um sie platzierten Links erzeugen, erstellen wir die folgende Regel: a img { border: 0; }
Davon wird auch das Logo profitieren, wenn auf Unterseiten des Shops ein Link zur Homepage eingesetzt wird. Der eingangs definierte Außenabstand macht eine weitere Regel notwendig, die das h1-Element betrifft und für ein wenig Platz nach unten sorgt. h1 { margin-bottom: 10px; }
Die Eigenwerbung muss an die richtige Stelle manövriert werden, was wir über absolute Positionierung erledigen:
Hinweis
Auffallend ist, dass wir ausnahmsweise auf eine Bildersatztechnik verzichten, um das Logo in der Überschrift darzustellen. Stattdessen verwenden wir ein img-Element. Dieses Vorgehen ist rein demonstrativ: Das Problem bei dieser Vorgehensweise ist, dass Suchmaschinen hier keinen Überschriftentext indizieren und damit diesem nicht das Gewicht beimessen werden, das ihm eigentlich zukommt. Da Bildschirmlesesoftware (wie der IBM Home Page Reader) die Überschrift dennoch erkennt und vorliest, ist dies zwar nicht unzugänglich, aber wegen der erwähnten Suchmaschinenpro blematik als Eigentor zu sehen.
Die Position der Werbung ergibt sich dadurch, dass wir nach links genügend Platz für das Logo lassen müssen (359 Pixel) und die Reklame rechts später bündig mit den Inhalten sein soll. Nach oben wünschen wir 10 Pixel Raum, die wir explizit angeben müssen, da der bereits definierte bodyAußenabstand durch die Positionierung wirkungslos ist.
Navigation Die Navigation besteht aus drei Bereichen: Hardware, Software und »Über uns«. Jeder dieser Bereiche erfordert eine Liste, so dass sich das folgende Markup ergibt:
Die weitere Struktur wird dadurch bestimmt, dass wir einen Außencontainer (nav) brauchen, um den gesamten Bereich auf der Seite fließen zu lassen – auf diese Art sorgen wir dafür, dass Navigation und Inhalt am Ende nebeneinander stehen. Die Untercontainer nav-1 bis nav-3 benötigen wir, um die Zusammengehörig keit der jeweiligen »Navigationsüberschrift« mit ihrer Liste zu dokumentieren. Zudem bilden sie die Grundlage für die in Kürze eingesetzten Selektoren. In den einzelnen Untercontainern kommen strong- und ul-Elemente zum Einsatz, wobei letztere dann die Menüs repräsentieren. Warum aber strongElemente anstatt »echter« Überschriften? Diese Überlegung beruht darauf, dass zum einen als Überschriften h2-Elemente erforderlich wären – das »Überspringen« von Überschriftenebenen gilt als schlechtes Vorgehen –, was des Guten zu viel wäre, denn semantisch sind die Navigationsbeschrif tungen nicht so bedeutend. Zudem sind sie kein echter Bestandteil unserer Dokumentstruktur. Gäbe es eine anstelle von drei Überschriften, die den Navigationsabschnitt kennzeichnen, könnte man den Einsatz eines h2Elements in Erwägung ziehen, bei unserer Anwendung scheidet dies jedoch aus. Semantisch »unwichtig« sind die Navigationsbeschriftungen jedoch nicht, und so sorgt strong für etwas mehr Gewicht. XHTML 2.0 wird genau dieses Problem, das wir mit unserer Navigation erleben, höchstwahrscheinlich über das nl- und label-Element angehen (siehe Infokasten). Wir beginnen die Formatierung der Navigation damit, dass wir sie nach links »fließen« lassen, wobei die Breite des »Überschriften«-Hintergrundbilds die Breite des Containers bestimmt: div#nav { float: left; width: 158px; }
66
Teil I: Seitenvorlagen
Anschließend formatieren wir einen gepunkteten Rahmen nach rechts, indem wir die border-right-Eigenschaft deklarieren (im Internet Explorer 6 einen gestrichelten Rahmen, was dem Rahmenstil dashed entspricht, da er dotted nicht versteht). Damit der Rahmen nicht direkt an der Liste anliegt, fügen wir rechts noch einen Innenabstand von 30 Pixeln hinzu. Ein ebenso großer, den Inhaltsbereich auf Distanz haltender Außenabstand, der über die margin-right-Eigenschaft realisiert wird, rundet alles ab. div#nav { border-right: 1px dotted; margin-right: 30px; padding-right: 30px; } Ein Blick in die Spezifikation
Navigationslisten in XHTML 2.0 Der Entwurf zur XHTML 2.0-Spezifikation zollt der Praxis und den Erfordernissen hinsichtlich Navigationsmenüs Tribut, indem er das nl-Element (»Navigation List«) einführt, das semantisch eine Navigation ausdrücklich kennzeichnet, und indem er Menübeschriftungen über das label-Element erlaubt. Das Markup der im vorliegenden Design verwendeten »Hardware«Navigation würde in XHTML 2.0 wie folgt aussehen:
Drucker
Eingabegeräte
Gehäuse
Grafikkarten
Kommunikation
Speicher
Neben der verbesserten Semantik wird der Code wesentlich einfacher. Dazu trägt auch das href-Attribut bei, das – wenn der aktuelle XHTML 2.0-Entwurf »Empfehlungsstatus« erreicht und zur Spezifikation wird – auf alle Elemente angewendet werden darf. Das a-Element wird aber aller Voraussicht nach Bestandteil des XHTML-Vokabulars bleiben.
Den »Navigationsüberschriften« verleihen wir jetzt einen Hintergrund, den die jeweilige Liste durch einen Rahmen vervollständigt. div#nav div { background-repeat: no-repeat; } div#nav-1 { background-image: url(bilder/hintergrund-nav-1.jpg); }
Kapitel 8, Fließlayout »PC-Shop«
Abbildung 8-4: hintergrund-nav-1.jpg, 158 x 42 Pixel
Während die Regel div#nav div generell vorgibt, dass sich die Hintergrundbilder nicht wiederholen dürfen, definieren wir über die Selektoren div#nav‑1 bis div#nav-3 die einzelnen Bilder. Die zugehörigen Listen versehen wir mit einem Rahmen, den wir nach oben mittels border-top: 0; »deaktivieren«. Mit der list-style-Eigenschaft entfernen wir die Listenpunkte, und wir geben einen Außenabstand nach unten sowie eine feste Breite vor. div#nav ul { border: 1px solid #C0C0C0; border-top: 0; list-style: none; margin-bottom: 10px; width: 156px; }
Da sich der rechte Rahmen, der vom Navigationscontainer beschrieben wird, nach den Inhalten der Navigation richtet, führt der Außenabstand der letzten Liste dazu, dass der Rahmen 10 Pixel »zu lang« wird. Um dies zu vermeiden, setzen wir diesen Außenabstand auf 0: div#nav-3 ul { margin-bottom: 0; }
Die strong-Elemente dienen nicht nur als semantische Betonung, sondern werden natürlich auch entsprechend hervorgehoben. Den Text betreffend nehmen wir drei Anpassungen vor. Zum einen ändern wir die Schrift in eine Serifenschrift ab, und zwar in Georgia. Die Zeilenhöhe wird via line-height auf das 3,5-Fache hochgesetzt, so dass die gesamte Höhe des Hintergrundbilds beansprucht wird. Indem der Text auf der Grundlinie bleibt, wird er durch diese Zeilenhöhenanpassung genau an die gewünschte Stelle verschoben. Und über die text-transform -Eigenschaft kommen wir in den Genuss von Versalien. Mit einem Innenabstand von 7 Pixeln nach links erzielen wir eine leichte Einrückung des Textes. div#nav strong { font: .9em/3.5 georgia, serif; padding-left: 7px; text-transform: uppercase; }
Ebenfalls über die Zeilenhöhe verschaffen wir den Navigationslisten Luft zwischen den einzelnen Menüpunkten. Und wir justieren sie durch einen
68
Teil I: Seitenvorlagen
Innenabstand zu allen Seiten außer nach oben mit nochmals 7 Pixeln. Bedingt durch das CSS-Boxmodell, müssen wir die width-Deklaration entsprechend anpassen. div#nav ul { line-height: 1.4; padding: 0 7px 7px 7px; width: 142px; }
Um die Navigation zu vervollständigen, müssen wir uns lediglich noch um die Links kümmern. Global sollen alle Links rot und unterstrichen sein, in der Navigation jedoch schwarz und ohne Unterstreichung. Diese Anforderungen können wir in zwei Regeln verpacken. text-decoration: underline; müssen wir nicht explizit angeben, da durch eigentlich alle UserAgent-Stylesheets Links grundsätzlich unterstrichen werden. a { color: #C40F0F; } div#nav a { color: #000; text-decoration: none; }
Inhalt Die Struktur des Inhaltsbereichs ist durch eine ganze Reihe von Hilfs containern in Form von div-Elementen geprägt. Neben einem einleitenden Absatz umfasst er vier Abschnitte, die inhaltlich die Komplettangebote und Sonderangebote, den Newsletter und einen »Shop-Navigator« ausmachen und denen wir gleichnamige IDs vorgeben.
Ähnlich wie bei der Navigation muss der Inhaltsbereich zunächst an die gewünschte Stelle gebracht werden. Wir erledigen dies analog über die float-Eigenschaft mitsamt einer definierten Breite von 735 Pixeln. div#inhalt { float: left; width: 743px; }
Das erste eigentliche Element im Inhaltsbereich wird durch einen Anreißer repräsentiert. Den Anreißer heben wir nicht nur durch eine Textzentrierung über text-align hervor, sondern – ähnlich der Navigation, die sich so nach rechts abgrenzt – durch einen Innenabstand, einen Rahmen sowie einen Außenabstand nach unten. Den Außenabstand erweitern wir noch dahin gehend, dass er auch nach links und rechts Platz freigibt – ein kleines kosmetisches Experiment. p#anreisser { border-bottom: 1px dotted; margin: 0 30px 15px; padding-bottom: 15px; text-align: center; }
An die einzelnen »Boxen«, die Angebote, Newsletter und »Shop-Navigator« bilden, gehen wir erst allgemein und dann speziell heran. Generell sollen
70
Teil I: Seitenvorlagen
alle div-Elemente innerhalb des inhalt-Containers »gefloatet« werden, wir wollen sie nebeneinander stellen, und sie haben für uns erst einmal alle die gleichen Maße: div#inhalt div { float: left; height: 212px; width: 223px; }
Die Ausnahmen – tatsächlich sind die Maße der div-Elemente natürlich nicht überall identisch – erhalten eine Sonderbehandlung. Die Breiten- und Höhenangaben resultieren bei allen Kästen aus den noch einzusetzenden Hintergrundbildern, was auch für den »Shop-Navigator« gilt. Wir müssen ein !important hinter seine height- und width-Deklarationen setzen, da die ursprüngliche Regel div#inhalt div, die ja bereits alle div-Maße definiert, eine höhere Spezifität besitzt und sonst Vorrang hat. div#shop-navigator { height: 162px !important; width: 743px !important; }
Seine div-Kindelemente erhalten als Höhe den Wert auto (wir wollen diese nicht explizit setzen). Die Breite ist das Ergebnis einer Rundung: 743 Pixel sind verfügbar, die sich sechs Rubriken teilen müssen, was 123,8333… ergibt und auf eine natürliche Zahl abgerundet werden muss – 123 Pixel. Hier ist kein !important erforderlich, da zwar die Spezifität der beiden Selektoren gleich ist (0,1,0,2), die im Code später folgenden Deklarationen jedoch als maßgeblich gelten. Die Spezifität von Selektoren wird in Kapitel 4, »Spaltenlayout ›Alias‹«, näher beschrieben. div#shop-navigator div { height: auto; width: 123px; }
Bevor es an das Design der einzelnen Kästen geht, sorgen wir über die margin-Eigenschaft für ihre korrekte Ausrichtung. div#sonderangebote { margin: 0 37px 30px; }
Diese Regel sorgt dafür, dass die drei ersten Kästen den ganzen zur Verfügung stehenden Raum von 743 Pixeln ausnutzen – jeder einzelne ist 223 Pixel breit, was 669 Pixel ergibt, so dass noch 74 Pixel zu vergeben sind. Diese 74 Pixel werden auf die linke und rechte Seite des »Sonderangebote«Kastens verteilt. Der abschließende Container geht bereits über die ganze Breite, soll jedoch einen Abstand nach oben erhalten – diesen Effekt können wir recht elegant erzielen, wenn wir den Sonderangeboten auch gleich einen Abstand nach unten geben.
Kapitel 8, Fließlayout »PC-Shop«
71
Alle Kästen erhalten jetzt ein Hintergrundbild. Die Hintergrundbilder umfassen im Gegensatz zu den Navigationsbildern den gesamten Kasten, da wir über diese einen leichten Schatteneffekt erzielen wollen. div#komplettangebote { background: url(bilder/hintergrund-komplettangebote.jpg); } div#sonderangebote { background: url(bilder/hintergrund-sonderangebote.jpg); }
Abbildung 8-9: hintergrund- komplettangebote.jpg, 223 x 212 Pixel
Die Kastenüberschriften, die durch h2-Elemente abgebildet werden, werden genauso gestaltet wie die Navigationsbeschriftungen. Wir gruppieren daher einfach div#nav strong-Regel und h2-Selektor:
Abbildung 8-10: hintergrund- sonderangebote.jpg, 223 x 212 Pixel
Eine weitere simple Gruppierung erspart es uns, eine zusätzliche Regel für die gewünschte Schwarzfärbung und Nichtunterstreichung der h2-Links zu erstellen, da wir die entsprechenden Deklarationen bereits in der Navigation verwenden: h2 a, div#nav a { color: #000; text-decoration: none; }
Abbildung 8-11: hintergrund- newsletter.jpg, 223 x 212 Pixel
Ziel von Nutzertests sollte es an dieser Stelle sein, herauszufinden, ob die fehlende Unterscheidungsmöglichkeit zwischen Überschriften, die Links
Abbildung 8-12: hintergrund-shop-navigator.gif, 743 x 162 Pixel
72
Teil I: Seitenvorlagen
enthalten, und solchen, die nur aus Text bestehen (wie zum Beispiel beim Newsletter), problematisch ist. Wenn wir unsere Seite als einen Prototyp für einen solchen Test betrachten bzw. solche Tests unseren Designentwürfen immer folgen, muss man dies jetzt lediglich anmerken. Wir können die Unterscheidbarkeit zwischen normalem Text und Links zumindest etwas fördern, indem wir mittels der Pseudoklasse :hover eine Textunterstreichung beim Darüberfahren mit der Maus zulassen: h2 a:hover, div#nav strong a:hover { text-decoration: underline; }
In der Navigation erweitern wir den Selektor div#nav a dabei nicht nur um die :hover-Pseudoklasse, sondern auch um einen strong-Selektor, da nur in diesen Elementen Links unterstrichen werden sollen. Arbeiten wir zur Finalisierung der Webseite nun die Kästen nacheinander ab. Die Komplett- und Sonderangebote enthalten jeweils lediglich ein Bild. Da im Inhaltsbereich sonst keine Bilder eingesetzt werden, ergibt sich für uns daraus der Selektor div#inhalt img. Die Zentrierung und den Abstand nach oben, den wir für die Bilder wünschen, gehen wir mathematisch an: Uns stehen 223 Pixel zur Verfügung, von denen die Bilder jeweils 155 beanspruchen – macht 34 Pixel Abstand zu den Seiten. Nach oben legen wir 5 Pixel Abstand fest. div#inhalt img { margin: 5px 34px 0; }
Auf diesem Weg ersparten wir uns übrigens ehemals hinsichtlich der Zentrierung auch Probleme mit dem Internet Explorer 5.x, der den autoWert der margin-Eigenschaft nicht versteht und uns gezwungen hätte, zusätzlich noch die text-align-Eigenschaft zu deklarieren. Die »Newsletter«-Box enthält zwei Absätze, für die wir eine Regel mit einem Außenabstand definieren: div#newsletter p { margin: 5px 7px 10px; }
Der »Shop-Navigator«-Bereich bereitet ebenso wenig Aufwand. Zwingend erforderlich ist mehr Abstand zwischen den Untercontainern, wobei wir das Boxmodell berücksichtigen und somit die Breite entsprechend reduzieren müssen: div#shop-navigator div { padding: 0 7px; width: 109px; }
Kapitel 8, Fließlayout »PC-Shop«
73
Die letzte Maßnahme besteht darin, die h3-Überschriften in der regulären Schriftgröße darzustellen. Bei aller Liebe zu Kontext und Sortierung in unserem Stylesheet – hier stellen wir dem Selektor kein div#shop-navigator voran. h3 { font-size: 1em; }
Referenzen • TheCounter.com-Statistiken http://www.thecounter.com/stats/ • Jens Meiert: HTML: Hinweise zu Überschriften und Hierarchien (Outlines) http://meiert.com/de/publications/articles/20070106/ • XHTML 2.0-Entwurf: Das nl-Element http://www.w3.org/TR/xhtml2/mod-list.html#edef_list_nl • XHTML 2.0-Entwurf: Das label-Element http://www.w3.org/TR/xhtml2/mod-list.html#edef_list_label • XHTML 2.0-Entwurf: href http://www.w3.org/TR/xhtml2/mod-hyperAttributes.html#adef_hyperAttributes_href
74
Teil I: Seitenvorlagen
Spaltenlayout »Anodesign« Das »Anodesign«-Layout dient uns erneut als Möglichkeit, validen, semantischen und zugänglichen Code in einem schlichten, aber durchaus ansprechenden Design zu verpacken. Wir wollen auch dieses Layout wieder mehr spaltig umsetzen.
9 Schwierigkeitsgrad: einfach
Abbildung 9-1: Spaltenlayout »Anodesign«
75
Den Anfang machen wie üblich die generellen Zuweisungen. So wünschen wir schwarze Schrift in Form von Georgia auf weißem Grund. Zusätzlich erhalten wir den ersten Effekt, die erste »Spalte«, durch ein vertikal wiederholtes Hintergrundbild. html { background: #FFF url(bilder/hintergrund.gif) repeat-y; color: #000; font: 87.5%/1.3 georgia, serif; }
Abbildung 9-2: hintergrund.gif, 215 x 1 Pixel (hier vergrößert dargestellt)
Das Markup der Seite können wir in drei Abschnitte unterteilen, die es uns auch einfach machen, die entsprechenden Elemente auszuwählen. Die Überschrift und unser Logo bilden den ersten Abschnitt, der zweite Abschnitt ist die Navigation in Form einer Liste, und der letzte Abschnitt ist der Inhaltsbereich, den wir durch einen einfachen div-Container abbilden.
Die Umsetzung der Überschrift erfordert etwas Voraussicht. Wir müssen uns überlegen, wie wir die Inhalte einsetzen wollen. Die Inhalte werden im rechten Abschnitt der Webseite platziert, links muss Platz für Logo und Navigation sein. Diese Zweiteilung der Seite lässt sich auf zwei Arten erreichen: »Floats« und Positionierung. »Floats« erscheinen uns problematisch, da der linke Bereich der Seite mit Logo und Navigation eine feste, der rechte Inhaltsbereich jedoch eine variable Breite haben soll. Realistischer scheint also die Positionierung zu sein, ähnlich wie wir sie schon in Kapitel 7, »Spaltenlayout ›Chat & mehr!‹«, verwendet haben, indem wir dem Inhaltsbereich die volle Breite überlassen, einen festen Außenabstand definieren und optisch in diesem weitere Elemente einsetzen. Nach diesen Vorüberlegungen nehmen wir also die Überschrift aus dem »normalen Fluss« heraus und greifen auf die absolute Positionierung zurück. h1 { left: 0; position: absolute; }
Die Breite und Höhe der Überschrift ist durch die Größe des Hintergrundbildes bedingt, das auch das Logo selbst beinhaltet. 76
Im nächsten Schritt lassen wir die h1-Textinhalte über die text-indentEigenschaft »verschwinden«. h1 { text-indent: -999em; }
Und in der Überschrift verwendete Links sollen ebenfalls mit Zuwendung bedacht werden: h1 a { display: block; height: 375px; text-decoration: none; }
Abbildung 9-3: logo.gif, 215 x 375 Pixel
display: block; macht aus dem Link ein Block-Element, was uns in die Lage versetzt, das Element im Zusammenhang mit der height-Eigenschaft den gesamten Platz in der Überschrift ausfüllen zu lassen. text-decoration: none; sorgt dafür, dass trotz der »Ausrückung« des Textes über h1 in wirklich kei-
nem Browser mehr etwas von einer Linkunterstreichung zu sehen ist. Die erstellten Regeln und Deklarationen könnten wir bereits zusammenfassen, werden dies aber erst am Ende tun, da noch mehr Vereinfachungen möglich sein werden.
Die Navigation besteht aus der einzigen Liste auf unserer Seite. Das ermöglicht uns, einfache Elementselektoren zu verwenden. Einzige Ausnahme: Für die Hervorhebung des Pfades und des aktuellen Menüpunkts über die Klasse aktiv benötigen wir einen Attributselektor.
Kapitel 9, Spaltenlayout »Anodesign«
77
Bevor wir die Liste an die richtige Stelle bringen oder die einzelnen Menüpunkte bearbeiten, sorgen wir erst einmal für das Entfernen der Listenpunkte sowie für eine angemessene Einrückung. ul { list-style: none; } ul ul { margin-left: 1.5em; }
Die erste Regel sorgt dafür, dass keine Listenmarkierungen (Bullets) verwendet werden, die zweite Regel rückt die zweite Liste um anderthalb »em« nach rechts. Im nächsten Schritt kümmern wir uns um die Positionierung der Navigation. Um »freie Sicht« zu haben – momentan liegt zumindest schon die Überschrift über den Inhalten –, schieben wir den Inhaltsbereich etwas beiseite: div { margin-left: 435px; }
Das ul-Element positionieren wir jetzt an die richtige Stelle, dabei richten wir es optisch an dem Logo bzw. dessen Hintergrund aus. Damit die Positionierung nicht auch die zweite, verschachtelte Liste betrifft, heben wir sie über position: static; auf; die Liste befindet sich somit wieder im »normalen Fluss«. ul { left: 240px; position: absolute; top: 60px; } ul ul { position: static; }
Es fehlt noch etwas »Styling« für die li-Elemente und die enthaltenen Links. Über die line-height-Eigenschaft sorgen wir vertikal für etwas mehr Raum. li { line-height: 2.0; }
Die Links sollen generell schwarz und in der Navigation nicht unterstrichen sein: eine Aufgabe für die Eigenschaften color und text-decoration, die auf die Selektoren a und li a angewendet werden. a { color: #000; } li a { text-decoration: none; }
78
Teil I: Seitenvorlagen
Um die Navigationslinks zumindest beim »Hovern« noch mal hervorzuheben, soll dort eine Unterstreichung vorliegen: li a:hover { text-decoration: underline; }
Es fehlt jetzt nur noch eine Kleinigkeit: Der Pfad zum aktuellen Punkt und der aktuelle Punkt selbst sollen in roter Farbe dargestellt werden. Dazu benötigen wir den Selektor .aktiv, der sowohl auf unsere mit der Klasse aktiv versehenen li-Elemente als auch a-Elemente zutrifft: .aktiv { color: #C70000; }
Inhaltsbereich
Blindtext
Lorem ipsum […]
Vivamus massa. […]
…
Bei der einfachen Struktur des gesamten Dokuments, in dem bislang kein einziges div-Element vorkam, können wir ein solches hernehmen, um den Inhaltsbereich auf einfachem Wege zu kennzeichnen und damit einen einfachen Selektor an der Hand zu haben. Im Navigationsabschnitt haben wir etwas vorgegriffen, um überhaupt sehen zu können, wie wir die Navigationsliste anordnen: div { margin-left: 435px; }
So haben wir links eine Aussparung erzeugt, in der wir die Überschrift bzw. das Logo und auch die Navigation unterbringen können. Das div-Element ist dennoch »liquide«, beansprucht also die restliche Breite des Fensters. Um den Inhaltsbereich optisch noch etwas mehr zur Geltung zu bringen, werden wir ihn jetzt mit einer Hintergrundfarbe, einem Rahmen nach links und einem Innenabstand versehen: div { background: #EDEBD5; border-left: 1px solid; padding: 2em; }
Hinweis
Bei den von uns verwendeten Inhalten reicht die rechte Spalte bei vielen Fenstergrößen bis zum Ende der Seite, bei weniger Text wird aber ein weißer Bereich unter dem Inhaltscontainer zu sehen sein. Das liegt daran, dass die Größe des div-Elements von den Inhalten (den Texten) abhängt. Das ist okay.
Da die Inhalte nur noch aus einer h2-Überschrift sowie Absätzen bestehen, können wir dieses Layout relativ rasch abschließen. Die Überschrift soll in dem roten Ton der als »aktiv« gekennzeichneten Listenpunkte erscheinen und eine größere Schrift bekommen. Kapitel 9, Spaltenlayout »Anodesign«
79
h2 { color: #C70000; font-size: 2.2em; }
Wir geben allen Absätzen einen einfachen Außenabstand nach oben: p { margin-top: 1em; }
Am Ende widmen wir uns noch dem »Anreißer«, dessen Schrift wir kursiv stellen: p#anreisser { font-style: italic; }
CSS-Überblick Da bei der sukzessiven Aufzählung der für die Umsetzung des Layouts erforderlichen Regeln auch einige Vereinfachungen deutlich wurden, folgt hier das vollständige Stylesheet mit den zusammengefassten Regeln: * { margin: 0; padding: 0; } html, a { color: #000; } html { background: #FFF url(bilder/hintergrund.gif) repeat-y; font: 87.5%/1.3 georgia, serif; } h1, h1 a { height: 375px; } h1, ul { position: absolute; } h1 { background: url(bilder/logo.gif); left: 0; text-indent: -999em; width: 215px; } h1 a, li a { text-decoration: none; }
80
Teil I: Seitenvorlagen
h1 a { display: block; } h2 { color: #C70000; font-size: 2.2em; } p { margin-top: 1em; } p#anreisser { font-style: italic; } ul { left: 240px; list-style: none; top: 60px; } ul ul { margin-left: 1.5em; position: static; } li { line-height: 2.0; } li a:hover { text-decoration: underline; } div { background: #EDEBD5; border-left: 1px solid; margin-left: 435px; padding: 2em; } .aktiv { color: #C70000; }
Der folgende Teil II ist vom Anspruch her einfach, denn die Semantik der darzustellenden Designs erfordert durchgehend Listenelemente. Die vor gestellten Designs werden aber illustrieren, was für vielfältige Szenarien und Gestaltungsmöglichkeiten sich trotz ähnlicher Struktur und damit ähnlichem Markup ergeben.
II In diesem Teil 10 Blog-Navigation 11 Sitemap 12 Navigation »Fischwelten« 13 Fotoalbum 14 Navigation »08/15« 15 Themennavigation 16 Veranstaltungskalender
83
Blog-Navigation
Bei diesem Design arbeiten wir mit einem auch in Kapitel 24, »Image-Map«, angewendeten Prinzip. Es handelt sich um eine schlichte Blog-Navigation, in der beim »Hovern« keine Verzögerung auftreten soll.
Zuerst bringen wir die semantisch erforderliche Liste auf die richtige Größe und setzen das Hintergrundbild ein – den oberen, »richtigen« Teil des Bildes, versteht sich. Listenbullets wollen wir nicht, also deaktivieren wir sie. Außerdem ergänzen wir die Schriftzuweisung auf dem html-Element noch durch die font-weight-Eigenschaft. ul { background: url(bilder/wolken.jpg); color: #FFF; font-weight: bold; height: 188px; list-style: none; text-transform: uppercase; width: 560px; }
Abbildung 10-2: wolken.jpg, 560 x 376 Pixel
Der verzögerungsfreie »Hover«-Effekt basiert nun darauf, dass die entsprechenden Bilder nicht mehr neu geladen werden müssen, sondern durch das Hintergrundbild schon vorliegen. Im Gegensatz zum Design in Kapitel 24, »Image-Map«, haben wir hier durch geschicktes Zuschneiden des Bildes etwas Ladezeit sparen können. Die einzelnen Listenelemente stecken nun die Bereiche ab, in denen der Effekt sichtbar wird. Wir gehen zudem über »Floats« vor: Wir lassen die Listenpunkte fließen und definieren die Zwischenabstände über einen Außenabstand nach links: 86
Der »Blog«-Menüpunkt stellt eine Ausnahme dar und muss dementsprechend behandelt werden. Normalerweise würden wir ihn einfach mit einem größeren Außenabstand versehen, doch leider zickt dabei wieder der Internet Explorer rum. Wir umgehen das Problem, indem wir den Außenabstand für »Blog« zurücksetzen und stattdessen der Liste einen passenden Innenabstand verleihen. Wegen des Boxmodells müssen wir zudem die Breite der Liste neu justieren: ul { padding-left: 29px; width: 531px; } li.blog { margin-left: 0; }
Die Links selbst versorgen wir nun mit ein paar Zuweisungen, die dafür Sorge tragen, dass sie den zur Verfügung stehenden Platz auch ausnutzen (display: block;), wobei wir über die height-Eigenschaft noch die exakte Höhe vorgeben. Zusätzlich folgen zwei selbsterklärende Deklarationen, die die Farbe festlegen und die Unterstreichung der Links vermeiden. li a { color: #FFF; display: block; height: 137px; text-decoration: none; }
Nun aber zum eigentlichen Effekt: Wenn man mit der Maus über einen Navigationslink fährt, aber auch, wenn man durch das Menü »tabbt«, soll sich der Hintergrund ändern. Das ist eine klare Anforderung an die zu verwendenden Selektoren. Ebenso ist klar, welche CSS-Eigenschaften dafür herangezogen werden müssen: background-image und background-position. li a:focus, li a:hover, li a:active { background-image: url(bilder/wolken.jpg); } li.blog a:focus, li.blog a:hover, li.blog a:active { background-position: 0 -188px; } li.portfolio a:focus, li.portfolio a:hover, li.portfolio a:active { background-position: -117px -188px; }
Sie können den Fall, dass in Linklisten manche Punkte nicht verlinkt werden, aber die Darstellung von Links abhängt, grundsätzlich auch über spanElemente adressieren. In un serem Fall könnten wir also dem nicht verlinkten »Blog«Punkt einfach das a-Element entziehen und stattdessen ein span verwenden. Dann würden wir die a-Regeln nur um analoge span-Selektoren ergänzen müssen, um denselben Effekt zu erzielen.
Um noch etwas mehr Praxisnähe zu zeigen, haben wir hier – und das haben Sie vielleicht auch schon im Markup erkannt – ein Szenario geschaffen, das davon ausgeht, dass man sich gerade im Blog befindet und deshalb nicht auf diesen Bereich verlinkt wird. Da wir einen solchen aktiven Bereich ebenso hervorheben wollen, wie es beim »Hovern« der Navigationslinks der Fall ist, haben wir uns noch eine Klasse aktiv vorbehalten, die nun zum Einsatz kommt. Deshalb werden auch keine IDs verwendet. Die entsprechende Modifikation ist einfach: Wir ergänzen die obigen vier Regeln jeweils durch die Selektoren li.aktiv, li.blog.aktiv, li.portfolio. aktiv und li.kontakt.aktiv. Zuletzt müssen noch die Navigationstexte justiert werden. In den Bereichen, in denen die Navigation wirklich Links verwendet (»Portfolio«, »Kontakt«), versehen wir die Links mit einem Innenabstand. In Bereichen, in denen man sich befindet (»Blog«), müssen wir dem Listenpunkt selbst einen solchen Innenabstand geben. Das wird uns aber durch die Klasse aktiv erleichtert. Auch hier gilt in Bezug auf die Breite: Vorsicht, Boxmodell! li a, li.aktiv { height: 19px; padding: 118px 0 0 5px; width: 112px; }
CSS-Überblick Zusammengefasst erhalten wir neben schlankem Markup ein nicht minder schlankes Stylesheet: * { margin: 0; padding: 0; } html { background: #FFF; font: 81.25%/1.0 arial, helvetica, sans-serif; } ul { background: url(bilder/wolken.jpg); color: #FFF; font-weight: bold; height: 188px; list-style: none; padding-left: 29px; text-transform: uppercase; width: 531px; }
In diesem Beispiel nehmen wir uns einen sehr praktischen Teil unserer fiktiven Webseite vor, nämlich das Inhaltsverzeichnis, auch »Sitemap« genannt. Ganz offiziell, wie wir es diesmal halten wollen, tun wir so, als ob wir zufällig dieselben Inhalte wie die Bundesregierung haben.
11 Schwierigkeitsgrad: einfach
Abbildung 11-1: Sitemap
91
Und damit geht es los:
Hinweis
Wir wollen uns nicht den Seitenhieb verkneifen, dass unser Markup hier nicht nur valide ist, sondern schlanker und vor allem semantischer als der Quelltext der inhaltlichen Vorlage.
Auch wenn die Struktur der Sitemap hierarchisch ist, wir also Listenelemente verschachteln, soll die Darstellung der Sitemap diese Hierarchie anders abbilden. Den ersten Schritt in diese Richtung nimmt uns unser überall zum Einsatz kommender universeller Selektor mit dem »Zurücksetzen« Innen- und Außenabstände ab: * { margin: 0; padding: 0; }
Gleich im Anschluss kommen zwei generelle Zuweisungen für das htmlElement zum Einsatz: eine für den Hintergrund, die neben orangener Hintergrundfarbe auch ein nur horizontal wiederholtes Bild setzt, und eine für die Schrift. html { background: #C84905 url(bilder/hintergrund.jpg) repeat-x; font: 87.5%/1.3 arial, helvetica, sans-serif; }
Dann nehmen wir uns das h1-Element vor. Es soll eine andere Schrift (Trebuchet MS) sowie eine etwas größere Schrift als der reguläre Text bekommen (nahezu weiß) und auch nicht fett hervorgehoben werden, wobei wir den Text über eine niedrige line-height heranführen. Eine durchgezogene Linie soll es nach unten abgrenzen, und ein dezenter Außenabstand nach unten ist auch angemessen: Abbildung 11-2: hintergrund.jpg, 200 x 238 Pixel
Ein kleines Intermezzo stellen die Links dar, die im Allgemeinen hell und beim Darüberfahren mit der Maus fast weiß dargestellt werden sollen: a { color: #E3DBBB; } a:hover { color: #F3EFDD; }
Nun geht es an die Listen. Die Listensymbole verschwinden zu lassen ist einfach: ul { list-style: none; }
Mit Hilfe eines Außenabstands bewirken wir eine dezente Einrückung der untersten Hierarchie: ul ul ul { margin-left: 1.9em; }
Bringen wir ein paar Grafiken ins Spiel. Die Listenelemente der ersten und zweiten Ebene enthalten Unterpunkte, sind also gewissermaßen »Ordner«; zumindest wollen wir ihnen eine solche Kennzeichnung zuteilwerden lassen. Dazu legen wir die folgenden beiden Regeln an. (Prinzipiell bräuchten wir nur die Selektoren a und a:hover, aber wir beziehen uns so explizit auf Links in Listen.) li a { background: url(bilder/ebene-aus.gif) 0 2px no-repeat; padding-left: 27px; } li a:hover { background-image: url(bilder/ebene-an.gif); }
Die erste Regel definiert das Hintergrundbild und gibt an, dass dieses 2 Pixel weiter unten stehen soll und nicht wiederholt werden darf. Außerdem werden die Links mit einem Innenabstand von 27 Pixeln versehen, um Platz für das Hintergrundbild zu schaffen. Die zweite Regel sorgt dafür, dass beim »Hovern« eines Links das Hintergrundbild gewechselt wird.
Abbildung 11-3: ebene-aus.gif, 21 x 14 Pixel (hier vergrößert dargestellt)
Abbildung 11-4: ebene-an.gif, 21 x 14 Pixel (hier vergrößert dargestellt)
Beide Regeln treffen auf alle Listenelemente zu, doch das ist eigentlich nicht unsere Intention. Da wir aber nicht groß mit Klassen oder IDs hantieren wollen – und auch gar nicht müssen –, »überschreiben« wir nun die Zuweisungen auf den unteren Ebenen:
Kapitel 11, Sitemap
93
li li li a { background-image: url(bilder/dok-aus.gif); padding-left: 16px; }
Abbildung 11-5: dok-aus.gif, 11 x 14 Pixel (hier vergrößert dargestellt)
li li li a:hover { background-image: url(bilder/dok-an.gif); }
Die Deklarationen sprechen für sich selbst, interessant ist lediglich der Selektor, der uns tief in die Hierarchie führt. Abbildung 11-6: dok-an.gif, 11 x 14 Pixel (hier vergrößert dargestellt)
Warnung
Wer unserem Weg gefolgt ist, muss diese beiden Regeln unbedingt vor der bereits oben einmal vorkommenden ul ul ul-Regel platzieren. Ansonsten schlägt die Kaskade zu und die »neue« margin-Deklaration greift auch für den linken Außenabstand. Aber keine Sorge: In Kürze führen wir alle Regeln zusammen und lösen dabei den drohenden Konflikt.
Die unterste Ebene wurde von uns eingerückt. Etwas irritierend ist nun, dass »Homepage« auf gleicher Höhe wie beispielsweise »Bundesregierung« oder »Reformprojekte« steht. Genau das ist beabsichtigt, aber wir müssen daran noch etwas feilen. Als Verfechter eines Stils, der lieber auf eine Klasse oder ID verzichtet, anstatt auch nur eine zu viel zu verwenden, führt unser Weg über Elementselektoren: ul ul { border-top: 1px dashed #F3EFDD; margin-top: .4em; padding-top: .4em; } ul ul ul { border: 0; margin: 0; padding: 0; }
In der ersten Regel verpassen wir jeder unsortierten Liste, die sich bereits innerhalb einer anderen solchen Liste befindet, einen Innenabstand nach oben, einen 1 Pixel dicken Rahmen sowie einen Außenabstand, der genauso groß ist wie der definierte Innenabstand. Die zweite Regel sorgt dafür, dass all diese Regeln eine Ebene darunter, wenn also noch eine Liste folgt, annulliert werden – dort wollen wir nichts von Rahmen, Innen- und Außenabständen wissen. Wer mag, kann die erzielte optische Trennung auch über eine ID vornehmen (macht aufgrund der Einmaligkeit mehr Sinn als eine Klasse), indem er diese entweder dem »Homepage«-Listenelement oder dem darauffolgenden ul-Element zuweist, wo wir ja jetzt ansetzen.
CSS-Überblick Unsere erste Liste ist nun einsatzbereit, und der entstandene CSS-Code ist kurz: * { margin: 0; padding: 0; }
94
Teil II: Listen und Menüs
html { background: #C84905 url(bilder/hintergrund.jpg) repeat-x; font: 87.5%/1.3 arial, helvetica, sans-serif; } body { padding: 50px; } h1, a:hover { color: #F3EFDD; } h1 { border-bottom: 2px solid; font: normal 1.7em/.8 'trebuchet ms', arial, helvetica, sans-serif; margin-bottom: .6em; } ul { list-style: none; } ul ul { border-top: 1px dashed #F3EFDD; margin-top: .4em; padding-top: .4em; } ul ul ul { border: 0; margin: 0 0 0 1.9em; padding: 0; } li a { background: url(bilder/ebene-aus.gif) 0 2px no-repeat; padding-left: 27px; } li a:hover { background-image: url(bilder/ebene-an.gif); } li li li a { background-image: url(bilder/dok-aus.gif); padding-left: 16px; } li li li a:hover { background-image: url(bilder/dok-an.gif); } a { color: #E3DBBB; }
Navigation »Fischwelten« Mit »Fischwelten« stellen wir mal eine zugegebenermaßen äußerst fiktive und gleichzeitig äußerst simple Navigation zusammen. Wir befürchten zudem, dass durch Fische als Menüpunkte unsere Nutzertests weniger erfolgreich verlaufen würden – da könnten gerne aussagekräftigere Punkte her.
Zunächst färben wir die ganze Seite über den »Viewport« (die durch das html-Element aufgezogene Fensterfläche) dunkelblau (#002238) ein. Dann liegt als erste eigentliche Übung die Formatierung des h1-Elements an: html { background: #002238; } h1 { height: 85px; } h1 a { background: url(bilder/fischwelten.gif) 15px 24px no-repeat; display: block; height: 100%; text-decoration: none; text-indent: -999em; }
Abbildung 12-2: fischwelten.gif, 318 x 63 Pixel
Wir verwenden wie immer unseren Liebling in puncto Bildersatz: die Phark-Methode. Da sie in diesem Buch sehr oft auftaucht und in Kapitel 19, »Newsletter-Formular«, ausführlich vorgestellt wird, werden wir hier nicht näher auf sie eingehen. Auch die Navigation wird nicht schwer: Eigentlich müssen wir nur die li-Elemente fließen lassen, ihre Größe festlegen, die enthaltenen Links zu Block-Elementen machen, diese noch mit einem Bildchen versehen und den eigentlichen Text verstecken. ul { list-style: none; } li { float: left; height: 138px; width: 138px; }
98
Teil II: Listen und Menüs
li a { display: block; height: 100%; text-decoration: none; text-indent: -999em; } li#nav-1 a { background: url(bilder/nav-1.gif); }
Abbildung 12-3: nav-1.gif, 138 x 138 Pixel
li#nav-2 a { background: url(bilder/nav-2.gif); } li#nav-3 a { background: url(bilder/nav-3.gif); } li#nav-4 a { background: url(bilder/nav-4.gif); }
Abbildung 12-4: nav-2.gif, 138 x 138 Pixel
li#nav-5 a { background: url(bilder/nav-5.gif); }
Um unsere Liste gänzlich perfekt zu machen, müssen wir sie noch mit etwas mehr Innenabstand versehen, schließlich stehen die einzelnen Bilder sehr nah an der Überschrift. Wir greifen auf die padding-Eigenschaft zurück, weil die ebenfalls noch zu setzende Hintergrundfarbe dort sichtbar ist – ein Außenabstand würde uns nichts nützen. Außerdem legen wir noch die Höhe fest. ul { background: #8A3304; height: 138px; padding: 10px; }
Abbildung 12-5: nav-3.gif, 138 x 138 Pixel
Abbildung 12-6: nav-4.gif, 138 x 138 Pixel
CSS-Überblick Fassen wir unsere Arbeit zusammen: * { margin: 0; padding: 0; }
Abbildung 12-7: nav-5.gif, 138 x 138 Pixel
html { background: #002238; }
Kapitel 12, Navigation »Fischwelten«
99
h1 { height: 85px; } h1 a, li a { display: block; height: 100%; text-decoration: none; text-indent: -999em; } h1 a { background: url(bilder/fischwelten.gif) 15px 24px no-repeat; } ul { background: #8A3304; height: 138px; list-style: none; padding: 10px; } li { float: left; height: 138px; width: 138px; } li#nav-1 a { background: url(bilder/nav-1.gif); } li#nav-2 a { background: url(bilder/nav-2.gif); } li#nav-3 a { background: url(bilder/nav-3.gif); } li#nav-4 a { background: url(bilder/nav-4.gif); } li#nav-5 a { background: url(bilder/nav-5.gif); }
Ein schöner Urlaub bedarf auch einer schönen Präsentation der geschossenen Bilder. Für das dafür zu kreierende Fotoalbum denken wir uns deshalb auch nicht gerade etwas Triviales aus, wir wollen eine CSS-Vorschau sowie ein nettes Drumherum.
13 Schwierigkeitsgrad: schwer
Abbildung 13-1: Fotoalbum »Paris 2005«
101
Wie immer widmen wir uns zuerst den grundsätzlichen und einfachen Dingen, zum Beispiel den Hintergrundbildern. Dem html-Element schenken wir einen schlichten Hintergrund: html { background: #292929 url(bilder/hintergrund.gif); }
Abbildung 13-2: hintergrund.gif, 10 x 10 Pixel (hier vergrößert dargestellt)
Der body wird mit einem schwergewichtigen Bild versehen, das einen Block darstellt. Damit es horizontal keine Scrollbalken gibt, geben wir dem bodyElement keine feste Breite vor und nehmen in Kauf, dass ein Teil des Bildes bei kleineren Auflösungen abgeschnitten wird. Die von uns über background-position vorgegebene Zentrierung verhindert aber Schlimmeres. Die Höhe hingegen geben wir fest vor und sorgen mit einem Außenabstand nach oben und unten noch für etwas Luft. body { background: url(bilder/block.gif) top center no-repeat; height: 628px; margin: 20px 0; }
Abbildung 13-3: block.gif, 797 x 628 Pixel
102
Teil II: Listen und Menüs
Die Überschrift ist das erste »echte« Element, mit dem wir uns befassen, wobei wir dem html-Element noch Zuweisungen für die Schrift und deren Farbe mit auf den Weg geben. html { color: #000; font: bold 75%/1.2 verdana, arial, helvetica, sans-serif; }
Der Austausch des Überschriftentextes durch ein Bild kommt in diesem Buch öfter vor. In dieser Übung wollen wir das Bild jedoch nicht ganz zentrieren, sondern durch einen Außenabstand noch an die richtige Stelle schieben. Ein Innenabstand scheidet für dieses Manöver aus, da die background-Eigenschaft Innenabstände mit einbezieht. Ein Innenabstand ist aber noch beteiligt, weil wir ihn brauchen, um für einen Abstand nach oben zu sorgen. Das Hintergrundbild sitzt durch seine Position im Element (bottom) trotzdem richtig. h1 { background: url(bilder/ueberschrift.gif) bottom center no-repeat; font-size: 1em; height: 36px; margin-left: 80px; padding-top: 112px; text-indent: -999em; }
Abbildung 13-4: ueberschrift.gif, 119 x 36 Pixel
Listenmagie Das Markup unseres Albums besteht aus einer Liste, die wir mit ein paar zusätzlichen Finessen ausstatten.
Das Markup wurde für die Darstellung im Buch etwas verkürzt: Es fehlen die Bildreferenzen (src-Attribut) sowie deren Alternativtexte (alt-Attribut).
Kapitel 13, Fotoalbum
Tipp
Die XHTML-Datei, die Sie unter der in der Einleitung angegebenen Adresse herunterladen können, enthält natürlich das vollständige Markup. Allerdings haben wir dort die Alternativ texte nur sehr allgemein mit »Bild 1« bis »Bild 9« angegeben. Das sollten Sie nicht nachahmen. Bitte machen Sie sich die Mühe und Ihren Besuchern die Freude und geben Sie Ihren Bildern aussagekräftige Be schreibungen.
103
Abbildung 13-5: bild-1-gr.jpg, 264 x 353 Pixel
Abbildung 13-6: bild-2-gr.jpg, 264 x 353 Pixel
Abbildung 13-7: bild-3-gr.jpg, 264 x 353 Pixel
Abbildung 13-8: bild-4-gr.jpg, 264 x 353 Pixel
Abbildung 13-9: bild-5-gr.jpg, 264 x 353 Pixel
Abbildung 13-10: bild-6-gr.jpg, 264 x 353 Pixel
Abbildung 13-11: bild-7-gr.jpg, 264 x 353 Pixel
Abbildung 13-12: bild-8-gr.jpg, 264 x 353 Pixel
Abbildung 13-13: bild-9-gr.jpg, 264 x 353 Pixel
Was nun folgt, ist ein bisschen wie »Augen zu und durch«. Wir bringen als Erstes die Liste in Position und sorgen über die marginEigenschaft für Zentrierung. Zu der position-Deklaration müssen wir anmerken, dass wir diese für die noch folgende Positionierung der spanElemente benötigen. bild-1-gr.jpg machen wir zum »Deckblatt« des MiniAlbums. ul { background: url(bilder/bild-1-gr.jpg) right no-repeat; height: 353px; list-style: none; margin: 41px auto 0; padding-left: 65px; position: relative; width: 623px; }
Besagte span-Elemente blenden wir vorerst aus: li span { display: none; }
Nun »floaten« wir die zunächst leeren Listenelemente, wobei wir einen Abstand nach oben und rechts definieren: li { float: left; margin: 16px 16px 0 0; width: 84px; } li a { display: block; height: 81px; }
Leer sind diese Elemente nur für kurze Zeit, denn wir versehen sie jetzt mit je einem Hintergrundbild. Wir blenden also die großen Bilder aus, um den Listenelementen bzw. deren Ankern, die ja »noch da« sind, dann die Kleinansicht vorzugeben.
Abbildung 13-14: bild-1-kl.jpg, 82 x 81 Pixel
Abbildung 13-15: bild-2-kl.jpg, 82 x 81 Pixel
li#bild-1 a { background: url(bilder/bild-1-kl.jpg); } li#bild-2 a { background: url(bilder/bild-2-kl.jpg); }
Abbildung 13-16: bild-3-kl.jpg, 82 x 81 Pixel
li#bild-3 a { background: url(bilder/bild-3-kl.jpg); } li#bild-4 a { background: url(bilder/bild-4-kl.jpg); }
Kapitel 13, Fotoalbum
Abbildung 13-17: bild-4-kl.jpg, 82 x 81 Pixel
105
li#bild-5 a { background: url(bilder/bild-5-kl.jpg); }
Abbildung 13-18: bild-5-kl.jpg, 82 x 81 Pixel
li#bild-6 a { background: url(bilder/bild-6-kl.jpg); } li#bild-7 a { background: url(bilder/bild-7-kl.jpg); }
Abbildung 13-19: bild-6-kl.jpg, 82 x 81 Pixel
li#bild-8 a { background: url(bilder/bild-8-kl.jpg); } li#bild-9 a { background: url(bilder/bild-9-kl.jpg); }
Abbildung 13-20: bild-7-kl.jpg, 82 x 81 Pixel
Abbildung 13-21: bild-8-kl.jpg, 82 x 81 Pixel
Abbildung 13-22: bild-9-kl.jpg, 82 x 81 Pixel
Eine zusätzliche Regel ist erforderlich, die nach dem dritten und sechsten Bild mit einem ausreichend großen Außenabstand das Layout »stützt«. li#bild-3, li#bild-6 { margin-right: 300px; }
Die bis dato »unsichtbaren« span-Elemente und deren Kinder, die Bilder der Großansicht, wollen wir beim »Durchtabben« (:focus-Pseudoklasse) sowie beim Darüberfahren mit der Maus wieder sichtbar machen. Außerdem müssen wir aus diesen Elementen noch Block-Elemente machen, da wir bestimmte Maße vorgeben müssen und Inline-Elementen keine width und height zuweisen können. a:focus span, a:hover span { display: block; height: 353px; position: absolute; right: 0; top: 0; width: 264px; }
Wir wollen aber nicht unterschlagen, was wir an dieser Stelle eigentlich mit den großen Bildern machen: Wir positionieren sie absolut zur Liste und weisen sie mittels right und top an, in der rechten oberen Ecke zu sitzen. Ein wenig Feinschliff kommt dieser sehr rasch durchlaufenen, aber im Grunde auch nicht allzu schweren Übung zugute, indem die a-Elemente noch ein paar Zuweisungen erhalten, die für einen grauen bzw. schwarzen Rahmen sorgen: a { border: 1px solid #999; }
Das ist ein bisschen gemein, da man zuvor teilweise die Standardrahmen ertragen musste (die wir über die a img-Regel wegwischen). Aber wir haben den dann gesetzten Rahmen wiederum berücksichtigt, indem wir den Listenelementen gleich zu Beginn schon eine Breite von 84 Pixeln zugewiesen haben (statt einer Breite von 82 Pixeln, wenn wir ganz auf einen Rahmen verzichtet hätten).
Authentizität Authentizität ist das Stichwort, wenn wir das Ganze noch raffinierter gestalten wollen. Wir verwenden zwei Klebestreifen, die wir über die großen Bilder legen, und zwar links oben und rechts unten. Um die Liste selbst erst noch wirklich zu »malträtieren«, indem wir sinnleere Schmuckbilder in den li-Elementen verwenden, bedienen wir uns eines strukturellen div-Hilfskonstrukts, das wir um die Liste schreiben. Wir haben das bewusst nicht schon früher eingefügt, da es für die Albumliste selbst nicht relevant ist, wie man sieht. Allerdings führt das in der Konsequenz dazu, dass wir nun noch mal Hand an ein paar ulDeklarationen legen und diese »auslagern« müssen. Die Regeln für ul und div sehen dann wie folgt aus: ul, div { position: relative; width: 623px; } ul { background: url(bilder/bild-0.jpg) right no-repeat; height: 353px; list-style: none; } div { margin: 41px auto 0; padding-left: 65px; }
Dies ist eine gute Basis, um nun im div-Container die Klebestreifen vorzubereiten:
Kapitel 13, Fotoalbum
107
Die Klasse klebestreifen benutzen wir, um beide Container mit einer absoluten Positionierung und mit einer Deklaration zu versehen, die den weiter oben definierten padding-Wert überschreibt: div.klebestreifen { padding: 0; position: absolute; }
Anschließend folgen die individuellen Hintergrundbilder, die Maße sowie die Positionsangaben.
Abbildung 13-23: klebestreifen-oben.png, 83 x 67 Pixel
Das funktioniert so allerdings noch nicht im Internet Explorer 6. Es gibt mehrere Möglichkeiten, dieses Problem zu umgehen. Die beiden verbreitetsten sind, gar keine PNGs zu verwenden oder aber die PNGs dem Internet Explorer nicht zur Verfügung zu stellen. Wir entscheiden uns dafür, für den Internet Explorer alternativ GIFs zu verwenden. Um dem Internet Explorer die alternative Kost zu servieren, ändern wir bei den beiden vorigen Regeln lediglich die Dateiendungen in .gif ab. Alle anderen Browser inklusive Internet Explorer 7 versorgen wir über Kindselektoren mit den alten PNG-Deklarationen: Abbildung 13-25: klebestreifen-oben.gif, 83 x 67 Pixel
div > div.klebestreifen.oben { background: url(bilder/klebestreifen-oben.png); } div > div.klebestreifen.unten { background: url(bilder/klebestreifen-unten.png); }
Abbildung 13-26: klebestreifen-unten.gif, 86 x 54 Pixel
108
Das sieht nun nicht mehr ganz so schön aus, funktioniert aber trotzdem gut.
Teil II: Listen und Menüs
Finale Den Abschluss stellt folgender Hinweis dar:
Fahren Sie mit der Maus über die Bilder, um eine Vorschau zu erhalten. Ein Klick öffnet das Bild dann in Druckqualität.
Wir würden diesen Hinweis nicht unbedingt benötigen, wenn unser Fotoalbum so populär wäre, dass es bereits einer Konvention entsprechen würde, und wenn wir es ausführlich auf Schwächen hinsichtlich der Benutzerfreundlichkeit getestet hätten. Wir positionieren nun den Absatz 65 Pixel von links, um den Innenabstand des Elternelements zu kompensieren, sowie 310 Pixel von oben. Um das nicht wiederholte Hintergrundbild einzutüten, sehen wir 30 Pixel Innenabstand vor. Außerdem legen wir eine Breite von 280 Pixeln fest. Das rundet den Hinweistext und auch das Album selbst ab. p { background: url(bilder/pfeil.gif) no-repeat; left: 65px; padding-left: 30px; position: absolute; top: 310px; width: 280px;
In einer weiteren Navigation setzen wir Douglas Bowmans Technik aus »Sliding Doors« ein. Ja, sie ist nicht die jüngste Methode, aber das ändert nichts daran, dass sie funktioniert und einfach in unseren Werkzeugkasten gehört. Vielmehr dürfen wir sogar mit einem Augenzwinkern hinzufügen, dass unser Design dabei nicht nur besser aussehen, sondern auch eleganter geschrieben sein wird.
14 Schwierigkeitsgrad: einfach
Abbildung 14-1: Navigation »08/15«
113
Da wir das Pferd auch hier wieder von hinten aufzäumen, beginnen wir mit ein paar einführenden und leicht nachvollziehbaren Regeln. html { background: #F1D34D url(bilder/hintergrund.jpg) repeat-x; color: #000; font: 75%/1.3 georgia, serif; }
Abbildung 14-2: hintergrund.jpg, 20 x 65 Pixel
Das sorgt für klare Verhältnisse: einen orangefarbenen Hintergrund mit einem nur horizontal verlaufenden Hintergrundbild (zur Illustration in einer Breite von 20 statt 1 Pixel), eine schwarze Schriftfarbe und eine etwas verkleinerte Schrift in Form von Georgia. Was brauchen wir an Markup für eine Navigation? Normalerweise eine Liste.
In erster Instanz entfernen wir die Listenmarker und lassen die li-Elemente fließen, da wir sie horizontal anordnen möchten. ul { list-style: none; } li { float: left; }
Bevor wir die Liste an die gewünschte Position bugsieren, widmen wir uns den einzelnen Menüpunkten. Douglas Bowmans Ziel ist es, Menüpunkte (oder auch andere Elemente) links und rechts abzurunden, ohne dass man die Breite der jeweiligen Elemente kennen und damit entweder immer dasselbe Hintergrundbild oder immer exakt zugeschnittene Bilder verwenden muss. Seine Methode basiert darauf, den enthaltenen Links sowie den Elternelementen einen Hintergrund zu spendieren, wobei das Elternelement (li) eine Seite und damit eine Abrundung abdeckt, während der Link die andere Seite sowie den eigentlichen Inhalt abdeckt. Wir erweitern also entsprechend die Zuweisungen für unsere li-Elemente:
Das ist der erste Schritt. Unser großzügig ausgelegter und damit auch deutliche Textvergrößerungen tolerierender Hintergrund wird als nicht wiederholtes Bild eingebunden. Die Breite des Hintergrundbildes wird auch als Innenabstand definiert, damit es »sicher« ist und nicht mit dem im nächsten Schritt definierten Hintergrund auf dem a-Element kollidieren kann. Die Navigationslinks brauchen jetzt im Grunde nur zwei Deklarationen, um unseren Effekt erzielen zu können: ein weiteres, oben rechts angelegtes Hintergrundbild sowie die Anweisung, dass es den vollen Platz beanspruchen, also ein Block-Element sein soll. li a { background: url(bilder/tab-rechts.gif) no-repeat top right; display: block; }
Abbildung 14-4: tab-rechts.gif, 400 x 300 Pixel
Auch hier ist das Hintergrundbild sehr großzügig ausgelegt, offeriert uns dafür aber auch genug Platz, um nach Belieben die Schriftgröße zu skalieren, ohne dass das Layout »kaputtgeht«. Mit beiden Schritten lässt sich die Technik im Wesentlichen erklären. Um ansprechend auszusehen, müssen wir aber noch etwas nachlegen. Die wichtigste Rolle spielt dabei ein moderater Innenabstand, der den Abstand kompensiert, den wir links schon über li erzielt haben. li a { color: #666; font-weight: bold; padding: 5px 14px 3px 5px; text-decoration: none; }
Kapitel 14, Navigation »08/15«
115
In unserem Fall »überkompensieren« wir, wir legen also sowohl rechts (14 Pixel) als auch links (5 Pixel – die Differenz entspricht der linken Aus sparung) nach. Begleitet wird diese Modifikation durch eine andere Link farbe (Grau), Fettung der Schrift sowie das Wegnehmen der Textunter streichung. Anschließend wünschen wir sowohl einen Effekt beim »Hovern« der Links – dafür bestehen die Bilder aus zwei »Phasen« – als auch das »Einfrieren« genau dieses Effekts, wenn der jeweilige Menüpunkt ausgewählt wurde. Für Letzteres erzeugen wir eine ID, aktiv:
Spätestens an dieser Stelle weichen wir von dem Weg ab, den Bowman beschreitet. Dieser sieht ebenfalls eine solche Hervorhebung vor, allerdings versieht er jeden Menüpunkt mit einer ID (in diesem Fall zum Beispiel navprojekte), um dann dem body-Element auch eine ID zu geben, wenn die aufgerufene Seite zu diesem Bereich gehört. Um das entsprechende Styling zu erzielen, verwendet er dann einen auf den Kontext bezogenen Selektor, um eine Hervorhebung zu erreichen. In unserem Beispiel könnte das etwa #projekte #nav-projekte sein. Da wir einfach einmal voraussetzen, dass das Setzen der aktiv-ID möglich ist, vereinfachen wir unseren Code entsprechend. Da der Effekt wie auch die Kennzeichnung »aktiver« Bereiche in derselben Visualisierung resultieren sollen, können wir die Selektoren kombinieren: li:hover, li#aktiv { background-position: 0 -150px; border-bottom: 0; } li:hover a, li#aktiv a { background-position: 100% -150px; color: #000; padding-bottom: 4px; }
Bei beiden Regeln bestimmt die erste Deklaration, dass das bereits gesetzte Hintergrundbild einfach um 150 Pixel nach oben verschoben wird – genau um die Hälfte der eigentlichen Bildgröße, so dass wir den unteren, weißen Bereich der Bilder sichtbar machen. Denselben Kniff verwenden wir auch in Kapitel 10, »Blog-Navigation«, und in Kapitel 24, »Image-Map«. Wir sparen uns so die ärgerliche Verzögerung, die sonst bei der Verwendung alternativer Bilder durch deren Ladezeiten auftreten würde. Bei den Listenelementen blenden wir den Rahmen nach unten aus, was wir aber durch einen erhöhten Innenabstand der Links geschickt ausbalancieren. Die optische Unterstreichung, die zum einen durch den htmlHintergrund und zum anderen durch den Listenrahmen erzeugt wird, wird so unterbrochen, da der Link des betroffenen Elements eine Lücke schafft, der Reiter also wie zum Inhalt gehörend erscheint. 116
Teil II: Listen und Menüs
Die Änderung der Linkfarbe verdient noch eine Randnotiz. Der Internet Explorer kann bis zur Version 7 mit der :hover-Pseudoklasse nur etwas im Zusammenhang mit Links anfangen, wir haben diese aber einfach auf li angewendet. Tragisch ist dieses Vorgehen nicht, die Hervorhebung des jeweils aktiven Punkts funktioniert dennoch. Das Einzige, was wir noch tun könnten, um diese Problematik zu berücksichtigen, ist es, die Schrift zumindest zu ändern, wenn die Maus über Links fährt: li a:hover { color: #000; }
Bringen wir schließlich noch die Liste selbst in Stellung. Ein Außenabstand und eine angepasste Zeilenhöhe genügen, um Opera-Differenzen zu um schiffen. ul { line-height: 1.25; margin: 40px 20px; }
Jetzt sind wir fertig – fast. Wir wollen noch eine Kleinigkeit ergänzen. In dem Bereich, in dem die Listenelemente den linken Reiterabschnitt beschreiben, erhalten wir zwar einen schönen Effekt, der Mauszeiger entspricht aber dem Standard-Cursor. Das ist zwar korrekt, da in diesem kleinen Bereich auch gar kein Link vorliegt, kann aber seltsam anmuten. Über die cursor-Eigenschaft können wir das ändern: li { cursor: pointer; }
Warnung
Wir müssen uns dabei aber darüber im Klaren sein, dass das zu erheblichen Irritationen führen kann; der Cursor lädt schließlich zum Klicken ein. Wir ergänzen die Regel also rein spaßeshalber und genießen sie mit Vorsicht.
CSS-Überblick Da wir einige Regeln nachträglich erweitert und zudem gar nicht so viel Code im Stylesheet benötigt haben, fassen wir es noch einmal zusammen: * { margin: 0; padding: 0; } html { background: #F1D34D url(bilder/hintergrund.jpg) repeat-x; color: #000; font: 75%/1.3 georgia, serif; } ul { line-height: 1.25; list-style: none; margin: 41px 20px; }
Kapitel 14, Navigation »08/15«
117
li { background: url(bilder/tab-links.gif) no-repeat; border-bottom: 1px solid #000; cursor: pointer; float: left; padding-left: 9px; } li:hover, li#aktiv { background-position: 0 -150px; border-bottom: 0; } li:hover a, li#aktiv a { background-position: 100% -150px; color: #000; padding-bottom: 4px; } li a { background: url(bilder/tab-rechts.gif) no-repeat top right; color: #666; display: block; font-weight: bold; padding: 5px 14px 3px 5px; text-decoration: none; } li a:hover { color: #000; }
Referenzen • Douglas Bowman: »Sliding Doors of CSS, Part II« http://www.alistapart.com/articles/slidingdoors2/
118
Teil II: Listen und Menüs
Themennavigation
Vom Kommunikationsdienst GMX haben wir die Erlaubnis erhalten, auch einmal anhand seiner Subnavigation die Vorzüge eines anspruchsvollen und auf der Basis von Cascading Style Sheets realisierten Designs zu illustrieren. Wir sind von der Umsetzung überzeugt und werden die Subnavigation von GMX nachbauen und aufzeigen, warum welcher Weg beschritten wurde.
15 Schwierigkeitsgrad: mittel
Abbildung 15-1: Themennavigation
119
Im Vorfeld einige Anmerkungen: Wir haben das Stylesheet von GMX zurechtgestutzt, so dass nur die unbedingt notwendigen Regeln und Deklarationen verwendet werden. Die Subnavigation zeichnet sich eigentlich dadurch aus, dass durch die Änderung einer einzigen Klasse (darauf kommen wir noch zurück) das Gesamtbild der ganzen Navigation verändert wird. Doch diese Flexibilität bilden wir hier nicht ab. Das meiste lassen wir unverändert, wodurch sicherlich ein, zwei Unter schiede zu den übrigen Beispielen in diesem Buch auszumachen sind. Auf der einen Seite betrifft das die Benennung der Bilder, auf der anderen Seite die von Klassen, denn GMX verwendet für beides englischsprachige Bezeichner. Zudem weicht der Gebrauch von Selektoren etwas voneinander ab: Wie zu Beginn dieses Buchs erwähnt, verwenden wir zur Verdeutlichung eher Selektoren der Art div#nav-sub statt #nav-sub. Auch die Verwendung von einzelnen Werten ist unterschiedlich, so wie bei der fontweight-Eigenschaft, wo GMX den Wert 700 bold vorzieht. GMX setzt wie wir gleich zu Beginn die Innen- und Außenabstände pauschal zurück. Die Schrift und die Farben werden über das html-Element vorgegeben. * { margin: 0; padding: 0; } html { background: #C1D2EC; color: #000; font: 400 11px/14px verdana, arial, helvetica, sans-serif; }
Das Haar in der Suppe: Die Angabe in Pixeln verhindert, dass die Schriftgröße im Internet Explorer 6 vom Benutzer verändert werden kann Wir benötigen nun den HTML-Code. Die Navigation wird korrekterweise als Liste bzw. – zur Abbildung der Hierarchie – als mehrere verschachtelte Listen umgesetzt, die zur Kennzeichnung der Ebene und als spätere Basis für Selektoren mit den Klassen l1 bis l4 versehen werden. GMX verwendet Klassen anstelle von IDs, da diese auf der Homepage noch um eine Klasse home ergänzt werden (dort ist die Formatierung etwas anders) und da auf einer Seite grundsätzlich auch mehrere, parallel stehende Listen verwendet werden. (Es gibt im Themen-Bereich beispielsweise noch eine zweite Navigationsliste, die zusätzliche Dienste enthält und von uns ausgespart wird.)
Es ist anzumerken, dass wir bei dieser »Standalone«-Version der Navigation den äußeren div-Container nicht unbedingt benötigen. Wir behalten ihn aber an Bord, um möglichst wenig zu verfälschen. Der Menüpunkt »1. Bundesliga« wird durch ein strong-Element semantisch betont, er stellt den derzeit ausgewählten Eintrag dar. Die Formatierung beginnt damit, die Breite des Containers zu definieren und keine Punkte vor die Liste zu stellen, wobei über den Kontext (#nav-sub ul) vorgegangen wird. #nav-sub { width: 130px; } #nav-sub ul { list-style: none; }
Die Navigationslinks sollen, um den kompletten durch die li-Elemente offerierten Raum auszunutzen, Block-Elementen entsprechen, und sie sollen nur beim »Hovern« unterstrichen sein.
Ohne bisher die Hintergrundbilder gesetzt zu haben, werden nun die einzelnen Hierarchie-Ebenen gestaltet. Der Ansatz ist dabei der, dass von oben nach unten spezifiziert wird und die unteren Levels »geerbte« Deklarationen bzw. deren Werte »überschreiben«. Gut erkennbar ist das unter anderem daran, dass von den Linkzuweisungen der Ebenen l1 bis l4 immer wieder ein neuer Innenabstand gesetzt wird, um eine Höhe zu erreichen, die an die im Anschluss folgenden Hintergrundbilder angepasst ist. Die ab l2 definierte height-Eigenschaft entspricht der auf dem html-Element definierten Zeilenhöhe und kann gewissermaßen als »Sicherheitsmaßnahme« verstanden werden. #nav-sub .l1 li a { color: #FFF; font-weight: 700; padding: 9px 0 8px 7px; text-transform: uppercase; } #nav-sub .l2 li a { font-weight: 400; height: 14px; padding: 5px 0 3px 7px; text-transform: none; } #nav-sub .l3 li a { color: #244E7E; height: 14px; padding: 4px 0 2px 14px; } #nav-sub .l4 li a { font-size: 9px; height: 9px; line-height: 10px; padding: 4px 0 2px 20px; }
Die vorgenommenen Einstellungen berücksichtigen bereits die einzubeziehenden Hintergrundbilder. Das erkennt man nicht nur an den Maßen, sondern auch an den Farben: Die Links der ersten und zweiten Ebene sollen weiß sein, während die darunter liegenden blau dargestellt werden. Nun werden die Hintergrundbilder der li-Elemente explizit angewiesen, sich nicht zu wiederholen. Das könnte schon allein aufgrund der transparenten Abrundung des letzten Containers (end) unschön sein. 122
Teil II: Listen und Menüs
Eine Eigenschaft von Gewicht
Die font-weight-Eigenschaft font-weight ist sicherlich eine der populäreren CSS-Eigenschaften. Die meisten Webdesigner und Webentwickler verwenden sie mit den Werten normal und bold. Die CSS-Spezifikation sieht jedoch noch zwölf weitere Werte vor: bolder, lighter, 100, 200, 300, 400, 500, 600, 700, 800, 900 und inherit. Interessant sind vor allem die Zahlenwerte, sie geben die Gewichtung der Schrift an, wobei jede Ausprägung mindestens genauso dunkel wie ihr Vorgänger sein muss. Zwar verfügt nicht jede Schrift über ein Äquivalent zur jeweiligen Zahl, sicher verwendbar sind aber die Werte 400 und 700, die den Schlüsselwörtern normal und bold entsprechen. GMX geht diesen Weg, während wir in diesem Buch auf Verständlichkeit setzen und daher auf die Zahlenwerte verzichten.
#nav-sub li { background-repeat: no-repeat; }
Die Hintergrundbilder selbst sind nur eine Formalität: #nav-sub .l1 .topic { background-image: url(bilder/bg-topic-level1.gif); } #nav-sub .topic .l2 li { background-image: url(bilder/bg-topic-level2.gif); }
Abbildung 15-2: bg-topic-level1.gif, 130 x 31 Pixel
Abbildung 15-3: bg-topic-level2.gif, 130 x 27 Pixel
#nav-sub .topic .l3 li { background-image: url(bilder/bg-topic-level3.gif); } #nav-sub .topic .l4 li { background-image: url(bilder/bg-topic-level4.gif); }
Beim nun folgenden Abschluss der Navigation wird etwas von der von GMX geforderten Flexibilität verdeutlicht. Während wir eigentlich nur eine Regel für das mit der Klasse end versehene div-Element definieren würden, verwendet GMX in diesem Fall zwei Regeln: eine für die generellen Zuweisungen und eine weitere, topic-spezifische Regel. Das ergibt sich daraus, dass GMX nicht nur für diesen, sondern auch für andere Bereiche Zuweisungen benötigt. So erhält zum Beispiel der Shopping-Channel über die Klasse shopping einen wiederum anders visualisierten Abschluss.
Abbildung 15-4: bg-topic-level3.gif, 130 x 22 Pixel
Abbildung 15-5: bg-topic-level4.gif, 130 x 18 Pixel
GMX verwendet die erste Regel generisch, also für alle in der Subnavigation aufgehängten Container mit der Klasse end, um dann je nach Kontext bzw. Bereich – hier topic – das entsprechende Hintergrundbild zu setzen. Die Regeln für die Menüpunkt-Hintergründe haben aus dieser Perspektive ebenfalls mehr Sinn, denn wir könnten bei unserem Markup dasselbe Resultat erzielen, wenn wir #nav-sub und die topic-Klasse weglassen würden. Das von GMX verwendete Design und seine Umsetzung sind interessant. Die Hierarchie der Liste wird geschickt kommuniziert, und ihr Code mutet erst komplex an, stellt sich dann aber als einfach heraus, wenn es darum geht, Designs erweiterbar zu gestalten. Der Aufbau des Codes ermöglicht es, durch Hinzufügen einiger weniger hintergrundbezogener CSS-Regeln (wie zuletzt beim Hintergrundbild für das Navigationsende) und durch simples Ändern einer Klasse im Markup (zum Beispiel shopping anstelle von topic) die gesamte Darstellung anzupassen. Anmerkung zur 2. Auflage: GMX hat seine Subnavigation im April 2007 einer Überarbeitung unterzogen. Während sich dabei das Aussehen geändert hat (leider kann es aus rechtlichen Gründen hier nicht im neuen Design dargestellt werden), ist das HTML zumindest im Dienstbereich, also dem Bereich, den man als eingeloggter Benutzer wahrnimmt, unverändert geblieben. Was für ein wunderbares Beispiel für HTML, das wiederverwendet werden kann und das nur mittels CSS in neuem Glanz erscheint.
Referenzen • CSS-Spezifikation: Die font-weight-Eigenschaft http://www.w3.org/TR/CSS21/fonts.html#font-boldness Mit freundlicher Genehmigung der GMX GmbH München, www.gmx.de.
124
Teil II: Listen und Menüs
Veranstaltungskalender
In diesem Kapitel wollen wir uns mit Mikroformaten beschäftigen, einem in den letzten ein, zwei Jahren immer populärer gewordenen Thema. In diesem Sinne ist die Zuordnung in den Bereich »Listen und Menüs« eigentlich nicht ganz richtig – wir werden zwar auch Listen einsetzen, aber nur sekundär.
16 Schwierigkeitsgrad: einfach
Abbildung 16-1: Veranstaltungskalender
125
Das vorliegende Design stellt einen Veranstaltungskalender dar. Dafür gibt es mit hCalendar ein Mikroformat, das uns einige Rahmenbedingungen in Form von Klassennamen vorgibt (siehe Kasten »Mikroformate«).
Vorgegebenes HTML
Abbildung 16-2: logo.gif, 57 x 52 Pixel
Veranstaltungen im Dezember
…
6.12. bis 10.12.2007:
Weihnachten und der Mittelstand
Diskussionstage rund um mittelständische Unternehmen.
Die Außenstruktur bilden wir über ein div-Element als Container, ein h1Element als Überschrift und ein Bild oder Logo des Veranstalters ab. Im Inneren folgt eine Auflistung der in diesem Fall für Dezember geplanten Veranstaltungen, mit dem Einsatz von hCalendar-Markup: • vevent: Damit kennzeichnen wir jedes li-Element (mit Ausnahme des
letzten Elements »Alle Veranstaltungen«), um auszudrücken, dass es sich um ein Ereignis, eine Veranstaltung handelt. • dtstart/dtend: Diese beiden abbr-Elemente werden zur Hervorhebung von Start- und End-Zeitpunkt verwendet. Der Einsatz von abbr macht
Sie stutzig? Richtig, eigentlich ist es – vor allem bei ausführlichem Inhalt (wie »6. Dezember«) – semantisch nicht korrekt. Dazu folgen aber Probleme in Screenreadern, die den Wert des title-Attributs vorlesen: Liegt dort gar eine ISO-Datumsangabe vor, ist dies für den Benutzer nahezu unverständlich. In den Referenzen finden Sie einen weiterführenden Artikel zum Thema (»hAccessibility«). • summary: Titel bzw. Zusammenfassung des Ereignisses. • description: Beschreibung. • location: Ort.
126
Teil II: Listen und Menüs
Unter der Lupe
Mikroformate Mikroformate definieren eine bestimmte Semantik – weitestgehend über vordefinierte Klassennamen – für Inhalte und Funktionen, für die die aktuellen (X)HTML-Spezifikationen keine Elemente kennen. Beispiele für solche Elemente und Funktionen sind Adressbucheinträge und Kontaktinformationen (via hCard), Kalender und Veranstaltungen (via hCalendar) oder soziale Beziehungen (via XFN, »XHTML Friends Network«). Durch das vorgefertigte Vokabular müssen Seitenautoren das Rad nicht jedes Mal neu erfinden und sie können zudem besondere Informationen auch automatisch verarbeiten. Im Fall von hCalendar kann zum Beispiel ein Bot oder eine Browser-Erweiterung (wie die Firefox-Erweiterung »Operator«, siehe Referenzen) »erkennen«, dass eine Seite Veranstaltungsinformationen bietet, und diese dann besonders hervorheben, die Informationen speichern oder in anderer Form verarbeiten. Im Fall von hCard kann ein entsprechen des Widget dem Seitenbesucher die Möglichkeit geben, Kontaktdaten gleich ins eigene Adressbuch zu überführen.
Freies CSS Die Formatierung ist gegenüber dem stark vorgegebenen HTML – und IDund Klassen-Namen zählen wir sicherlich dazu – nun wieder frei. Und wir können entsprechend aufspielen: html { background: #252525; color: #000; font: 75%/1.4 verdana, arial, helvetica, sans-serif; }
Dunkler Hintergrund, dunkle Schriftfarbe, 12 Pixel Verdana als Schrift. Der Grund, warum uns dunkle Schrift auf dunklem Grund nicht auf die Füße fällt, erschließt sich über das div-Element: div { background: #E7E7E7 url(bilder/abrundung-oben.gif) no-repeat; padding-top: 3px; position: relative; width: 317px; }
Dem div-Außencontainer erlegen wir nämlich auf, einen hellen Hintergrund zu verwenden, und jede (dunkle) Schrift kommt hier zum Tragen. Außerdem sorgen wir für eine Abrundung nach oben, in der einfachsten Form über ein einziges Hintergrundbild. Dieses Vorgehen ist einfach, hat aber grund-
Kapitel 16, Veranstaltungskalender
Abbildung 16-3: abrundung-oben.gif, 317 x 3 Pixel (hier vergrößert dargestellt)
127
sätzlich den Nachteil, dass so etwas mehr oder minder (je nach Breite) die Skalierbarkeit einschränkt. Die gewählten 317 Pixel, die wir als Breite des div-Containers vorgeben, schaffen jedoch noch einige Stufen Spielraum. Mit einem Innenabstand nach oben sichern wir dem Hintergrundbild ausreichend Raum zu. Zudem leitet die relative Positionierung wunderbar zu den nächsten beiden Elementen über, nämlich der h1-Überschrift und dem Veranstalterlogo: h1, h2 { font-size: 1em; } Hinweis
Mit letter-spacing lassen sich zwar theoretisch schöne Schrift anpassungen und ‑effekte erzielen, dies ist aber aus typografischer Sicht nicht wirklich trivial. In der Regel profitiert man am ehesten vom StandardBuchstaben-Kerning, setzt letter-spacing also besser spärlich ein.
Der h1-Überschrift und auch gleich allen h2-Überschriften weisen wir eine Schriftgröße von 1em (in unserem Fall also 12 Pixel) zu. Ebenso sind auch die weiteren Überschriftenregeln leicht nachvollziehbar, mit blauem Hintergrund und weißer Farbe, mangelnder Fettung über font-weight und einem Außenabstand nach oben und links. Eine Prise letter-spacing, also Abstand zwischen den Buchstaben, rundet das Ganze ab. Der h1-Innenabstand ist wie die relative Positionierung des div-Elements wegbereitend für den Einsatz des Logos: Wir positionieren über die Überschrift. Dazu verwenden wir einen h1-Innenabstand von 77 Pixel nach links und setzen dort das Bild mit 10 Pixel Abstand nach links sowie 6 Pixel nach oben ein. Der Grund für einige der Pixelangaben ist wieder die Skalierbarkeit – mit em -Angaben würde das Bild bei einer Schriftvergrößerung »mit durch die Gegend wandern«, und angesichts des eingeschränkten Platzangebots wäre das nicht gerade dienlich. Wir verdrahten manche Größen und Abstände also bewusst, um den eigentlichen Inhalten mehr Platz einzuräumen. Nähern wir uns der Liste mit den Veranstaltungen:
Abbildung 16-4: schatten.jpg, 132 x 17 Pixel
128
ol { background: url(bilder/schatten.jpg) top right no-repeat; list-style: none; padding-top: 1.5em; }
Teil II: Listen und Menüs
Mit einer Durchnummerierung können wir hier nichts anfangen und blenden sie deshalb via list-style: none; aus. Den unter der h1-Überschrift erscheinenden Schatten können wir relativ simpel anbringen, indem wir ihn auf der Liste als Hintergrundbild einbinden, und zwar rechts oben und nicht wiederholt. Das ist vor allem deshalb einfach, weil wir das im Weg – zwischen Überschrift und Liste – stehende »Logo« durch die Positionierung aus dem »Fluss« genommen haben, die Liste jetzt also direkt an die Überschrift grenzt. Mit einem Innenabstand nach oben erhalten wir optisch dennoch Platz zwischen der Überschrift und den Listen-Inhalten. Nachdem uns das Mikroformat-HTML anfangs etwas beschäftigt hat, sieht das bei seinem Styling etwas leichter aus. Dass wir mehrere Klassen einsetzen, heißt nicht, dass wir sie auch benutzen müssen. In unserem Fall ist die Gestaltung der Veranstaltungen weniger anspruchsvoll – aber deshalb nicht unbedingt unterfordernd. Das uns vorschwebende Design sieht vor, dass Beschreibung und Ort der Veranstaltung nicht einzelne Zeilen oder Absätze beanspruchen, sondern hintereinander folgen. Dennoch haben wir uns im HTML-Markup für Absätze (und nicht für span-Elemente) entschieden, weil zumindest die Beschreibungen prinzipiell mehrere Sätze umfassen könnten. p { display: inline; }
Warum das nun keinen Einfluss auf die Darstellung des jeweils ersten Absatzes mit den Start- und End-Daten hat? Das erklärt sich leicht, wenn man die Spezifikation im Auge hat. Unser Fall sieht verkürzt so aus:
Wir machen hier zwar alle Absätze zu Inline-Elementen, die Überschrift jedoch ist ein Block-Element und erzeugt deshalb vor und hinter sich einen Zeilenumbruch. Nun bewegen sich aber auch die p-Elemente in einem sogenannten »Blockformatierungskontext«, so dass das p-Element vor der h2Überschrift ein »anonymes« Block-Element darstellt, ebenso wie die beiden darauffolgenden Absätze einen »anonymen« Block bilden (und nicht zwei Blöcke, da sie ja trotzdem »inline« dargestellt werden). Jetzt haben wir nur noch zwei Wünsche: mehr Innenabstand für die veventElemente und keine Rahmenlinie unter den Datumsangaben. li.vevent { padding: .6em 1em .6em 2em; } abbr { border: 0; }
Kapitel 16, Veranstaltungskalender
129
Mehr los in unserer Stadt Das Finale stellt der Link »Alle Veranstaltungen« dar – wenn wir das bisher Erreichte betrachten, scheint der Abschluss des Kalenders etwas unglücklich. li a { color: #000; text-decoration: none; }
Mit schwarzer Farbe und fehlender Unterstreichung (das muss nicht die glücklichste Entscheidung sein, da der Link nun schwerer als solcher erkennbar ist) gliedern wir den Link etwas ins restliche Erscheinungsbild ein. li a { background: url(bilder/abrundung-unten.gif) bottom no-repeat; display: block; height: 2.7em; padding: .9em 1em 0 2em; }
Abbildung 16-5: abrundung-unten.gif, 317 x 36 Pixel
Wir wenden hier einen kleinen Trick an, um ohne zusätzliches HTML die Abrundung unten zu erzielen. Leider können wir weder auf unserem div- noch auf dem ol-Element ein weiteres Hintergrundbild definieren. Die Angabe mehrerer Hintergrundbilder ist zwar in CSS 3 vorgesehen, bisher aber kaum implementiert. Folglich benutzen wir für die Abrundung unten unseren Link: Wir machen ihn zu einem Block-Element, so dass er die gesamte Breite beansprucht (absichtlich sehen weder die Liste noch das letzte Listenelement einen Abstand vor), und weisen ihm das gewünschte Hintergrundbild, eine Höhe sowie einen Innenabstand zu. Schlussendlich wünschen wir noch einen kleinen Effekt, wenn dieser Link aktiviert wird, mit einem anderen Bild und weißer Farbe: li a:focus, li a:hover, li a:active { background-image: url(bilder/abrundung-unten-alt.gif); color: #FFF; }
Abbildung 16-6: abrundung-unten-alt.gif, 317 x 36 Pixel
Nun dürfen wir auch auf die beworbenen Veranstaltungen gehen. 130
Referenzen • Mikroformate http://microformats.org/ • Mikroformate: hCalendar http://microformats.org/wiki/hcalendar • Bruce Lawson und James Craig: hAccessibility http://www.webstandards.org/2007/04/27/haccessibility • Firefox-Add-on »Operator« https://addons.mozilla.org/de/firefox/addon/4106 • CSS-Spezifikation: Blockformatierungskontext http://www.w3.org/TR/CSS21/visuren.html#q15
132
Teil II: Listen und Menüs
Formulare und Tabellen
Im nun anstehenden Teil III liegt der Fokus auf den unterschiedlichen Möglichkeiten, Formulare über CSS zu gestalten, und auf den Feinheiten bei der Arbeit mit tabellarischen Daten. Durchaus anspruchsvolle Designvorgaben führen in diesem Teil zu einer größeren Komplexität von Markup wie auch Stylesheets.
III In diesem Teil 17 Vergleichstabelle 18 Balkendiagramm 19 Newsletter-Formular 20 Kommentar-Formular 21 Forenregistrierung 22 Periodensystem der Elemente 2 3 Bundesligatabelle
133
Vergleichstabelle
Auch wenn es in der Diskussion um »tabellenloses CSS-Design« manchmal etwas untergehen mag: Eine Website darf durchaus Tabellen enthalten, wir möchten jedoch vermeiden, dass diese für reine Layoutzwecke missbraucht werden. Wo jedoch eine Auflistung von Daten dargestellt werden soll, ist eine Tabelle notwendig und richtig. Und mit CSS kann man sie sogar ziemlich gut aussehen lassen.
17 Schwierigkeitsgrad: einfach
Abbildung 17-1: Vergleichstabelle
135
Als Beispiel dient uns eine Aufstellung von technischen Daten fiktiver Digitalkameras. Wir vergleichen sechs verschiedene Modelle anhand von Megapixel-Anzahl, unterstützten Speicherkarten, optischem Zoom und natürlich dem Preis. Als Abschluss setzen wir eine Fußzeile, die die jeweiligen Durchschnittswerte angibt. Das Besondere an unserer Lösung: Die Tabelle ist elastisch – Höhe und Breite richten sich nach der eingestellten Schriftgröße. Verändert man diese mit entsprechenden Befehlen im Browser, wächst die gesamte Tabelle mit. Eine schwierige Aufgabe für den Designer? Eigentlich nicht, wenn man weiß, wie es funktioniert.
Von Kopf bis Fuß: Die Tabellenstruktur Das wissen auch viele erfahrene Webdesigner und Webentwickler nicht: Eine Tabelle kann eine ziemlich ausgefeilte, semantische Struktur besitzen. Üblich ist etwa Folgendes:
…
…
Pragmatisch betrachtet, würde das auch ausreichen. Doch es genügt uns nicht. Wenn wir nämlich nachschlagen, was es für erweiterte Möglichkeiten gibt, um innerhalb einer Tabelle für Struktur zu sorgen, kommen die Elemente thead, tfoot und tbody ins Spiel. Sie definieren die Bereiche, in denen sich die Kopfzeile, die Fußzeile und die regulären Tabellenzeilen befinden. Dabei ist die Reihenfolge etwas verwirrend. tfoot soll nämlich im Quelltext vor tbody platziert werden, obwohl es bei der Bildschirmausgabe ganz am Ende der Tabelle erscheint. Wir erweitern die Struktur entsprechend:
…
…
136
Teil III: Formulare und Tabellen
…
Man beachte, dass innerhalb der thead- und tfoot-Elemente die einzelnen Zellen mit th gekennzeichnet sind, da man sie semantisch als Spaltenüberschriften verstehen muss. Innerhalb von tbody sind es dann die »normalen« td -Elemente. Außerdem haben wir noch eine kurze Zusammenfassung als summary-Attribut hinzugefügt. Ganz bewusst gibt es hier keine Tabellenüberschrift caption. Beim Styling dieses Elements verhalten sich die Browser nämlich dermaßen unterschiedlich, dass wir lieber ganz darauf verzichten und eine normale Überschrift h1 vorziehen. In anderen Teilen des Buchs gibt es aber Beispiele, wo wir die caption dennoch heranziehen oder sie definieren, aber ausblenden. Der gewünschte dünne Rahmen um die Tabelle zwingt uns außerdem dazu, ein zusätzliches div-Element zu verwenden, das die ganze Tabelle umfasst. Denn leider lassen sich Innenabstände und Rahmen nicht besonders gut an das eigentliche table-Element anfügen, weil dabei abermals Schwierigkeiten in diversen Browsern auftreten. Die gekürzte Gesamtstruktur sieht dann so aus:
Digitalkameras im Vergleich
… … …
Das Styling Zunächst folgen einige grundlegende Einstellungen für die Elemente html und body: eine globale Schriftgröße und Schriftfarbe sowie ein wenig Abstand zum Rand des Browserfensters. html { font: 68.75%/1.2 'trebuchet ms', arial, helvetica, sans-serif; }
Kapitel 17, Vergleichstabelle
137
body { color: #444; padding: 20px; }
Nun das div-Element, das die Tabelle umschließt. Ein einfacher Rahmen, der mit einem Innenabstand von 3 Pixeln die Tabelle ziert, ist schnell angelegt und bedarf keiner großartigen Erklärung. div { border: 1px solid #712F86; padding: 3px; width: 60em; }
Interessanter wird es bei der Breite. Da unsere Tabelle proportional zur Schriftgröße mitwächst, bekommt sie einen Wert, der von der aktuellen Schriftgröße abhängig ist: 60em. Das entspricht ungefähr 60-mal der Breite des großen M. Jedenfalls lautet so die Definition – doch natürlich ist das nur ein Richtwert. Sie merken schon: Das wird mit Sicherheit kein pixelgenaues CSS-Design. Aber das soll es auch gar nicht sein. Wir schließen das Styling des »Außenbereichs« ab, indem wir uns das eigentliche table-Element vornehmen. table { border-collapse: collapse; table-layout: fixed; }
Diese beiden eher weniger bekannten CSS-Eigenschaften sind ungemein wertvoll, um Tabellen sauber und ordentlich aussehen zu lassen. Mit border-collapse: collapse; verhindern wir, dass der Browser zwischen zwei Tabellenzellen stets einen Zwischenraum und einen doppelten Rahmen anzeigt. Dies wäre der Standard in HTML, ist jedoch meist eine Beleidigung für die Augen. Eigentlich ist es sogar die logische Vorgehensweise – schließlich kann jede einzelne Zelle oben, unten, links und rechts einen Rahmen erhalten. Doch wenn wir die Rahmen wie beschrieben »einstürzen« lassen, wird der Zwischenraum entfernt und die zwei aneinander stoßenden Rahmen werden zu einem einzigen verschmolzen. Die zweite Eigenschaft, die wir definieren, ist table-layout: fixed;. Auch hier setzen wir uns über eine Standardregel hinweg. Normalerweise wird die Breite der einzelnen Spalten, falls ihnen kein bestimmter Wert zugewiesen wird, vom Browser automatisch bestimmt. Er berechnet für jede einzelne Spalte, wie viel Inhalt sich darin befindet, und vergleicht das mit den anderen Spalten. Dann findet er das rechnerisch optimale Verhältnis. Doch das wollen wir nicht. Vielmehr ist es sinnvoll, mit einer Tabelle zu beginnen, bei der alle Spalten gleich breit sind. Genau dafür ist tablelayout: fixed; gedacht. Später werden wir dann die Breite einzelner Spalten exakt definieren.
138
Teil III: Formulare und Tabellen
Bleibt nur noch, auch die Breite der Tabelle auf 60em festzusetzen. Zwar wäre ein Wert von 100% logischer, doch das verleitet bestimmte Browser zur Fehlinterpretation der Breitenangaben innerhalb der Tabelle. table { border-collapse: collapse; table-layout: fixed; width: 60em; }
Verläufe und mehr: Das Tabellen-Innere Gehen wir direkt in den Inhalt der Tabelle. Wie bereits oben beschrieben, besteht sie aus den Zellenelementen th und td. Als Elternelemente fungieren die tr-Zeilen. Diese wiederum befinden sich in den Tabellenabschnitten thead, tfoot und tbody.
Modell
Megapixel
CF-I
CF-II
MMC
SD Card
Mem Stick
opt. Zoom
Preis
Durchschnitt
8,7
1
4
4
5
3
8-fach
€ 330,-
Bihijutshi SC-205
7,1
<span>nein
<span>ja
<span>nein
<span>nein
<span>ja
10-fach
€ 180,-
…
Kapitel 17, Vergleichstabelle
139
Nun machen wir uns an den dazugehörigen CSS-Code. Als Erstes legen wir einige Regeln fest, die für alle Einzelzellen gelten sollen: th, td { border-right: 1px solid white; padding: .7em .4em; text-align: center; }
Der Innenabstand richtet sich nach der Schriftgröße, damit das Verhältnis stets gleich bleibt. Der Text wird zentriert. Außerdem grenzen wir die Zellen mit einem dünnen weißen Rahmen auf der Horizontalen voneinander ab. Weiter geht es mit einigen Styling-Angaben, die ausschließlich die Kopfund Fußzeile betreffen sollen. Dafür verwenden wir den th-Selektor, da dieses Element nur in diesen beiden Zeilen vorkommt. th { background: #9766A7 url(bilder/hintergrund.jpg) repeat-x; color: #FFF; font-weight: normal; letter-spacing: 1px; text-transform: uppercase; }
Abbildung 17-2: hintergrund.jpg, 10 x 120 Pixel
Das sind einige Angaben zu Hintergrund und Schrift. Zuerst setzen wir unsere vorbereitete Grafik hintergrund.jpg ein. Diese besteht aus einem vertikalen Verlauf von (demonstrativ) 10 Pixeln Breite, den wir in horizontaler Richtung wiederholen lassen. Eine Angabe zur Platzierung wird nicht benötigt: Die Grafik setzt standardmäßig links oben an, und falls sich die Höhe der Zeilen vergrößert, ist nach unten genügend Spielraum. Schließlich ist die Grafik ganze 120 Pixel hoch. Außerdem legen wir als Hintergrundfarbe einen Wert von #9766A7 fest. Das entspricht dem Farbwert des untersten Bereichs der Grafik. Sollte die Höhe der Tabellenzeile also wider Erwarten die Höhe der Hintergrundgrafik übersteigen, wird das nicht unangenehm auffallen. Die Angaben zur Schrift sind eher trivial: Weiß soll sie sein, in Versalien gesetzt und ein wenig mehr Laufweite bekommen (weil Versalien dadurch besser lesbar sind). Außerdem wollen wir nicht, dass der Browser, wie bei th-Elementen voreingestellt, automatisch den fetten Schnitt der Schrift einsetzt. Also zurück zu font-weight: normal;. Nun zu den regulären Zellen, den td-Elementen: td { background: #A07BAF url(bilder/hintergrund-zelle.jpg) bottom right no-repeat; border-top: 1px solid #712F86; }
140
Teil III: Formulare und Tabellen
Abbildung 17-3: hintergrund-zelle.jpg, 500 x 85 Pixel
Diese Zellen erhalten eine andere Hintergrundgrafik, nämlich hintergrundzelle.jpg. Sie soll nicht gekachelt werden, ist sie doch ausreichend groß, um auch bei hoher Skalierung die Zellen voll auszufüllen. Wir platzieren sie am rechten unteren Rand, damit der Verlauf zum Weiß immer gleich gut zur Geltung kommt und die Tabelle somit ein wenig räumlich wirken lässt. Auch hier gehen wir jedoch auf Nummer sicher und definieren als Hintergrundfarbe zusätzlich einen zur Grafik passenden Farbton. Ein durchgezogener oberer Rand sorgt abschließend für schicke Über sichtlichkeit.
Symbole statt Text: Image Replacement Nun das »besondere Etwas« unserer Tabelle: die angekreuzten oder ausgeblendeten Kästchen. Die Grafiken dafür werden jedoch nicht etwa über das img-Element in das HTML hineingeschrieben. Wir lösen das viel eleganter per CSS. So können wir die Grafiken an einer zentralen Stelle austauschen, wenn uns ihr Design nicht mehr gefällt. Wenn wir noch einmal den entsprechenden HTML-Code konsultieren, sehen wir, dass es für die beiden Zustände »Kreuz« und »Leeres Kästchen« zwei entsprechende td-Elemente mit unterschiedlichen Klassen und Inhalten gibt:
<span>ja
<span>nein
Dort, wo ein Kreuz erscheinen soll, wird dem Zellenelement eine Klasse ja zugewiesen, für das leere Kästchen setzen wir die Klasse nein. Die ausgeschriebenen Texte »ja« und »nein« sind nützlich für Blinde und Menschen mit einer Sehbehinderung, die mit Screenreader oder Braillezeile unterwegs sind, sowie für Menschen, die mit speziellen Stylesheets arbeiten oder die Stylesheets deaktiviert haben. Wer aber in den Genuss unseres hübschen CSS kommt (und das sind ja die meisten), wird die Wörter »ja« und »nein« nicht wahrnehmen, denn wir verstecken sie und bedienen uns stattdessen einer Hintergrundgrafik, die wir an das span-Element anhängen. td.ja span, td.nein span { background: center center no-repeat; display: block; text-indent: -999em; }
Um den Text zu verstecken, wird ein absurd niedriger Wert als »negativer Einzug« definiert: text-indent: -999em;. Der Textinhalt des Elements wird dadurch so weit nach links verschoben, dass er garantiert aus dem sichtbaren Bereich verschwindet. Da das span-Element naturgemäß ein inline-Element ist, müssen wir es dann noch manuell in ein block-Element umwandeln, sonst funktioniert der negative Einzug nicht. Als Hintergrund setzen wir die entsprechenden Grafiken für »ja« oder »nein« und platzieren sie, natürlich ohne Kachelung, in der Mitte des span-Elements – schließlich ist der Text in den anderen Spalten auch mittig ausgerichtet.
Finetuning am Schluss: Festlegen der Spaltenbreiten Werfen wir noch einmal einen Blick auf den HTML-Code für eine der regulären Tabellenzeilen:
DigiPowerCamera 5s
6,0
<span>nein
<span>ja
<span>nein
<span>ja
<span>ja
3-fach
€ 245,-
Wir möchten, dass die Spalten mit wenig Inhalt schmaler werden als die mit relativ viel Inhalt. Dadurch können wir Platz sparen. Also fügen wir den Klassen ja und nein jeweils noch eine feste Breitenangabe von 4em hinzu. td.ja, td.nein, .speicher { width: 4em; }
Hier haben wir auch gleich die dazugehörigen Zellen in der Kopf- und Fußzeile mit angesprochen. Diese müssen ebenfalls auf 4em gesetzt werden, damit auch wirklich die gesamte Spalte unsere gewünschte Breite annimmt. Wir verwenden dazu die Klasse speicher. (Der dazugehörige HTML-Code wurde bereits weiter vorne gezeigt.) Doch auch die erste Spalte, in der die Namen der Kameramodelle aufgelistet werden, soll eine feste Breite bekommen. Zu diesem Zweck definieren wir, 142
Teil III: Formulare und Tabellen
ähnlich wie weiter oben im Text, eine eigene Klasse namens modell. (Siehe dazu auch den folgenden Infokasten.) Diese Klasse wird mit folgenden Eigenschaften belegt: .modell { text-align: left; width: 15em; }
Nach ein wenig Ausprobieren weisen wir der Tabellenzelle eine feste Breite von 15em zu. Außerdem heben wir die global verordnete Schriftzentrierung wieder auf und richten die Wörter in dieser Spalte linksbündig aus – alles andere sähe seltsam aus. Ein Blick in die Spezifikation
Die :first-child-Pseudoklasse Die im HTML-Code angegebene Klasse modell wäre an dieser Stelle eigentlich gar nicht nötig, wenn alle Browser die CSS-Regeln korrekt verstehen würden. CSS2 stellt eine praktische Pseudoklasse zur Verfügung, die genau für diesen Fall gemacht zu sein scheint, nämlich :first-child. Wir können damit nur das erste td-Element innerhalb eines tr-Elements ansprechen, und zwar so: tr > td:first-child { text-align: left; width: 15em; }
Eine elegante Lösung. Doch wie sooft ist der Internet Explorer 6 nicht in der Lage, diese Angabe zu interpretieren. Sie kommt für uns also leider nicht in Frage.
Unsere Tabelle ist fertig. Der HTML-Quelltext ist verhältnismäßig schlank geblieben, und durch den Einsatz von global definierten CSS-Eigenschaften erreichen wir eine ungeahnte Flexibilität, die es uns ermöglicht, auch massive Modifikationen der Optik allein über das Stylesheet durchzuführen.
Referenzen • CSS-Spezifikation: Die :first-child-Pseudoklasse http://www.w3.org/TR/CSS21/selector.html#first-child
Kapitel 17, Vergleichstabelle
143
Balkendiagramm
Wir haben die Aufgabe bekommen, ein paar Unternehmenszahlen aufzubereiten, allerdings nicht als Excel-Training, sondern auf der Basis von Webstandards. Das ist zwar eine so einfache Angelegenheit, dass wir nicht von zwanzig Manntagen Aufwand ausgehen müssen, aber wir können die Gelegenheit beim Schopfe greifen und noch ein, zwei Spielereien illustrieren.
18 Schwierigkeitsgrad: einfach
Abbildung 18-1: Balkendiagramm
145
Kümmern wir uns zunächst nicht um die Tabelle, die wir für unser Dia gramm verwenden wollen, sondern um etwas anderes: zwei Hintergrund bilder auf unserer Seite, eins links sichtbar, eins rechts. Was sich in so einem Fall und angesichts der noch fehlenden Möglichkeit, einem Element mehrere Hintergrundgrafiken zuzuweisen (CSS 3 …), anbietet, ist, zwei immer vorhandenen Elementen entsprechende Zuweisungen zu verabreichen: html und body.
Abbildung 18-2: hintergrund-verlauf.png, 227 x 1 Pixel (hier vergrößert dargestellt)
html { background: #666 url(bilder/hintergrund-verlauf.png); font: 93.75%/1.3 georgia, serif; } body { background: #FFF url(bilder/hintergrund.png); margin-left: 15.13em; }
Abbildung 18-3: hintergrund.png, 17 x 17 Pixel
Auf beiden Elementen setzen wir ein Hintergrundbild sowie eine Hinter grundfarbe (als »Fallback« bei deaktivierten Bildern). Da das html-Hinter grundbild bei einem komplett darüberliegenden body gar nicht sichtbar wäre, »schaufeln« wir entsprechenden Platz frei – mit 227 Pixel Außenabstand nach links. Genauer gesagt 15.13em: 227 Pixel / 15 Pixel, wobei 15 Pixel 93,75% der Schriftgröße bei einer Basis von 16 Pixel entsprechen. Das führt allerdings zu folgendem Effekt: Das body-Element beansprucht nicht mehr die volle Höhe, sondern nur noch die durch seine Inhalte implizierte Höhe – man sieht den html-Hintergrund also nicht nur links, sondern auch unterhalb des body-Elements. Nimmt man die backgroundDeklaration bei html wieder weg, ist der body auch wieder 100% hoch. Dass die Spezifikation html als Element definiert, das quasi die »Leinwand« darstellt, ist uns bewusst – dass body aber ein derart inkonsistentes Verhalten an den Tag legt, ist für uns weniger erfreulich. Was können wir dagegen unternehmen? Bei sehr inhaltsreichen Seiten, wo die Länge des body-Elements »garantiert« die des html-Elements erreicht, müssen wir gar nichts machen. In unserem Fall, wo wir nur relativ wenig Inhalt präsentieren, können wir dem body-Element eine sehr große Höhe (exemplarisch: 500em) verabreichen und dem html-Element dafür »verbieten«, Scrollbalken darzustellen: html { overflow: hidden; } body { height: 500em; }
146
Teil III: Formulare und Tabellen
Der Effekt ist der erwünschte und die Lösung eine elegante – nur mit der Crux, dass sehr lange Inhalte ebenso wie äußerst opulente große Schriften nicht mehr funktionieren, da sie abgeschnitten werden. Gut, dass wir es hier auch mal mit einem solchen Fall zu tun haben: Als professioneller Webdesigner oder Webentwickler sollte man sowohl die hier vorgestellten Lösungen als auch ihre Probleme im Blick (und im Griff) haben. Mit html {color: #000;} geben wir nun noch schwarze Schrift vor.
Überschriften Unsere Überschrift
Personal 2004-2008
stylen wir in zwei Schritten, zunächst ihre Schrift, mit Angaben zur Farbe (weiß), Größe (2.6em bzw. 39 Pixel), »Gewicht« (normal) und Zeilenhöhe (0.9): h1 { color: #FFF; font-size: 2.6em; font-weight: normal; line-height: 0.9; }
Da sich die Überschrift im vom body vorgegebenen Rahmen befindet, kommt sie leider nicht so schnell auf die Idee, sich auf dem für sie eigentlich vorgesehenen dunklen Verlauf des html-Elements niederzulassen. Deshalb helfen wir mittels relativer Positionierung nach und ziehen sie 5.56em nach links (5,56 × 2,6 × 15 Pixel = 216,84 Pixel, aufgerundet 217 Pixel). Die Überschrift verfügt also auch noch über zehn Pixel Abstand zum linken Rand (227 – 217 Pixel). Bei einer Schriftgröße von 39 Pixel (2,6 × 15) genügen .26em Abstand nach oben (via top), um weitere 10 Pixel Luft zu erzielen. Mit einer Breite von 5.3em (206,7 Pixel) stellen wir sicher, dass der Text nicht mehr Platz einnimmt als vereinbart und somit wie von uns geplant umbricht: h1 { left: -5.56em; position: relative; top: .26em; width: 5.3em; }
Das ist recht viel Rechnerei, aber dennoch lohnenswert – so ist üblicherweise der Weg, um »pixelgenaue« Layouts über relative Angaben zu erreichen. Übrigens haben wir mit dem em -Außenabstand auf body sichergestellt, dass der linke Überschriftenbereich schön skaliert und seine weiße Schrift nie »überlappt« und auf dem hellen Hintergrund unleserlich werden würde.
Kapitel 18, Balkendiagramm
147
Tabellen
Abbildung 18-4: balken.png, 32 x 31 Pixel
Anzahl der Mitarbeiter im Unternehmen
2004
2005
2006
2007
2008
300px;" />
248px;" />
286px;" />
330px;" />
Das Ziel, ein Balkendiagramm zu erstellen, erreichen wir nahezu ausschließlich über die dahinterliegende Tabelle und nur marginal über CSS: Der eigentliche »Effekt« beruht auf einem einzigen »Balken«-Bild, das wir jeweils individuell über Inline-CSS »stretchen«. (Die Breite des Bildes basiert dabei genau auf einer einfachen Verdopplung der vorliegenden Mitarbeiterzahlen.) Warum inline, via style-Attribut? Es macht wenig – sprich: keinen – Sinn, für jede mögliche Zahl eine eigene Klasse zu definieren. Das Tabellengerüst ist ansonsten einfach: eine »Überschrift«, dazu thElemente zur Kennzeichnung des Jahres, dann td-Elemente mit den Bildern zur Visualisierung und Vergleichbarkeit der Zahlen, die in derselben Zelle folgen. Diese Zahlen sollten deshalb auch nicht noch mal im alt-Attribut wiederholt werden. Das wäre redundant, die Bilder sind hier gewissermaßen »dekorativ«. Mit der folgenden Regel wird die Höhe der Balken-Bilder fixiert, damit diese durch die variierende Breite nicht auch in der Höhe verändert werden, was nicht nur wenig nützlich, sondern auch optisch sehr unschön wäre.
148
Teil III: Formulare und Tabellen
img { height: 31px; margin: 0 .5em -.75em 0; }
Der Außenabstand stellt einen einfachen Weg dar, »Bündigkeit« mit den Texten herzustellen, die wir wiederum vertikal am unteren Rand ausrichten: th, td { font-weight: normal; text-align: left; padding: .5em 1em 1em 1em; vertical-align: bottom; }
Außerdem geben wir vor, dass der Text nicht fett und nach links ausgerichtet ist (betrifft eigentlich nur die th-Elemente) und zudem mehr Innenabstand bekommt. Auch die caption wird mit ein wenig Innenabstand versehen: caption { padding: .4em; }
Zur Krönung bauen wir noch einen kleinen Effekt ein: tr:hover { background: #DDD; }
Damit heben wir jede Zeile grau hervor, wenn sie mit der Maus überfahren wird. Leider unterstützt der Internet Explorer 6 diese Pseudoklasse nur bei Links. Insofern ist dieser Effekt auch neu für dieses Buch, das ansonsten ja eher »defensiv« vorgeht.
Referenzen • CSS-Spezifikation: Die dynamischen Pseudoklassen :hover, :active und :focus http://www.w3.org/TR/CSS21/selector.html#dynamic-pseudo-classes
150
Teil III: Formulare und Tabellen
NewsletterFormular Die anstehende Herausforderung ist ein Formular, das wir für eine News letter-Anmeldung kreieren wollen, eine durchaus nicht seltene Aufgabe.
19 Schwierigkeitsgrad: einfach
Abbildung 19-1: Newsletter-Formular
151
Unser dazu benötigtes Markup ist wie immer nicht außergewöhnlich: Wir greifen auf die »üblichen Verdächtigen« zurück, semantisch richtig sind das form, fieldset, legend, label, input und div. Die einzigen zusätzlichen Ingredienzen sind ein paar Klassen und IDs, die wir später gut in unserem Stylesheet gebrauchen können:
Normalerweise verwenden wir keine gleichnamigen Klassen- und IDBezeichner, in diesem Fall aber bietet sich dieses Vorgehen an, denn die jeweiligen Elemente haben einen Bezug zu einer einzelnen Funktion. Durch gleiche Namen, die spezifikationskonform sind, »assoziieren« wir die betroffenen Elemente formell und erleichtern uns dadurch unter anderem die weitere Arbeit.
Schnelle Umsetzung Zuerst definieren wir die Größe des Formulars, die durch unser Hinter grundbild vorgegeben wird, das wir sofort einbinden. Außerdem neutralisieren wir fieldset und legend. Wir verwenden somit zwar das gesamte »semantische Portfolio«, tragen aber gleichzeitig dem Umstand Rechnung, dass wir in diesem Entwurf weder eine Umrahmung noch eine Formularlegende darstellen wollen. form { background: url(bilder/hintergrund.gif); height: 344px; width: 471px; } fieldset { border: 0; position: relative; } legend { display: none; }
152
Teil III: Formulare und Tabellen
Abbildung 19-2: hintergrund.gif, 471 x 344 Pixel
Im Hinblick auf die Zugänglichkeit ist unser Vorgehen nicht unbedenklich. Ein kurzer Test im IBM Home Page Reader (den es bei IBM in einer kostenlosen Testversion zum Herunterladen gibt) belegt beispielsweise, dass die Legende nun nicht mehr verfügbar ist. Da das von uns in diesem Fall aber nicht als kritisch eingestuft wird – wir setzen voraus, dass bereits zuvor deutlich gemacht wurde, dass man sich hier zu unserem Newsletter anmelden kann –, fahren wir gleich fort, und zwar wollen wir Bilder anstelle von Text für die Labels verwenden. Sofort denken wir daran, dass der Internet Explorer 6 uns einen Vorteil von Labels entzieht, wenn wir einfach ein img-Element innerhalb von label verwenden: Er erlaubt es nämlich nicht mehr, durch einen Klick auf das Bild Zugang zum zugehörigen Formularelement zu erhalten; der Cursor springt in den IE-7-Vorgängern also nicht in das Feld hinein. Und gerade das ist ein wirklich nicht zu unterschätzender Vorteil von Labels. Wenn wir weiter über diese Problematik nachdenken, kommen wir sofort auf ein anderes Thema: »Image Replacement«-Techniken – und genau dort werden wir ansetzen. Die einfachste Technik wird sein, über einen »Outdent« vorzugehen, also über einen negativen Wert der text-indentEigenschaft. Techniken wie das »Fahrner Image Replacement« erfordern zusätzliches Markup und sind weniger zugänglich, und auch Alternativen wie das »Malarkey Image Replacement« scheinen uns nicht voranzubringen.
Kapitel 19, Newsletter-Formular
153
Phark &Co.
Image Replacement Image Replacement ist das Ersetzen von HTMLElementen durch Bilder, so dass der eigentliche Textinhalt nicht mehr angezeigt wird. (Die ersetzten Textinhalte sollten dabei weitgehend denen auf den Bildern entsprechen, damit Ihre Seiten bei Suchmaschinen wie Google nicht unter Verdacht geraten, den Suchmaschinen etwas anderes vorzusetzen als den Website-Besuchern.) Die populärsten Bildersatztechniken sind das Fahrner Image Replacement (FIR), die Phark-Methode sowie das Scalable Inman Flash Replacement (sIFR), das auf Flash und JavaScript aufsetzt. Neben diesen dreien gibt es eine ganze Reihe von weiteren Methoden, die meisten davon auf Basis von CSS, einige auch auf Grundlage von JavaScript. Einige sind zugänglich für Menschen mit Behinderungen, andere sind eher problematisch. Aufgrund der Vielzahl und Vielfältigkeit dieser Techniken würde es an dieser Stelle zu aufwändig sein, alle aufzuzählen. Der am Ende dieses
Kapitels referenzierte Artikel »Image-ReplacementTechniken« beinhaltet jedoch eine detaillierte Übersicht. Im vorliegenden Buch wird durchgängig die PharkMethode verwendet, da sie eine der einfachsten Methoden ist. Will man ein 250 x 50 Pixel großes Bild bei einer h1-Überschrift einsetzen, reicht bereits die folgende Regel: h1 { background: url(beispiel.gif); height: 50px; text-indent: -999em; width: 250px; }
Die Maße der Überschrift werden durch height und width fixiert, während die text-indent-Eigenschaft den Text gewissermaßen »nach links rausschiebt« und die background-Eigenschaft dann das Bild einfügt.
Da wir mit Inline-Elementen wie label oder span arbeiten, in denen wir die Bilder anzeigen möchten, müssen wir diese über die display-Eigenschaft erst zu Block-Elementen machen, um text-indent überhaupt nutzen zu können – denn dieses kann nur bei Block-Elementen verwendet werden: .index { display: block; text-indent: -999em; }
Der Grund, warum wir nicht über Elementselektoren vorgehen, liegt auf der Hand: Wir müssten dann für die beiden Versandart-Beschriftungen Regeln schaffen, die die obigen Deklarationen wieder aufheben. Das wäre hier unschön, und zudem nutzen wir gerne die Möglichkeit in CSS, mehrere Klassen zuzuweisen, denn wir gehen gleich dazu über, die Bilder und die erforderlichen Höhen- und Breitenangaben für die einzelnen Bild-Label zu definieren:
Die Positionierung aller Elemente – mit dem fieldset-Element als Bezugs punkt – heben wir uns bis zum Schluss auf, so dass wir mit der Formatierung aller Formularelemente fortfahren. Machen wir also die Eingabefelder und den Button etwas hübscher.
Die Positionierung geht nun mit vielen Regeln einher. Zuerst einmal picken wir uns die Elemente heraus, die positioniert werden sollen. Das form Element ist deshalb dabei, weil es als »Referenzpunkt« für die anderen Elemente dient, die zu diesem Element positioniert werden. div, form, input, label, span { position: absolute; }
Anschließend schieben wir alle Elemente an die richtige Position: #name, #e-mail { left: 197px; } .name { left: 101px; top: 82px; } #name { top: 80px; }
Die Zuweisungen, die wir beim html -Element vornehmen, nämlich die Hintergrundfarbe wie auch die Schriftfarbe auf Weiß zu setzen, können uns in die Bredouille bringen, wenn die Anzeige von Bildern vom Nutzer deaktiviert wird. Es ist wichtig, auf solche Feinheiten zu achten (auch wenn es in diesem Buch sicherlich dennoch Grenzfälle gibt).
Zum Schluss folgt noch ein kleiner Kniff, und zwar lassen wir uns nicht darauf ein, die beiden Radio-Buttons und ihre Beschriftungen alle einzeln zu positionieren, sondern verwenden ein div als Container, der die Positionierung übernimmt. Innerhalb des Containers muss der Fluss wieder normal erfolgen, deshalb gilt für alle Elemente ein position: static;. Der Rest ist Formsache – Opera erfordert es, dem div noch eine feste Breite zuzuweisen, und damit der rechte Radio-Button ordentlich sitzt, weisen wir ihm einen Außenabstand von 25 Pixeln nach links zu: div { left: 201px; top: 187px; width: 180px; } div * { position: static; } div #versand-html { margin-left: 25px; }
CSS-Überblick Nun können wir das Stylesheet bereits in seiner Gesamtheit inspizieren: * { margin: 0; padding: 0; } html { background: #FFF; color: #FFF; font: bold 87.5%/1.0 verdana, arial, helvetica, sans-serif; }
Referenzen • Jens Meiert: Image-Replacement-Techniken http://meiert.com/de/publications/articles/20050513/ • IBM Home Page Reader http://www-5.ibm.com/de/accessibility/hpr.html
158
Teil III: Formulare und Tabellen
KommentarFormular Für die kleine Kommentarfunktion in unserem Blog brauchen wir ein Formular, und wir wollen, dass unsere Eingabefelder mal etwas interessanter aussehen. Die Felder des Formulars lauten »Name«, »E-Mail«, »Homepage« und »Kommentar«, das ist das, was wir als Eingabe erwarten.
20 Schwierigkeitsgrad: einfach
Abbildung 20-1: Kommentar-Formular
159
Das entsprechende Markup zimmern wir schnell zusammen. Es reichen ein form -Element, ein div-Element, vier label- und vier input-Elemente, ein textarea-Element sowie ein span-Element (da das Formular wahrscheinlich mitten auf einer Seite erscheint, verzichten wir in diesem Fall auf eine »echte« Überschrift).
Basisdefinitionen, die wir hier nicht extra behandeln, sind die Schrift (11 Pixel Verdana via 68.75%), die Schriftfarbe (Blau) und die Hintergrund farbe (Dunkelblau). Das definiert unser Stylesheet global über das RootElement.
Erste Schritte Das erste Styling erledigen wir über den Hintergrund, den wir oben links mit einer kleinen Abrundung versehen. Dazu verwenden wir ein divElement, denn die Verwendung von fieldset und legend scheidet diesmal wegen unserer Pläne mit der Legende und wegen des Verhaltens des Internet Explorer in Bezug auf beide Elemente (wir können dadurch kein überall gleiches Erscheinungsbild gewährleisten) leider aus. Ein wenig Innenabstand erscheint uns sinnvoll, und wir haben eine Vorstellung von der Breite des Formulars; sie soll 470 Pixel betragen.
Abbildung 20-2: ecke.gif, 11 x 11 Pixel (hier vergrößert dargestellt)
div { background: #FFF url(bilder/ecke.gif) top left no-repeat; padding: 1em; width: 470px; }
Im nächsten Schritt hieven wir die Formularlegende aus dem Formular heraus. Wir möchten, dass sie oben rechts über dem Formular steht und dieses leicht »anschneidet«. Leider setzen wir uns semantisch aber nicht mit einer »echten« Legende, also einem legend-Element, auseinander, sondern verwenden alternativ ein span-Element.
160
Teil III: Formulare und Tabellen
Legenden
Probleme mit dem legend-Element Legenden für Formulare sind aus semantischer Sicht und in Bezug auf Zugänglichkeit eine wunderbare Sache. Allerdings wartet die Praxis mit zwei Besonderheiten auf. Zum einen »erbt« auch der Internet Explorer 7 etwaige generelle Farbzuweisungen nicht, die Farbe muss also »direkt« gesetzt werden: legend { color: red; }
Zum anderen zeigen der Internet Explorer, auf der Gecko-Engine basierende Browser (Mozilla, Firefox) und auch Opera alle ein unterschiedliches Verhalten, wenn man Legenden positionieren oder mit einem negativen Außenabstand versehen will. Der Internet Explorer lässt uns das legendElement zwar positionieren, negative Außenabstände bewirken aber, dass es unter den Bereich um das Formular bzw. Fieldset herum »geschoben« wird, ohne dass man dies über den Stacking-Kontext (mittels z-index) beeinflussen könnte. Gecko-Browser mögen sowohl Positionierung als auch negative Außenabstände, Opera jedoch koppelt Verschiebungen der Legende an das fieldset-Element und »zieht« nachfolgende Elemente quasi hinterher. Aufgrund dieser suboptimalen Ausgangslage wird im vorliegenden Design auf die Verwendung einer echten Legende verzichtet.
Bringen wir also die Legende in Position: form, span { position: absolute; } span { right: 0; top: -1em; }
Durch die erste Regel sorgen wir dafür, dass wir nicht absolut zum Viewport (das durch das html-Element repräsentierte gesamte Browserfenster) positionieren, sondern zum Formular (form -Selektor). Außerdem wird das spanElement selbst absolut positioniert. Die zweite Regel bestimmt dann, wo wir das span-Element gerne hätten, nämlich eine »em«-Höhe weiter oben (wir orientieren uns erst einmal) sowie ganz rechts. Im zweiten Schritt passen wir die Schriftgröße der improvisierten Legende an, verleihen ihr die richtige Farbe und sorgen dafür, dass die Schrift exakt mit der oberen Formularkante abschließt (wir modifizieren also entsprechend den Wert der top-Eigenschaft). span { color: #FFF; font-size: 2em;
Kapitel 20, Kommentar-Formular
161
line-height: 1.0; top: -.9em; }
Damit unsere Legende durch die Positionierung nicht einfach darüber liegenden Platz »auffrisst«, wird das Formular noch ein wenig angepasst: form { margin-top: 2em; }
Nach diesen vorbereitenden Maßnahmen kommen wir zur Gestaltung der Eingabefelder, wollen diese aber ebenfalls erst mal entsprechend in Position bringen. Hervorragend geeignet scheinen uns hierbei Floats zu sein, und da unser Markup schon eine schöne Struktur hergibt, können wir gleich dazu übergehen, unser Stylesheet entsprechend anzupassen. label, input, textarea { float: left; } label { clear: left; width: 100px; } input { width: 230px; } textarea { width: 343px; }
Warnung
Unter Linux kann es in einigen Versionen von Gecko-Browsern, zum Beispiel Mozilla 1.5, dennoch zu Problemen kommen, so dass das Formular »abgeschnitten« wird. Ein overflow -Wert von auto schafft Abhilfe, führt aber zu anderen Problemen, zum Beispiel mit Opera. Ein sicherer, aber hier absichtlich nicht beschrittener Weg ist im Zweifelsfall das Setzen einer festen Höhe über die heightEigenschaft.
162
Was wir an dieser Stelle machen, ist nichts anderes, als allen Beschriftungen (Labels) und Formularelementen vorzugeben, dass sie »gefloatet« werden, und ihnen gleichzeitig auch eine Breite zuzuweisen (das ist gemäß der CSSSpezifikation erforderlich). Und damit unsere Beschriftungen nicht in der falschen (der vorherigen) Zeile landen, »unterbrechen« wir den Fluss vor jeder Beschriftung. Nun taucht allerdings ein Problem auf: Der äußere Kasten, unser div, umfasst in Gecko-basierten Browsern augenscheinlich nicht mehr das ganze Formular, wobei dieses Verhalten der CSS-Spezifikation entspricht. Wir umgehen das Problem recht einfach über eine modifizierte Variante von Anne van Kesterens »Super Simple Clearing Floats«. Und zwar fügen wir eine zusätzliche Regel hinzu, die die overflow-Eigenschaft des div-Elements auf einen Wert ungleich visible setzt (was der Standardwert für diese Eigenschaft ist), in unserem Fall auf hidden. div { overflow: hidden; }
Teil III: Formulare und Tabellen
Anschließend erweitern wir die Regeln noch mal, um die Abstände noch etwas zu vergrößern. Die Eingabefelder sollen eine »em«-Höhe Abstand nach unten erhalten, und damit die Formularbeschriftungen danach auch noch ansprechend aussehen, werden sie über einen entsprechenden Innenabstand justiert. label { padding-top: .5em; } input, textarea { margin-bottom: 1em; }
Beginnen wir nun damit, das Formular zu schmücken. Auf den Standard rahmen wollen wir verzichten, und alle Eingabefelder sowie der Textbereich sollen ein Hintergrundbild erhalten: input, textarea { border: 0; } input { background: url(bilder/eingabefeld.gif); height: 23px; } textarea { background: url(bilder/kommentarfeld.gif); height: 228px; }
Abbildung 20-3: eingabefeld.gif, 230 x 23 Pixel
Abbildung 20-4: kommentarfeld.gif, 343 x 228 Pixel
Die Schriftfarbe für alle Eingabefelder muss dunkel sein, und wir bevorzugen auch hier Verdana als Schrift. Durch etwas Innenabstand können wir zudem dafür sorgen, dass sich der eingegebene Text auch schön ins Gesamtbild einfügt und nicht (wie jetzt) einfach links oben in der Ecke
Kapitel 20, Kommentar-Formular
163
(jedes Felds) klebt. Dadurch sind wir aber auch gezwungen, die Breite und Höhe jedes Eingabefelds anzupassen, so erfordert es das CSS-Boxmodell. input, textarea { color: #193076; font: 1em/1.0 verdana, arial, helvetica, sans-serif; } input { height: 15px; width: 212px; } textarea { height: 220px; width: 325px; }
Feinschliff Nun ist es an der Zeit, Resümee zu ziehen: Mit relativ wenigen CSS-Regeln und noch viel weniger XHTML-Code haben wir ein kleines KommentarFormular geschrieben. Bis hierher funktioniert alles wunderbar, einen Wermutstropfen stellte bis zur Version 8 lediglich der Opera-Browser dar: Wegen des Rahmens, den wir Opera (wie auch Safari) nicht vorgeben konnten, kamen wir dort um eine Standardformatierung der Eingabefelder nicht herum. Außerdem erlaubte uns Opera ebenfalls bis zu den 8er Versionen nicht, einen Innenabstand in den Eingabefeldern zu definieren. Eigentlich ermöglicht die CSS-Spezifikation einen Innenabstand bei allen Elementen, sofern diesen nicht mit der display-Eigenschaft ein Wert zugewiesen wurde, der irgendwelchen Tabellentypen außer table, inline-table und table-cell entspricht. Wir gehen nicht nur wegen dieses Spezifikationsausflugs, sondern auch deshalb darauf ein, weil wir uns alle an der Weiterentwicklung von Browsern erfreuen. Fahren wir also fort, der Button selbst soll noch ein neues Aussehen bekommen. Wir rücken ihn nun zurecht und bearbeiten ihn anschließend, indem wir die Schrift (wir wünschen dasselbe Aussehen wie bei den Formularbeschriftungen) und den Hintergrund anpassen: Abbildung 20-5: bestaetigung.gif, 25 x 25 Pixel
Die Deklaration height: 2.5em; benötigen wir, um die für die input-Elemente definierte Höhe zu überschreiben. margin-left dient zur Positionierung unterhalb und bündig zum Textbereich, padding zur Ausbalancierung im Verhältnis zum Hintergrundbild, dem Haken. width wird verwendet, um dieselbe Breite wie beim Kommentarfeld zu erhalten. Die Schrift soll weiß und unterstrichen sein.
Referenzen • CSS-Spezifikation: Der Viewport http://www.w3.org/TR/CSS21/visuren.html#q2 • Anne van Kesteren: Einfaches Steuern von Floats http://annevankesteren.nl/archives/2005/03/clearing-floats • CSS-Spezifikation: auto-Höhen für Elemente im Blockformatierungs kontext http://www.w3.org/TR/CSS21/visudet.html#root-height • CSS-Spezifikation: Innenabstand-Eigenschaften http://www.w3.org/TR/CSS21/box.html#padding-properties
166
Teil III: Formulare und Tabellen
Forenregistrierung
Stellen wir uns nun einmal eine Projektsituation vor, in der wir mal eben schnell ein Registrierungsformular hervorzaubern müssen. Total unrealistisch, ganz ohne vorliegendes Konzept! Aber uns wird sozusagen die Pistole auf die Brust gesetzt. Alles, was wir wissen, ist, dass Name, Vorname, E‑Mail-Adresse, zur Sicherheit deren Wiederholung sowie der gewünschte Nickname erforderlich sind. Wenigstens können wir uns den Text »Mit * gekennzeichnete Felder sind Pflichtangaben« sparen, da alle Felder ausgefüllt werden müssen.
21 Schwierigkeitsgrad: einfach
Wir beginnen das Styling mit dem Hintergrund und den Schriftzuweisungen: html { background: url(bilder/hintergrund-1.jpg); color: #9B1900; font: 68.75%/1.2 verdana, arial, helvetica, sans-serif; }
167
Abbildung 21-1: hintergrund-1.jpg, 7 x 8 Pixel
Die Formularlegende soll fett hervorgehoben sein, mit weißer Schrift auf weinrotem Grund und mit ein wenig Innenabstand, damit sie prominenter wirkt. legend { background: #9B1900; color: #FFF; font-weight: bold; padding: 3px 6px; }
Nun brauchen wir »Luft« in unserem fieldset. Außerdem wäre es schön, wenn der Rahmen ebenfalls unserer Schriftfarbe entsprechen würde. Da das Spezifizieren einer Farbe allein den Rahmen etwas dicker machen würde – trotz des von allen Browsern schon gesetzten und eigentlichen dünnen Rahmens –, holen wir uns Verstärkung in Form einer borderDeklaration. Der Clou ist das Einbeziehen eines halbdurchsichtigen PNG-Bildes als Hintergrund. Dabei stört weniger die mangelnde Unterstützung durch den Internet Explorer (nein, das ist hier wirklich nicht das Problem) als vielmehr der Umstand, dass dieser den nicht durchsichtigen Hintergrund auch oberhalb des fieldset anzeigt.
Abbildung 21-2: hintergrund-2.png, 1 x 1 Pixel (hier vergrößert dargestellt)
Nun, da wir diesen Missstand im Internet Explorer diagnostiziert haben, suchen wir nach Lösungen. Sofort befällt uns der Verdacht, dass dieses seltsame Verhalten, dass das Hintergrundbild (oder besser: die angezeigte solide Farbe) auch oberhalb des Rahmens sichtbar ist, mit der Legende zu tun haben könnte. Richtig, dieser Test bestätigt das: 168
Teil III: Formulare und Tabellen
legend { display: none; }
Da dieser Test aber auch gleichzeitig eine akzeptable Lösung darstellt – wir arbeiten ja dennoch mit semantischem Markup und sind nicht allzu sehr auf die Legende angewiesen –, können wir hier den Hebel ansetzen und aus unserem Repertoire ganz einfach den Kombinator > nutzen. Den beherrschen nur die »guten« Browser, und wir können über ihn und seine höhere Spezifität (siehe Kapitel 4, »Spaltenlayout ›Alias‹«) die Legende bei solchen Browsern wieder anzeigen. fieldset > legend { display: inline; }
Widmen wir uns jetzt einer einfacheren Aufgabe – wir versehen alle Elemente mit einem schönen Abstand zwischen den Buchstaben: * { letter-spacing: 1px; }
Hinweis
Hier haben wir tatsächlich einen der wenigen Fälle, in denen einen Workarounds wieder einholen: Der Internet Explorer 7 unterliegt derselben Problematik wie seine Vorgänger, kennt aber wiederum den angewandten Kombinator.
Die Feldbeschriftungen wollen wir nun über den einzelnen Feldern haben. Zusätzliches Markup benötigen wir dafür nicht: label { display: block; }
Nun stimmen aber die Abstände sowie die Breiten der Eingabefelder noch nicht. Und die Schriftfarbe, nicht zu vergessen. input { color: #000; margin: 2px 0; padding: 2px; width: 300px; }
Sowohl die Schriftgröße (sie soll gleich bleiben, also gehen wir den Weg über 1em) als auch die Schriftart müssen erneut definiert werden, so dass wir noch font: 1em verdana, arial, helvetica, sans-serif; hinzufügen müssen. Um den Abstand nach oben zu justieren, schlagen wir zwei Fliegen mit einer Klappe, da der Internet Explorer wohl unseren fieldset-Innenabstand nicht ganz schluckt. label { margin-top: 10px; }
Im Endresultat führen wir beide label-Zuweisungen selbstverständlich zusammen.
Kapitel 21, Forenregistrierung
169
Da wir unseren Button mit den input-Deklarationen ebenfalls »erwischt« haben, wollen wir diesen noch befreien. Außerdem soll er sich unter die Eingabeelemente verziehen, mit etwas Abstand nach oben, versteht sich: input#registrieren { display: block; margin-top: 10px; width: auto; }
Etwas Innenabstand wollen wir ebenfalls, auch wenn der Internet Explorer da grundsätzlich rumzickt, setzt er doch grundsätzlich etwas viel davon. Immer wieder der Internet Explorer. padding: 1px 3px; erledigt das für uns. Da wir nun auch schon fast am Ende sind – unsere Aufgabe hat uns vermutlich nur fünf Minuten unserer kostbaren Zeit gekostet –, setzen wir noch die Breite des fieldset-Elements auf 308 Pixel: fieldset { width: 308px; } Tipp
Die Differenzierbarkeit der verwendeten Hintergründe und Farben sowie die Kontraste sind möglicherweise noch zu prüfen. Aber die dazu benötigten Instrumente – zum Beispiel die Analyse-Tools von Gez Lemon oder Jonathan Snook – sollte jeder im Portfolio haben.
Schlussendlich überlegen wir uns noch einen weiteren Coup für alle weitgehend standardkonformen Browser, die nicht auf den Namen »Internet Explorer« hören. Alle Eingabeelemente einschließlich des Buttons sollen bei Erhalten des Fokus eine andere Hintergrundfarbe bekommen: input:focus { background: #FFDBE6; }
Das fertige Layout sehen Sie in Abbildung 21-3 (mit aktivem VornameFeld).
Periodensystem der Elemente Holen wir doch einmal das Periodensystem der Elemente hervor, das wir auf unserer chemiebezogenen Webseite schick aufmachen wollen. Wir haben also Gelegenheit, uns an einer weiteren Tabelle zu beweisen, denn das ist es, was wir hier benötigen.
22 Schwierigkeitsgrad: einfach
Abbildung 22-1: Periodensystem der Elemente
173
Das HTML dazu schütteln wir uns aus dem Ärmel, die Grundstruktur ist nicht gerade komplex:
Periodensystem der Elemente
I
…
H
…
…
Wir müssen festhalten, dass wir hier der Einfachheit halber auf die Verwendung des abbr- oder acronym -Elements verzichten sowie die Zusammenfassung (summary-Attribut) offenlassen (das ziehen wir später selbstverständlich nach). Zudem stellen wir nur die Elementnamen dar, Ordnungszahlen und Ähnliches interessieren uns vorerst nicht. Beginnen wir mit dem Styling. Zuerst suchen wir uns eine schöne, dezente Schrift und Schriftfarbe: Georgia in dunklem Grau sieht gut aus. Um Probleme mit älteren Versionen des Internet Explorer zu vermeiden, wird sie gleich auf unserem Hauptelement, der Tabelle, gesetzt. Und ein generelles Hintergrundbild, etwas Zierrat, wollen wir auch. html { background: url(bilder/hintergrund.gif); color: #333; }
Abbildung 22-2: hintergrund.gif, 60 x 60 Pixel
table { font: 75%/1.3 georgia, serif; }
Die Tabelle soll über die ganze Breite gehen und die Spalten sollen dabei alle die gleiche Breite beanspruchen, was wir über die table-layout-Eigenschaft definieren. table { table-layout: fixed; width: 100%; }
Eine weitere kleine Modifikation stellt der Innenabstand für th- und tdElemente dar. Bei dieser Gelegenheit erzwingen wir bei td-Elementen noch eine Zentrierung des enthaltenen Textes, wobei wir uns dieser bei th gewissermaßen zusätzlich versichern (sie wird von eigentlich allen User-AgentStylesheets bereits definiert). 174
Die Tabellenköpfe tauchen wir nun in dunkles Braun, dem wir mit weißer Schrift Rechnung tragen. th { background: #6B462E; color: #FFF; }
Fahren wir mit unserem Stakkato an Deklarationen und Regeln fort. Leere Zellen sollen nicht angezeigt werden: table { empty-cells: hide; }
Wir führen die Ergänzungen am Ende alle noch zusammen. Die Tabellen zellen erhalten ebenfalls eine Hintergrundfarbe: td { background: #E6C7B3; }
Eigentlich sollte der Internet Explorer die leeren Zellen nun nicht mit dieser Farbe versehen – aber wir kennen die Leier ja. Wir greifen also auf die spezielle Klasse aux zurück, mit der wir leere Zellen auch in diesem Fall transparent machen. td.aux { background: transparent; }
Die Tabelle selbst hinterlegen wir beigefarben: table { background: #FFEDE1; }
Nun kümmern wir uns um den Rahmen: table { border: 3px double #CC8F66; } td { border: 1px solid #CC8F66; }
Die Tabellen-caption kommt ebenfalls noch dran; wir vergrößern die Schrift und setzen einen dezenten Innenabstand: caption { font-weight: bold; padding: 0 0 .2em; }
Kapitel 22, Periodensystem der Elemente
175
Am Ende angekommen, bauen wir noch eine kleine Spielerei ein: Wir setzen den Cursor auf default, so dass nicht der übliche Textcursor erscheint, wenn die Maus über die Tabelleninhalte wandert. html { cursor: default; }
Referenzen • CSS-Spezifikation: Die table-layout-Eigenschaft http://www.w3.org/TR/CSS21/tables.html#width-layout
Kapitel 22, Periodensystem der Elemente
177
Bundesligatabelle
Fußballbegeisterung! Wir kennen diese langweiligen Bundesligatabellen, besonders dann, wenn »unser« Verein nicht an der richtigen Stelle steht. Zumindest optisch wollen wir daran jetzt etwas ändern, und da sich die laufende Saison nicht so gut für ein Beispiel eignet, schnappen wir uns für die zu präsentierenden Daten eine zurückliegende Saison.
23 Schwierigkeitsgrad: mittel
Abbildung 23-1: Bundesligatabelle
179
Eine Menge Hintergrundbilder liegt uns vor, und mit diesen geht es auch gleich los. Das initiale Aufsetzen unserer Musterseite sieht bereits die folgenden Regeln vor: * { margin: 0; padding: 0; } html { background: #FFF url(bilder/hintergrund.jpg); color: #000; }
Abbildung 23-2: hintergrund.jpg, 147 x 157 Pixel
body { padding: 30px; }
Stellen wir also das benötigte Markup zusammen und gehen wir dabei Schritt für Schritt vor. Die von uns angelegte Tabelle versehen wir der Einfachheit halber mit einem auf 0 gesetzten cellspacing-Attribut, da b order-spacing vom Internet Explorer nicht verstanden (aber dennoch exemplarisch von uns spezifiziert) wird bzw. border-collapse auf Grund der noch folgenden Rahmenprobleme ausscheidet. Zudem verwenden wir auch das caption-Element, das wir allerdings mittels display: none; ausblenden. Wir setzen auf semantische Vollständigkeit, die sich jedoch mitunter – wie in diesem Fall – unseren Designvorstellungen beugen muss. Als Erstes folgt das thead-Element mit den benötigten Spalten.
ID-Syntax Über das id-Attribut definierte IDs dürfen gemäß HTML-Spezifikation nur wie folgt verwendet werden: Sie müssen mit einem Buchstaben (a-z und A-Z) beginnen, können dann aber durch beliebig viele weitere Buchstaben, Zahlen ( 0-9), Bindestriche (-) und Unterstriche (_), Doppelpunkte (:) sowie Punkte (.) ergänzt werden. Wäre dies nicht der Fall, hätten wir unsere ID-Bezeichner in den Tabellen köpfen auch 1, 2, 3 usw. nennen können.
180
Teil III: Formulare und Tabellen
Wir beginnen mit der ersten Formatierung: table { border-spacing: 0; font: normal 68.75%/1.1 verdana, arial, helvetica, sans-serif; } th { background-color: #363; background-repeat: no-repeat; color: #FFF; height: 26px; padding-left: 8px; text-align: left; }
Die background-color-Eigenschaft ist eine primitive Lösung, um zu vermeiden, dass bei vergrößerter Schrift Weiß auf Weiß steht – das ist natürlich unleserlich. Gleichzeitig verwenden wir background-repeat, da die im Anschluss definierten Hintergrundbilder nicht wiederholt werden sollen. Diese sind zwar wunderschön und vor allem passgenau, verhindern aus diesem Grund aber fast eine gute Skalierbarkeit. Wir machen es uns in diesem Fall rein demonstrativ sehr einfach – unsere relative Schriftangabe nützt nicht viel (im Internet Explorer vor Version 7), wenn wir alle Texte in Zellen stopfen, die mit px-Maßen fixiert wurden. In einer Zeit, in der alle aktuellen Browser solche Angaben jedoch auch entweder gemäß Spezifikation als »relativ« betrachten oder zumindest »Zoom«Funktionalität bieten, zeigen wir anhand von schlechter Vorgehensweise aus der Vergangenheit legitimes Vorgehen der Zukunft. Während der geneigte Leser dies in den nächsten Jahren exakt so beobachten wird, sollten wir den IE 6 in diesen Tagen sonst aber noch toleranter behandeln. th#kopf-1 { background-image: url(bilder/hintergrund-kopf-1.gif); width: 45px; } th#kopf-2 { background-image: url(bilder/hintergrund-kopf-2.gif); width: 208px; }
Abbildung 23-3: hintergrund-kopf-1.gif, 53 x 26 Pixel
Abbildung 23-4: hintergrund-kopf-2.gif, 216 x 26 Pixel
Rein visuell kämen nun die Tabellenzellen im tbody-Bereich an die Reihe, doch im Markup muss – sofern vorhanden – erst der tfoot folgen. In unserem Fall wird er etwas zweckentfremdet, da er leer bleibt und nur unseren Tabellenabschluss darstellt.
Wir verpassen ihm ein nettes Bildchen: tfoot td { background: url(bilder/hintergrund-fuss.gif); height: 11px; width: 498px; }
Abbildung 23-9: hintergrund-fuss.gif, 498 x 11 Pixel
Nun zum tbody-Element und seinen Kindern. Grob skizziert wird das Markup von uns folgendermaßen geschrieben:
…
182
Teil III: Formulare und Tabellen
Die Klassen a und b dienen alternierenden Zuweisungen (mit CSS 3 wird das über neue Selektoren mal einfacher werden), und die Klasse alt ermöglicht »alternative« Formatierungen: tr.a { background: #A0C2A0; } tr.a .alt { background: url(bilder/hintergrund-zelle-a.gif); }
Abbildung 23-10: hintergrund-zelle-a.gif, 1 x 2 Pixel (hier vergrößert dargestellt)
Abbildung 23-11: hintergrund-zelle-b.gif, 1 x 2 Pixel (hier vergrößert dargestellt)
Kümmern wir uns nun um die th- und td-Elemente. Die den Platz designierenden th-Elemente sind durch unsere oben definierten Zuweisungen immer noch in Weiß gehalten, sollen aber schwarz sein. Zudem wollen wir sie rechtsbündig und mit etwas Innenabstand darstellen. tbody th { color: #000; padding-right: 8px; text-align: right; }
Denselben Innenabstand, allerdings nach links, weisen wir den eigentlichen Tabelleninhalten zu. Da wir auch im Tabellenfuß ein td-Element verwenden, greifen wir zum Selektor tbody td: tbody td { padding-left: 8px; }
Unsere »Alternativ«-Klassen (alt) geben uns die Möglichkeit, die betroffenen Zellen noch etwas hervorzuheben. Hier könnten wir eigentlich dieselbe Formatierung verwenden, wie wir sie bei den th-Elementen innerhalb des »Tabellenkörpers« vorgenommen haben. Diese Ergänzung ist schnell gemacht, wir ändern einfach den Selektor tbody th in .alt und ergänzen die Regel durch die Deklaration font-weight: bold;, um die Schrift in allen betroffenen Elementen fett hervorzuheben. Bevor wir in den Genuss kommen, noch an anderen Stellen mit noch zu definierenden Klassen zu hantieren – es ist absehbar, dass wir noch welche benötigen –, schieben wir noch etwas generelles Styling dazwischen, wie zum Beispiel die Höhe der Tabellenzellen. Diese an sich unspektakuläre Angelegenheit wird wider Erwarten interessant: Wir müssen die Höhe von th- und td-Elementen setzen, können dies
Kapitel 23, Bundesligatabelle
183
aber nicht generell definieren (über die entsprechenden Elementselektoren), sondern müssen über den Kontext vorgehen (tbody). Da wir außer den besagten beiden Elementen nur tr-Elemente im tbody verwenden, sollte der Selektor tbody * ausreichen, um die Höhe zu setzen. Das funktioniert aber zumindest nicht im Internet Explorer 6, dessen Implementierung offensichtlich irgendeine Regel höherer Spezifität kennt, die entweder den Selektor tbody th, tbody td oder die als !important gekennzeichnete Höhendeklaration erfordert, was diese in der Kaskade »vorziehen« würde. Was machen wir? tbody th, tbody td { height: 20px; }
Diese Lösung verwendet zwar weniger Zeichen, aber die folgende Lösung ist eleganter: tbody * { height: 20px !important; }
Nach diesem kleinen Ausflug widmen wir uns den beiden letzten ausstehenden Aufgaben, nämlich der Punktespalte sowie der Umrahmung der Tabellenzellen bei gleichzeitiger Kennzeichnung der Regionen der Tabelle, die den Meister, die zur Teilnahme an der Champions League sowie dem UEFA-Pokal berechtigenden Plätze sowie die Absteiger hervorheben. Tipp
Auch hier darf auf CSS 3 verwiesen werden, das uns in nicht allzu ferner Zukunft über die :last-child -Pseudoklasse das Leben vereinfachen wird.
Tipp
Auch wenn einzelne Designs in diesem Buch, wie zum Beispiel die Vergleichstabelle, bei der Klassenbenennung einen etwas anderen Kurs einschlagen, empfehlen wir Bezeichner, die die Funktion des Elements beschreiben oder die generisch bzw. neutral genug sind, um die Formatierung ohne Namens irritationen leicht ändern zu können.
184
Die Inhalte der Punktespalte wie auch die der alt-Zellen sollen rechtsbündig sein. Da uns zusätzliches Markup in Form des col-Elements nicht helfen würde, sind wir auf eine zusätzliche Klasse angewiesen. Diese zusätzliche Klasse nehmen wir zum Anlass, um noch mal auf deren Benennung einzugehen – es könnte ja naheliegend erscheinen, diese vielleicht punkte oder pkt oder ähnlich zu nennen. tdrechts, was fast so schlimm wäre wie fiktive Klassennamen wie blaufett oder dickelinie, scheidet schon im Vorfeld aus. Was passiert nämlich, wenn man den Inhalt der Zelle einmal ändert? Wir sollten also einen funktionsbeschreibenden oder wenigstens »generischen« Namen wählen – mit alt haben wir es schon vorgemacht. Da wir es ebenfalls mit einer alternativen Darstellung zu tun haben, machen wir es uns doch einfach: Wir rufen eine Klasse alt-2 ins Leben, werden aber unsere alte Klasse alt konsequenterweise in alt-1 umbenennen. Jetzt ist es einfach, der Punktespalte die gewünschte Formatierung zukommen zu lassen: .alt-2 { padding-right: 8px; text-align: right; }
Teil III: Formulare und Tabellen
Da wir beide Deklarationen bereits in der nun umbenannten Regel .alt-1 verwenden (die wir zuerst als tbody th kreierten und dann über .alt vereinfachen konnten), fassen wir dies am Ende noch mal zusammen, um Code einzusparen. Eine Abgrenzung der einzelnen Zeilen erzielen wir nun über einen Rahmen nach unten, der ein Pixel hoch und schwarz sein soll. Zwei Dinge fallen uns dabei auf: Auf tr-Elemente können wir die border-Eigenschaft nicht anwenden, und der Internet Explorer »erbt« in Tabellen nicht die Schriftfarbe als Wert für border-color, so dass wir diese explizit angeben müssen. Beides fließt entsprechend in unsere Zuweisungen ein: tbody * { border-bottom: 1px solid #000; } .alt-2 { border-right: 1px solid #000; }
Wie nützlich unsere neue Klasse .alt-2 jetzt doch ist. Ähnlich gehen wir bei der Differenzierung der einzelnen Punkteregionen vor, doch hier benötigen wir neue Klassen, um die Zeilen (bzw. deren Zellen) herauspicken zu können. Auch dabei kommen uns mehrere Namen in den Sinn, trenner klingt ganz gut, die im Buch schon öfter verwendete aux-Klasse scheint sich aber besser zu eignen. Diese neue Klasse weisen wir den betroffenen tr-Elementen zu, indem wir sie einfach hinter die schon vorhandene a- oder b-Klasse setzen:
…
Den Rahmen können wir nun über den Selektor tr.aux * setzen: tr.aux * { border-top: 2px solid #FFF; }
Auch hier wird es wieder spannend, denn zum einen hat der Rahmen rechts »Vorfahrt« gegenüber dem Rahmen nach oben, so dass rechts eine durchgehende Linie entsteht (schöner wäre es, wenn unsere Begrenzer über die ganze Breite gehen würden), zum anderen minimiert sich (korrekterweise, wie es die CSS-Spezifikation im Abschnitt »Tabellenhöhe-Algorithmen« definiert) die Höhe der Zellen durch den Rahmen. Für das erste Problem, den Rahmen, konsultieren wir den Abschnitt »Auflösung von Rahmen-Konflikten« in der CSS-Spezifikation und streichen damit auch schon die Segel. Denn wenn wir die border-collapseEigenschaft heranziehen und auf collapse setzen, beheben wir zwar unser Problem, aber nun würden aneinanderliegende weiße und schwarze Kapitel 23, Bundesligatabelle
185
Rahmen zusammenfallen – und das ist erst recht nicht akzeptabel. Wir müssen also mit diesem Umstand leben, und es lässt sich auch damit leben. Zumal Opera uns den Gefallen tut und den Rahmen anders und unseren Vorstellungen entsprechend zusammenführt. Was die dezimierte Höhe unserer Zellen anbelangt, können wir relativ leicht gegensteuern, indem wir zwei Regeln entsprechend modifizieren bzw. erweitern: tbody * { height: 21px !important; } tr.aux * { height: 23px !important; }
Zum Schluss unserer erfahrungsreichen Erstellung einer Bundesligatabelle folgt noch eine kleine Nachbesserung: tfoot td { height: 13px; }
Und da dies unter Opera nicht wie gewünscht funktioniert, betreiben wir Schadensbegrenzung, indem wir das Hintergrundbild wenigstens nicht wiederholen lassen, also explizit ein no-repeat hinter den Wert der ganz am Anfang vorgegebenen background-Eigenschaft hängen.
CSS-Überblick All diese Zaubereien, nachträglichen Änderungen, Hacks und Umsortie rungen können etwas verwirrend sein, also sehen wir uns noch das komplette Stylesheet an: * { margin: 0; padding: 0; } html { background: #FFF url(bilder/hintergrund.jpg); color: #000; } body { padding: 30px; } table { border-spacing: 0; font: normal 68.75%/1.1 verdana, arial, helvetica, sans-serif; }
Referenzen • CSS-Spezifikation: Die border-spacing-Eigenschaft http://www.w3.org/TR/CSS21/tables.html#propdef-border-spacing • HTML-Spezifikation: SGML-Grundtypen http://www.w3.org/TR/html4/types.html#h-6.2 • HTML-Spezifikation: Zeilengruppen – die Elemente thead, tfoot und tbody
Bei der Arbeit als Webdesigner oder Webentwickler stößt man tagtäglich auf besondere Herausforderungen wie beispielsweise Bildunterschriften oder auch auf »Schnickschnack« in Form von abgerundeten Ecken. Teil IV behandelt solche Fälle und wird einiges davon empfehlen, von manchem aber auch abraten.
IV In diesem Teil 24 Image-Map 2 5 »Über-Links« 26 Abgerundete Ecken 27 Bilder im Fließtext 28 Mini-Kochbuch 29 Pullquote 30 Bildunterschriften
189
Image-Map
In dieser Episode wenden wir uns Image-Maps zu. Image-Maps können prinzipiell über map- und area-Elemente realisiert werden, doch hier soll die CSS-basierte Lösung vorgestellt werden.
24 Schwierigkeitsgrad: einfach
Abbildung 24-1: Image-Map
191
Wir betrachten zuerst das zugrunde liegende Markup, bei dem wir eine Definitionsliste zugegebenermaßen nicht ganz ihrer Bestimmung entsprechend verwenden:
Der Clou bei der Umsetzung besteht diesmal darin, dass wir nur ein einziges Bild verwenden, auf dem zwei Zustände abgebildet werden. Doch gehen wir der Reihe nach vor. Zuerst schenken wir unserer Defi nitionsliste das obige Bild als Hintergrund, ohne dabei den unteren Bereich anzuzeigen. Dabei sorgen wir für einen (im wahrsten Sinne des Wortes) geeigneten Rahmen, indem wir eine zwei Pixel dicke Einfassung erzeugen. dl { background: url(bilder/siegestor.jpg); border: 2px solid; height: 410px; width: 550px; }
Der Effekt soll darin bestehen, einen erläuternden Text anzuzeigen und beim »Hovern« über die mit Zahlen versehenen Bereiche den jeweiligen Bereich optisch hervorzuheben (auf dem unteren Teil des Bildes zu erkennen). Die dt-Elemente blenden wir mittels display: none; aus. Mit den dd-Elemen ten fahren wir fort und positionieren sie zur Liste. Deshalb erhält die Liste selbst die Deklaration position: relative;. dl { position: relative; } dt { display: none; } dd { position: absolute; }
192
Teil IV: Effekte, Hingucker und Zaubereien
Abbildung 24-2: siegestor.jpg, 550 x 820 Pixel
Kapitel 24, Image-Map
193
Ein paar weitere Zuweisungen sind erforderlich, um den einzelnen »Defini tionsbeschreibungen« zu sagen, wo sie genau hingehören und wie groß sie sind: dd#relief { height: 100px; left: 104px; top: 236px; width: 220px; } dd#quadriga { height: 103px; left: 213px; top: 10px; width: 229px; } dd#medaillon { height: 100px; left: 330px; top: 150px; width: 220px; }
Die Links innerhalb der dd-Elemente sollen das ganze Element »ausfüllen«, deshalb weisen wir ihnen ein display: block; zu. Aus Rücksicht auf eventuelle andere Links auf der Seite gehen wir auch dabei über den Kontext vor und verwenden den Selektor dd a: dd a { display: block; height: 100%; width: 100%; }
Den ersten Teil des eigentlichen Effekts erzielen wir durch weitere Zauberei mit den Links. Da die Links nun die durch die dd-Elemente abgesteckten Bereiche komplett unter Beschlag nehmen, können wir ihnen beim Überfahren mit der Maus ein eigenes Hintergrundbild geben, das »zufällig« dem Listenhintergrund entspricht, aber nur den entsprechenden umrahmten Ausschnitt umfasst. dd a:hover { background: url(bilder/siegestor.jpg); } dd#relief a:hover { background-position: -104px -646px; } dd#quadriga a:hover { background-position: -213px -420px; } dd#medaillon a:hover { background-position: -330px -560px; }
194
Teil IV: Effekte, Hingucker und Zaubereien
Nachdem dieser Teil abgeschlossen ist, nerven uns natürlich die Linktexte, zumindest so, wie sie derzeit dargestellt werden. Wir greifen also erst einmal zu unserem bereits eingesetzten dd a-Selektor und verbessern das Erscheinungsbild: dd a { color: #FFF; text-decoration: none; }
Anschließend verschieben wir den Text, nachdem wir einige Modifikationen an der Hintergrundfarbe, am Rahmen und am Innenabstand vorgenommen haben. Wie gut, dass wir ein paar span-Elemente im Gepäck haben. dd a span { background: #000; border: 2px solid; padding: .5em; position: absolute; } dd#relief span { top: 105px; } dd#quadriga span { top: 105px; } dd#medaillon span { top: 75px; }
Das war es auch schon, von drei kleineren Problemen abgesehen. Das erste Problem besteht darin, dass der Text im Internet Explorer zwar anklickbar ist, aber durch die Umpositionierung einen Text-Cursor verwendet. Wir verwenden daher cursor: pointer; und weisen dies den span-Elementen zu. Eine andere Einschränkung ist, dass wir bisher nur Mausnutzer von unserer Image-Map profitieren lassen. Beim »Durchtabben« soll aber derselbe Effekt greifen. Dem tragen wir dadurch Rechnung, dass wir nicht nur die hover-Pseudoklasse verwenden, sondern auch focus und active. Und zu guter Letzt wollen wir, dass die Besucher das Bild und die dazugehörigen Erläuterungen auch sehen können, wenn CSS deaktiviert ist. Das erreichen wir ganz einfach, indem wir das eigentliche (also bereinigte) Bild siegestor-original.jpg (siehe Abbildung 24-3) ganz normal über ein imgElement einbinden und mittels display: none; ausblenden. (Um wie in der Einleitung erwähnt den leichten Übergang zu XHTML 1.1 zu ermöglichen, wurde das Bild in einen div-Container gesteckt und die CSS-Regel auf diesen angewandt.)
Kapitel 24, Image-Map
195
Abbildung 24-3: siegestor-original.jpg, 550 x 410 Pixel
CSS-Überblick Aufgrund der jüngsten Anpassungen sowie der möglichen Zusammen fassungen folgt nun noch einmal der gesamte CSS-Code im Überblick: * { margin: 0; padding: 0; } html { background: #EEE; color: #000; font: 68.75%/1.2 verdana, arial, helvetica, sans-serif; } body { padding: 30px; } dl, dd a:focus, dd a:hover, dd a:active { background: url(bilder/siegestor.jpg); } dl { border: 2px solid; height: 410px; position: relative; width: 550px; }
In einer Zeit, in der wir voller Spannung auf zukünftige (X)HTMLVersionen warten, vor allem auf HTML 5 und XHTML 2, müssen wir manche Wünsche und Effekte etwas anders realisieren, als es uns die Zukunft erwarten lässt. Ein Beispiel dafür ist die Möglichkeit von XHTML 2, alle Elemente als Hyperlink zu verwenden, indem überall das href-Attribut verwendet werden darf. Wir wollen hier in einfacher Form veranschaulichen, wie man auch heute schon »übernatürliche« Links einsetzen kann, die zumindest optisch mehr als nur ein paar Wörter umfassen.
25 Schwierigkeitsgrad: einfach
Abbildung 25-1: »Über-Links«
199
Theorie … Verdeutlichen wir unseren Plan mit etwas HTML. Wir gehen von einer Reihe von Text-Blöcken aus, die jeweils aus einem hervorgehobenen Text (»Pseudo-Überschrift«), einem Absatz sowie vielleicht einem weiterführenden Text bestehen.
Vielleicht hätten wir das anders vorstellen sollen, da wir nun bereits mitten im Geschehen sind. Normalerweise hätten wir dieses Pferd mit dem zuvor angedeuteten HTML aufgesattelt: eine Liste mit den einzelnen Blöcken, die wiederum aus einer Überschrift und einem Absatz mit entweder einem Link oder gar einem nachfolgenden, verlinkten Absatz bestehen. Diese Option steht uns aber nicht zur Verfügung, wenn wir den ganzen Block als Link definieren wollen: Wir können nur Elemente innerhalb des dann zwingend erforderlichen a-Elements einsetzen, die laut DTD erlaubt sind. Dazu gehören jedoch keine hn- oder p-Elemente – dafür aber die im Code oben bereits vorgesehenen Elemente. Die eingeschränkte Semantik gleichen wir zumindest »ein bisschen« aus, indem wir die Überschrift via strong und den abschließenden »Anreißer-Link« via em hervorheben.
… und Praxis Beziehen wir uns auf das nun begründete HTML – unser bester Freund bei der Formatierung ist die display-Eigenschaft: a, strong, em { display: block; }
Das ist die halbe Miete, um unsere »Über-Links« aus der Taufe zu heben. Mit display schaffen wir uns nicht nur die Möglichkeit, die Link-Protagonisten ansprechender hervorzuheben, sondern vor allem die strong- und em Elemente abzugrenzen, indem sie als Block-Elemente dargestellt werden. Nach diesem einfachen Kniff bereitet uns das »Glattziehen« der Darstellung keine allzu großen Schwierigkeiten mehr: html { background: #FAAB00; font: 87.5%/1.4 georgia, serif; }
200
Teil III: Formulare und Tabellen
ul { list-style: none; width: 60%; }
Diese Vorgaben erledigen mit Hintergrundfarbe und Schrift sowie neutralisiertem Listenstil und einer Platzbeanspruchung von 60% schon das Gröbste. Die folgende Regel enthält eine Deklaration, die wir in diesem Fall nur für den Internet Explorer vor Version 7 benötigen: height: 1%;. Wir stoßen darauf nach der Definition der zweiten Deklaration, nämlich margin-bottom: .5em; – der Abstand nach unten wäre im IE 6 viel zu groß. li { height: 1%; margin-bottom: .5em; } Unter der Lupe
hasLayout Eine Vielzahl von Darstellungsabweichungen und -problemen im Internet Explorer bezieht sich auf »hasLayout«. Das Konzept dahinter ist, da proprie tär, weitgehend, aber nicht vollständig erschlossen. Sehr vereinfacht ausgedrückt erhalten Elemente, die über Breiten- und Höhenangaben verfügen, »Layout« und können somit »normal« gestylt werden. Die folgenden (nicht ausnahmslos validen!) Eigenschaften/Werte sorgen für »Layout«: • position: absolute • float: left oder right • display: inline-block • width: jeder Wert außer auto • height: jeder Wert außer auto • zoom: jeder Wert außer normal • writing-mode: tb-rl Die unter »Referenzen« aufgeführte Dokumentation von Ingo Chao u.a. bietet ausführliche Informationen zu »hasLayout«.
Als nächstes kümmern wir uns um die Darstellung unserer allumspannenden Links: a { background: #6F9DCE; border: 3px solid #F9DA69; color: #FFF; padding: .2em .4em .4em; text-decoration: none; }
Kapitel 25, »Über-Links«
201
Hintergrundfarbe, Rahmen, Schriftfarbe, Innenabstand, (fehlende) Unter streichung: ein dankbares Profil. Bei den strong-Elementen ist es nicht minder einfach, jedoch anders in dem Sinne, dass wir optisch mehr Gewicht auf sie legen, als es semantisch der Fall ist. Wir wollen unsere »Fast-Überschriften« mit immerhin anderthalbmal so großer Schrift ausrüsten, die nicht gefettet sein soll, aber auch mit einem minimalen Abstand zum nachfolgenden Absatz. strong { font-size: 1.5em; font-weight: normal; padding-bottom: .1em; }
Die em -Elemente, die wir ebenfalls via display »in einer Zeile« darstellen, möchten wir etwas nach oben distanzieren: em { padding-top: .2em; }
Zum Schluss wollen wir noch für einen kleinen Effekt sorgen, der unsere ungewöhnlichen Links bei Fokus, Hover sowie »Aktivierung« mit anderen Hintergrund- und Rahmenfarben mehr zur Geltung bringt: a:focus, a:hover, a:active { background: #678191; border-color: #686868; }
Referenzen • Jens Meiert: (X)HTML 5 und XHTML 2 im Vergleich (xhtml.com) http://meiert.com/de/publications/translations/xhtml.com/xhtml-5-vsxhtml-2/ • XHTML 2.0-Entwurf: Hypertext-Attributsammlung http://www.w3.org/TR/xhtml2/mod-hyperAttributes.html#col_ Hypertext • Ingo Chao et al.: »On having layout« http://www.satzansatz.de/cssd/onhavinglayout.html
202
Teil III: Formulare und Tabellen
Abgerundete Ecken
Die nun folgende Geschichte machte Anfang 2005 als »Nifty Corners« (»schicke Ecken«) die Runde – wie es aussieht, der Feder Alessandro Fulci nitis entstammend. Sie stellt eine Möglichkeit dar, Ecken von Containern abzurunden bzw. abgerundet wirken zu lassen.
26 Schwierigkeitsgrad: einfach
Abbildung 26-1: Abgerundete Ecken
203
Anwendungsbeispiele kann sich jeder genug vorstellen, von kleinen Boxen auf privaten Webseiten bis hin zu nützlichen Widgets auf professionellen Angeboten. Da uns die Originalumsetzung nicht so gut gefällt, werden wir in unserem Beispiel noch ein bisschen Code-Tuning betreiben. Wie immer folgt zuerst ein Vorgeschmack auf das dazugehörige Markup:
Das sieht erst mal nicht so schön aus – und schreit förmlich nach Anmerkungen. Die kommen. Die Aufwärmphase sieht das übliche Zurücksetzen von Innen- und Außen abständen sowie die Definition von Hintergrundbild, Hintergrundfarbe, Schriftfarbe und Schriftarten vor. Als generelle Hintergrundfarbe dient ein dunkles Grün (#346560), kombiniert mit einem dekorativen, nicht wiederholten und recht großen Hintergrundbild. Als Schriftfarbe verwenden wir ein wirklich dunkles Weinrot (#602624) und als Schrift 11 Pixel Verdana.
Abbildung 26-2: hintergrund.gif, 348 x 1240 Pixel (hier verkleinert dargestellt)
Wir beginnen mit etwas generellem Styling. Während der reguläre Text »sitzt«, soll die Überschrift (wir verwenden ein h1-Element, da wir nur dieses Snippet haben) weiß sein, mit einer Schriftgröße von 11 Pixeln, entsprechend also der regulären Schriftgröße. Außerdem brauchen sowohl die Überschrift als auch der Absatz eine Hintergrundfarbe. h1 { background: #86AD2C; color: #FFF; font-size: 1em; } p { background: #FFF; }
Für beide Elemente definieren wir nun die Innenabstände, für ihre Container legen wir die Breite fest (skalierbar, versteht sich): h1, p { padding: .2em .7em; } div#abschnitt1, div#abschnitt2 { width: 15em; }
Nun zur Abrundung, bei der wir etwas mehr ins Detail gehen wollen. Sehen wir uns zuerst noch mal das Markup an, das wir oberhalb der Überschrift verwenden: <span class="e-oben"> <span class="e1"> <span class="e2"> <span class="e3"> <span class="e4">
In Alessandro Fulcinitis Originalentwurf werden für den zu erzielenden Effekt b-Elemente eingesetzt. Da diese aber als »veraltet« anzusehen sind (da rein präsentationsbezogen), verwenden wir offiziell nicht-semantische spanElemente. Okay, als »Code-Tuning« kann man das nicht unbedingt bezeichnen, aber aus semantischer Sicht ist das die einzig richtige Vorgehensweise. Heben wir uns weitere Anmerkungen noch etwas auf, auch wenn hier etwas Vernichtendes in der Luft liegt, und kümmern wir uns um unser CSS, um den Effekt an sich. Unsere erste Maßnahme ist, die span-Elemente zu BlockElementen zu machen, da sie die ganze Breite über und unter Überschrift und Absatz ausnutzen sollen (die abschnitt-Container stellen dabei eine »natürliche« Abgrenzung dar): .e-oben, .e-unten { display: block; }
Dabei setzen wir die Höhe der Kinder-span-Elemente auf 1 Pixel. Dem Internet Explorer 6 widmen wir zwei zusätzliche Deklarationen, font-size: 1px; und overflow: hidden;, da die Höhendefinition sonst nicht angewendet würde. Was wir bislang kreiert haben, ist gewissermaßen ein »Stapel« von vier Elementen, die alle ein Pixel hoch sind. Damit sich diese farblich ins Bild fügen, gleichen wir sie den mit ihnen assoziierten Elementen (Überschrift und Absatz) an: #abschnitt1 .e-oben *, #abschnitt1 .e-unten * { background: #86AD2C; } #abschnitt2 .e-oben *, #abschnitt2 .e-unten * { background: #FFF; }
Dadurch können wir mit einem einfachen Kniff die Abrundung erzielen. Wir definieren also nun für jedes einzelne span-Element einen Außenabstand zu den Seiten – je weiter oben bzw. unten, desto größer. In Kombination mit den zuvor definierten Hintergrundfarben wirken die Ecken jetzt abgerundet. .e-oben .e1, .e-unten .e4 { margin: 0 5px; } .e-oben .e2, .e-unten .e3 { margin: 0 3px; } .e-oben .e3, .e-unten .e2 { margin: 0 2px; } .e-oben .e4, .e-unten .e1 { height: 2px; margin: 0 1px; }
Bevor wir noch ein, zwei Kleinigkeiten anpassen – was ist überhaupt das Problem bei dieser Geschichte? Zum einen ist es der massive Gebrauch von nicht-semantischem Markup. Zwar sind span-Elemente (wie auch div) prinzipiell legitim, aber in dieser Form schädlich, weil hier keinerlei Struktur vermittelt wird. Letztlich ist es also nur ein auf die Darstellung bezogener »Hack«.
206
Teil IV: Effekte, Hingucker und Zaubereien
Zum anderen steht der Einsatz von solchen Markup-Konstrukten in keinerlei vernünftigem Verhältnis mehr zum Nutzen und zum eigentlichen, strukturellen Markup, so dass dieses Vorgehen in gewissem Sinne »unwirtschaftlich« ist. In unserem Fall macht diese Angelegenheit sicher schon 80% des gesamten Codes aus. Dass ein alternativ zu verwendendes Bild vielleicht immer noch größer wäre und mehr Ladezeit bedeuten würde, darf vor allem wegen der Semantik-Problematik nicht täuschen. Auch wenn moderne Webentwicklung durchaus immer mal etwas mit Kompromissen zu tun hat – der Kompromiss in diesem Szenario ist ein fauler. Noch eine letzte Anpassung: Der Absatz-Container soll ein Stückchen nach rechts sowie unter die Überschrift geschoben werden. Wie machen wir das am besten? Indem wir positionieren. Wir bedienen uns des »Stacking Context« und damit der z-index-Eigenschaft, um dafür zu sorgen, dass der untere Container nicht über, sondern wirklich unter dem oberen Container, also der Überschrift, landet. div { position: absolute; } div#abschnitt1 { z-index: 1; } div#abschnitt2 { left: 3em; top: 1.5em; } p { padding-top: 1em; }
Im Schnelldurchlauf: Die erste Regel bedeutet Positionierungsaction. Die zweite Regel besagt: abschnitt1 besitzt im lokalen »Stacking Context« das »Stack Level« 1 (Standardwert ist auto). abschnitt2 wird um drei Geviert nach rechts und anderthalb Geviert nach unten geschoben. Die letzte Regel schließlich bewirkt, dass Absätze einen Innenabstand von einer »em«-Höhe nach oben haben, was unseren eingangs für Überschriften und Absätze definierten Wert »überschreibt«.
Tipp
In CSS 3 werden wir die dargestellte Abrundung wesentlich leichter und eleganter sowohl durch die Eigenschaft borderradius als auch durch die background -Eigenschaft erreichen können. background-image war tet dann mit etwas auf, das wir uns schon länger wünschen: mehr als ein Hintergrundbild definieren zu können.
CSS-Überblick Zum Abschluss hier noch einmal alle CSS-Zuweisungen zusammen: * { margin: 0; padding: 0; }
Referenzen • Alessandro Fulciniti: Schicke Ecken http://pro.html.it/esempio/nifty/ • Alessandro Fulciniti: Mehr schicke Ecken http://pro.html.it/articoli/id_599/idcat_31/pag_1/pag.html • CSS-Spezifikation: Die z-index-Eigenschaft http://www.w3.org/TR/CSS21/visuren.html#z-index • CSS 3-Entwurf: Die background-image-Eigenschaft http://www.w3.org/TR/css3-background/#the-background-image • CSS 3-Entwurf: Die border-radius-Eigenschaften http://www.w3.org/TR/css3-background/#the-border-radius
Kapitel 26, Abgerundete Ecken
209
Bilder im Fließtext
Dies ist ein kleines Bilderexperiment, das aufzeigen wird, wie fließende Bilder etwas spannender integriert werden können, und das uns gleichzeitig einige Einsichten vermitteln kann. Als Experiment, das seine Schwächen hat, muss es aber niemand unbedingt nachahmen. Es dient lediglich zur Veranschaulichung.
27 Schwierigkeitsgrad: einfach
Abbildung 27-1: Bilder im Fließtext
211
Abbildung 27-2: kopf-01.gif, 241 x 15 Pixel
Abbildung 27-3: kopf-02.gif, 259 x 15 Pixel
Abbildung 27-4: kopf-03.gif, 270 x 15 Pixel
Abbildung 27-5: kopf-04.gif, 278 x 15 Pixel
Abbildung 27-6: kopf-05.gif, 284 x 15 Pixel
Abbildung 27-7: kopf-06.gif, 290 x 15 Pixel
Abbildung 27-8: kopf-07.gif, 293 x 15 Pixel
Abbildung 27-9: kopf-08.gif, 292 x 15 Pixel
Abbildung 27-10: kopf-09.gif, 299 x 15 Pixel
Abbildung 27-11: kopf-10.gif, 310 x 15 Pixel
Abbildung 27-12: kopf-11.gif, 313 x 15 Pixel
Wie sind wir auf die Idee gekommen? Nun, hier hat uns CSS-Koryphäe Eric Meyer inspiriert. Unsere kleine Bastelei beruht auf dem folgenden Markup:
Viele Bilder, viele Einzelteile. Und viele, viele leere alt-Texte, da wir hier mit nun wirklich rein dekorativen Bildern hantieren. Das ist auch der Grund für die nicht empfohlene Nachahmung – anstatt einem sehr viele Bilder, anstatt wenig sehr viel Markup und damit auch ein ungünstigeres Verhältnis von Inhalt (Text) zu Struktur (HTML). Die Formatierung der Seite ist dabei trivial. Zuerst die Hintergrund- und Textzuweisungen: html { background: url(bilder/hintergrund.jpg); color: #EEE; font: 81.25%/1.4 verdana, arial, helvetica, sans-serif; }
Abbildung 27-13: kopf-12.gif, 307 x 15 Pixel
212
Teil IV: Effekte, Hingucker und Zaubereien
Abbildung 27-15: kopf-13.gif, 301 x 15 Pixel
Abbildung 27-16: kopf-14.gif, 299 x 15 Pixel
Abbildung 27-14: hintergrund.jpg, 197 x 169 Pixel
Im Vergleich zu den Absätzen setzen wir für die Überschrift eine etwas größere, weiße Schrift. Für die Absätze definieren wir einen Außenabstand von einer »em«-Höhe nach oben und unten, auch wenn wir exemplarisch lediglich ein p-Element verwenden. h1 { color: #FFF; font-size: 1.2em; } p { margin: 1.2em 0; }
Dem Container, der den Text und unsere Bilder enthält, geben wir eine feste Breite vor, mit zwar nicht viel, aber ausreichend Luft zur Textvergrößerung: div { width: 540px; }
Womit wir zum eigentlichen Trick kommen: Die Unmenge an Bildern lassen wir fließen. img { float: right; }
Aber das reicht noch nicht ganz. Damit »pro Zeile« nur ein Bild angezeigt wird, müssen wir die clear-Eigenschaft benutzen, den kongenialen Partner, wenn es um Floats geht. Sie wird folgerichtig mit einem right-Wert versehen. Und damit die Bilder nicht direkt am Text kleben, setzen wir einen Außenabstand nach links. img { clear: right; float: right; margin-left: 28px; }
Abbildung 27-17: kopf-15.gif, 294 x 15 Pixel
Abbildung 27-18: kopf-16.gif, 294 x 15 Pixel
Abbildung 27-19: kopf-17.gif, 292 x 15 Pixel
Abbildung 27-20: kopf-18.gif, 248 x 15 Pixel
Abbildung 27-21: kopf-19.gif, 235 x 15 Pixel
Abbildung 27-22: kopf-20.gif, 231 x 15 Pixel
Abbildung 27-23: kopf-21.gif, 231 x 15 Pixel
Abbildung 27-24: kopf-22.gif, 235 x 15 Pixel
Abbildung 27-25: kopf-23.gif, 249 x 15 Pixel
Abbildung 27-26: kopf-24.gif, 260 x 15 Pixel
Kapitel 27, Bilder im Fließtext
213
Referenzen Abbildung 27-27: kopf-25.gif, 267 x 15 Pixel
• Eric Meyer: »Zottiger Float« http://www.meyerweb.com/eric/css/edge/raggedfloat/demo.html
Abbildung 27-28: kopf-26.gif, 273 x 15 Pixel
Abbildung 27-29: kopf-27.gif, 277 x 15 Pixel
Abbildung 27-30: kopf-28.gif, 281 x 15 Pixel
Abbildung 27-31: kopf-29.gif, 283 x 6 Pixel
214
Teil IV: Effekte, Hingucker und Zaubereien
Mini-Kochbuch
Ein echter Leckerbissen wartet auf uns, nicht nur in Form schmackhafter Rezepte, sondern auch durch ihre Verpackung. Auf einer fiktiven Webseite wollen wir eine kleine und gut verstaubare kulinarische Ecke einrichten.
28 Schwierigkeitsgrad: schwer
Abbildung 28-1: Mini-Kochbuch
215
Schon vor dem ersten Markup setzen wir unser Stylesheet auf. html { background: #FFF; color: #000; font: 68.75%/1.3 verdana, arial, helvetica, sans-serif; }
Unsere Inhalte folgen gleich im Anschluss. Auf das »Menü«, über das die Benutzer die einzelnen Rezepte erreichen, verzichten wir vorerst. An Bord kommen zunächst ein Hilfscontainer in Form eines div-Elements, mit IDs versehene h2-Elemente (h1 folgt noch) sowie darunter die Rezepte, strukturiert durch Absätze und jeweils eine h3-Überschrift, die die Zubereitung ankündigt.
Avocadosuppe mit Mais
…
Broccolisuppe
…
Erbsensuppe mit Minze
…
Kartoffelsuppe
…
Pilzrahmsuppe
…
Der Rezeptebereich soll derart gestaltet sein, dass nur ein bestimmter Platz zur Verfügung steht (293 x 392 Pixel) und dementsprechend ein Scrollbalken vorhanden ist. Dazu brauchen wir nur die Breite und Höhe sowie ein overflow: auto; zu definieren. Die overflow-Deklaration äußert sich in jeder Implementierung dadurch, dass bei unseren Inhalten ein Scrollmechanismus zur Verfügung steht. div#rezepte { height: 392px; overflow: auto; width: 295px; }
Im zweiten Schritt folgen die hellblaue Hintergrundfarbe und der Innenabstand. Der Innenabstand bedeutet für uns, dass wir aufgrund des Boxmodells Breite und Höhe nochmals anpassen müssen. Die div-Regel sieht in ihrer Gesamtheit dann wie folgt aus: div#rezepte { background: #ECF2F7; height: 372px; overflow: auto; padding: 10px 10px 10px 30px; width: 255px; }
Mit den Überschriften und Absätzen halten wir uns nicht lange auf. Den Überschriften geben wir lediglich die Schriftgröße vor, den Absätzen einen 216
Teil IV: Effekte, Hingucker und Zaubereien
Außenabstand nach oben und unten. Über unsere Struktur können wir sehr effektiv vorgehen: Da in unserem Fall zwei Überschriften nie direkt aufeinander folgen, müssen wir dort keine Abstände vorgeben. h2 { font-size: 1.3em; } h3 { font-size: 1em; } p { margin: 1em 0; }
Diese ersten Regeln sorgen für eine schlichte Formatierung des Rezepte bereichs. Wir ergänzen jetzt das Markup durch zwei div-Elemente, die wir verwenden, um oberhalb und unterhalb der Rezepte jeweils eine Abrundung nach rechts zu erzielen.
…
Über eine generische Regel – sie verwendet lediglich einen div-Element selektor – geben wir mehrere Hintergrundeigenschaften (Farbe, Position, Wiederholung) sowie die Schriftgröße, Breite und Höhe vor: div { background: #ECF2F7 top right no-repeat; font-size: 1px; height: 6px; width: 295px; }
Eigentlich würden diese Deklarationen auch für den zuvor behandelten rezepte-Container gelten. Aufgrund der höheren Spezifität jedoch haben die dortigen Deklarationen ein höheres Gewicht; wir müssen uns darum also gar nicht kümmern und können somit eleganteren Code schreiben. Zur background-Deklaration sind zwei Dinge erwähnenswert: Zum einen önnen wir die über die div#rezepte -Regel angegebene background k Deklaration, die nur die Farbe vorgegeben hat, jetzt entfernen. Zum anderen ebnen wir uns so den Weg für die eigentliche Abrundung, denn den Containern oben und unten muss nun einfach nur das jeweilige Bild zugewiesen werden. Die font-size-Deklaration hingegen dient lediglich dem Internet Explorer 6, damit die Höhe der beiden Hilfscontainer nicht »gesprengt« wird. Da sie direkt auf div angewendet wird, ist es erforderlich, dem Rezeptebereich wiederum explizit ein font-size: 1em; zuzuweisen. (Ein Überblick über das komplette Stylesheet folgt am Ende des Kapitels.) Kapitel 28, Mini-Kochbuch
217
Gut, hier also die Abrundungen:
Abbildung 28-2: ecke-oben.gif, 16 x 6 Pixel (hier vergrößert dargestellt)
Abbildung 28-3: ecke-unten.gif, 16 x 6 Pixel (hier vergrößert dargestellt)
Beim ersten Styling orientieren wir uns an dem Hintergrundbild, das wir für die Liste vorgesehen haben. Es ist 206 x 458 Pixel groß und gibt uns damit exakt die Maße des nav-Containers vor: div#nav { height: 458px; width: 206px; }
Das Hintergrundbild stellt – wie bereits an einigen anderen Stellen im Buch – eine besondere Herausforderung dar, denn wir möchten nicht nur Transparenz, sondern auch, dass darunter liegende Inhalte durchscheinen. Das riecht nach dem Einsatz von PNGs, aber diese werden vom Internet Explorer erst seit Version 7 unterstützt. Um dieses Problem zu umschiffen, wenden wir einen Kindselektor an, da die Browser, die Kindselektoren unterstützen, glücklicherweise auch PNGs mögen. Der Internet Explorer bis Version 6 erhält somit alternativ ein GIF. Abstriche hinsichtlich der Qualität sind aufgrund der Art des Bildes und der benötigten Transparenz unvermeidbar. div#nav { background: url(bilder/klecks.gif); }
Abbildung 28-4: klecks.gif, 206 x 458 Pixel
218
Teil IV: Effekte, Hingucker und Zaubereien
body > div#nav { background: url(bilder/klecks.png); }
Wir widmen uns nun dem nächsten Schritt, der Positionierung. Das Menü soll erst mal über die Rezepte gelegt werden, diese also teilweise über decken. div#nav { position: absolute; top: 0; }
Damit auch die Darstellung im Safari unseren Vorstellungen entspricht, müssen wir noch eine Deklaration hinzufügen. Safari droht sonst, den Rezeptebereich über und nicht unter dem Menü darzustellen. div#nav { z-index: 1; }
Da das Menü jetzt an der richtigen Stelle sitzt, kümmern wir uns nun um die h1-Überschrift, das ul-Element sowie die enthaltenen Links. h1 { color: #FFF; font-size: 1.3em; margin: 50px 7px 0; }
Dabei wenden wir dieselbe Schriftgröße wie bei h2 an und ziehen eine weiße Schriftfarbe sowie einen gesunden Außenabstand heran. Durch die gleichlautenden Deklarationen von color (dieselbe Farbe erhalten auch die Links) und font-size (h2) besteht natürlich Potenzial zur Vereinfachung.
Abbildung 28-5: klecks.png, 206 x 458 Pixel
Beim ul-Element entfernen wir die Listenmarker und definieren ebenfalls einen Außenabstand: ul { list-style: none; margin: 5px 7px; }
Die Links sollen weiß, fett und nicht unterstrichen sein. Die line-heightDeklaration benutzen wir dazu, um mehr Luft zu schaffen. Auf diesem Wege brauchen wir uns den li-Elementen nicht noch separat zu widmen. a { color: #FFF; font-weight: bold; line-height: 1.8; text-decoration: none; }
Für die beiden Zustände :focus und :hover haben wir uns etwas Besonderes ausgedacht. In beiden Fällen wollen wir einen Pfeil vor dem entsprechenden Eintrag anzeigen. Um diesen Effekt zu erzielen, brauchen wir nur ein Kapitel 28, Mini-Kochbuch
219
nicht wiederholtes Hintergrundbild zu definieren und diesem über einen Innenabstand Platz nach links zu schaffen. a:focus, a:hover { background: url(bilder/pfeil.gif) 0 2px no-repeat; padding-left: 10px; }
Abbildung 28-6: pfeil.gif, 6 x 10 Pixel (hier vergrößert dargestellt)
Noch sind wir nicht ganz fertig. Unser Problem besteht darin, dass das erste Rezept gar nicht ganz sichtbar ist. Dasselbe Problem besteht auch bei allen anderen Rezepten, wenn sie über das Menü aufgerufen werden – ihr »Startpunkt« liegt oben links im rezepte-Container. Es ist aber nicht schwer, dies zu ändern. Wir müssen nur für entsprechende »Luft« sorgen. Das erreichen wir, indem wir zunächst die h2-Elemente mit einem großen Innenabstand versehen – so groß, dass das erste Rezept frei sichtbar ist. h2 { padding-top: 175px; }
Da nun große »Löcher« zwischen den einzelnen Rezepten klaffen, müssen wir nochmals gegensteuern. Wir legen einen kompensierenden negativen Außenabstand an: h2 { margin-top: -175px; }
Wir schließen das Unterfangen damit ab, das erste Rezept bzw. dessen Überschrift von der letzten Zuweisung »freizusprechen« – es soll gleich mit einem Abstand nach oben beginnen: Abbildung 28-7: Hover-Effekt in Aktion
h2#rezept-1 { margin-top: 0; }
Bevor wir das aus den einzelnen Schritten resultierende Stylesheet noch einmal begutachten, sollten wir uns über die folgenden Punkte im Klaren sein: Die Umsetzung ist, wie eingangs erwähnt, nicht unproblematisch, was die Benutzerfreundlichkeit anbelangt. Es müssen nicht unbedingt Nutzertests her, um das prognostizieren zu können. Um diesen Umstand ein wenig abzumildern, ging es unter anderem darum, bei einer kleinen Auflösung wie 800 x 600 Pixel unbedingt doppelt vorkommende Scrollbalken zu vermeiden. Das sollte auch erreicht worden sein, aber es könnte Browserkonfigurationen geben (zum Beispiel mit mehreren installierten Toolbars), wo zwei Scrollbalken auftauchen. Das gilt es grundsätzlich zu bedenken.
Eine Pullquote – ein hervorgehobenes, in den Fließtext eingebettetes Zitat – haben wir bereits in unsere »Web-Bücherei« integriert (siehe Kapitel 2). Weil man Pullquotes durchaus öfter nutzen kann, setzen wir sie noch einmal in einem anderen Kontext um.
29 Schwierigkeitsgrad: einfach
Abbildung 29-1: Pullquote
223
Die initialen Zuweisungen erledigen wir im Schnelldurchlauf, da sie in diesem Buch immer wieder so verwendet werden. html { background: #F5F3EB; color: #000; font: 81.25%/1.3 verdana, arial, helvetica, sans-serif; } body { padding: 50px; width: 450px; }
Ein kurzer Überblick über die Struktur des Markups, das wir minimal und elegant gestalten:
Der Franzose
Lorem ipsum […]
<span>»Die Art, […]<span>«
In eros […]
Die folgende Regel bewirkt, dass die Überschrift fett und kursiv, mit anderthalbfacher Größe und in Georgia dargestellt wird: h1 { font: bold italic 1.5em georgia, serif; }
Die die Absätze betreffende Regel legt lediglich einen Außenabstand nach oben fest: p { margin-top: 1em; }
Die Pullquote haben wir nicht nur in einem semantisch richtigen blockquote-Element eingebunden, sondern sie darin auch mit zwei span-Elementen und einem em -Element versehen. Während die Anführungszeichen keine weitere Bedeutung haben und deshalb zur Formatierung auch in den spanElementen stehen, wird der Textabschnitt »verzückte« durch das em -Element semantisch betont, wie es die entsprechende Passage illustriert:
<span>»Die Art, wie er das Spielgerät liebkoste, <em>verzückte seine Anhänger<span>«
Um dieses Zitat visuell hervorzuheben, nehmen wir es mittels der floatEigenschaft aus dem normalen Fluss heraus und geben ihm eine Breite von 250 Pixeln: blockquote { float: right; width: 250px; }
224
Teil IV: Effekte, Hingucker und Zaubereien
Da sich zur Wahrung der Kompatibilität mit XHTML 1.1 im blockquoteElement noch ein Absatz befindet, setzen wir den zuvor global definierten Außenabstand zurück: blockquote p { margin: 0; }
Nun können wir mit der Formatierung der Pullquote beginnen. Die folgenden Deklarationen sorgen für eine kursiv gestellte Serifenschrift in Form von Georgia (analog zur Überschrift), in einer vom normalen Text abweichenden Farbe. Die Zeilenhöhe verkleinern wir dabei etwas (relativ gesehen), justieren den Außenabstand, den das Zitat nach oben, unten und links haben muss, und zentrieren den Text. blockquote { color: #927B6B; font: italic 2em/1.2 georgia, serif; margin: .3em 0 .7em .5em; text-align: center; }
Der »Wichtigkeit«, die wir dem Text »verzückte« beimessen, zollen wir lediglich über eine Anpassung der Textfarbe Tribut: blockquote em { color: #87420F; }
Verbleiben nur noch die Anführungszeichen. Mit der Eigenschaft color ändern wir die Farbe und durch die font-weight-Eigenschaft geben wir fette Anführungszeichen vor. Außerdem schaffen wir ein bisschen Luft über einen moderaten Innenabstand von einem fünftel »em« zu den Seiten. So lassen wir uns gar nicht erst darauf ein, das öffnende Anführungszeichen nur rechts und das abschließende Anführungszeichen nur links mit einem solchen Abstand zu bedenken. Ohne CSS 3-Selektoren wie :last-child wären wir gezwungen, spezielle Klassen oder IDs zu verwenden. blockquote span { color: #BAB9B3; font-weight: bold; padding: 0 .2em; }
Unserer Absicht, die Anführungszeichen besonders plakativ zu gestalten, indem wir die Schriftgröße stark erhöhen, können wir nur bedingt nachkommen. Das Problem besteht in der Zeilenhöhe des Zitats selbst, die die Grenze für dieses Unterfangen darstellt. Erhöhen wir die Schriftgröße der Anführungszeichen, führt das zumindest optisch zu einer übergroßen Höhe der letzten Zeile. Da wir dem normalen Text keine übermäßige Höhe vorgeben wollen, können wir die Textgröße lediglich ein bisschen erhöhen, bei gleichzeitiger Verringerung der Zeilenhöhe.
Eine bekannte Problematik beim Webdesign sind Bildunterschriften. Weder berücksichtigen die aktuellen Spezifikationen HTML 4.01 und XHTML 1.1 sie durch spezielles Markup, noch ist davon etwas in dem aktuellen Entwurf zur Spezifikation XHTML 2.0 zu lesen.
30 Schwierigkeitsgrad: einfach
Abbildung 30-1: Bildunterschriften
227
Wir werden drei mögliche Lösungen durchgehen, die auf ordinären Hilfscontainern, Definitionslisten sowie Ruby-Markup basieren. Da Ruby erst in XHTML 1.1 aufgenommen wurde, verwenden wir auf unserer Testseite ausnahmsweise XHTML 1.1, dem falschen MIME-Typ text/html zum Trotz. Wir besorgen uns ein Musterbild und definieren neben dem globalen Zurücksetzen von Innen- und Außenabständen noch vier weitere Regeln: html { background: #D5E3FF; color: #40444C; font: 81.25%/1.4 georgia, serif; } body { padding: 50px; } p { margin-bottom: 1em; text-indent: 1em; } img { background: #FFF; border: 1px solid #ACB6CC; padding: 2px; }
Neben den üblichen Farb- und Schriftzuweisungen handelt es sich hier um einen Innenabstand (auf body), der uns auf unserer Testseite Rand zu den Seiten sichert, sowie um einen Außenabstand und eine Einrückung für den Blindtext auf dem p-Element. Das Testbild (img) erhält jeweils einen Rahmen. Über einen Innenabstand sowie weiße Hintergrundfarbe kriegt es etwas Feinschliff, der Rahmen wird so optisch durch einen zwei Pixel breiten weißen sowie einen ein Pixel breiten blasslila Streifen gebildet.
Weg 1: Hilfscontainer Die erste Methode basiert auf dem folgenden Markup, wobei wir das Musterbild immer im vom Blindtext repräsentierten Fließtext darstellen:
Ein angriffslustiger Raubvogel.
Lorem ipsum […]
…
Abbildung 30-2: schwan.jpg, 225 x 255 Pixel
228
Die gewünschte Darstellung ist einfach zu erreichen, indem wir dem divElement die Breite des Bildes (zuzüglich seines Rahmens) zuweisen – so rutscht der Bildtext automatisch unter das Bild. (Eine alternative Variante Teil IV: Effekte, Hingucker und Zaubereien
besteht darin, den Text in einem Absatz zu verpacken, auch wenn der Text nicht wirklich einem Absatz entsprechen muss.) Die auf center gesetzte text-align-Eigenschaft sorgt für die Zentrierung. div { text-align: center; width: 231px; }
Zwei weitere Deklarationen sorgen dafür, dass der Container mitsamt Bild und Bildunterschrift in den Text »integriert« wird, nämlich float: left; sowie margin: 0 1em 1em 0;. Die erste Deklaration lässt ihn in den Text »fließen«, die zweite sorgt für etwas Abstand nach rechts sowie nach unten. Was sind die Vor- und Nachteile dieser Vorgehensweise? Ein Vorteil ist definitiv die Einfachheit. Ein Außencontainer reicht, für die Bildunterschrift selbst ist kein weiteres Markup notwendig. Zwei Punkte sind als nachteilig zu sehen: Man muss die Bildbreite kennen – auch wenn es je nach Text einen gewissen Toleranzbereich gibt –, sofern man Bilder fließen lassen will. In unserem Fall wäre es kein Problem, als Breite zum Beispiel 235 Pixel zu wählen, da der Text dennoch unter dem Bild landet. Ein größeres Problem sind per se die mangelnde Semantik (es gibt lediglich ein divElement) sowie der Umstand, dass es keine echte Verknüpfung von Bild und Bildunterschrift gibt.
Weg 2: Definitionsliste Die zweite Variante gleicht einen Nachteil der »Hilfscontainer«-Methode aus, denn sie assoziiert Bild und Bildunterschrift:
Ein angriffslustiger Raubvogel.
Von der width -Deklaration abgesehen, verwenden wir hier dieselben Zuweisungen wie bei Weg 1, allerdings demonstrativ im Rechtsfluss und mit einem entsprechenden Außenabstand nach links. Die Motivation ist die gleiche, wir wollen das dl-Element mit etwas Abstand in Richtung Text sowie einer Zentrierung fließen lassen. dl { float: right; margin: 0 0 1em 1em; text-align: center; }
Nachdem wir zuvor die fehlende Verknüpfung von Bild und seinem Text bemängelt und hier vermieden haben, sind wir froh, auch gleich die zweite Hürde genommen zu haben, denn wir müssen in diesem Fall auch nicht die Breite des Bildes kennen und angeben. Die Definitionsliste ist eine gute Kapitel 30, Bildunterschriften
229
Lösung, wenn man davon absieht, dass auch sie semantisch nicht ganz korrekt ist, denn mit dd »definieren« wir das Bild nicht. Drei Anmerkungen zur Darstellung: In Gecko-basierten Browsern wie Mozilla oder Firefox tritt ab und zu das Phänomen auf, dass die Bildunter schrift nicht zentriert ist. Da das nicht immer passiert und zudem nach einer Aktualisierung der Seite verschwindet, weisen wir lediglich darauf hin. Ohne das bei uns generell immer eingesetzte Zurücksetzen von Innen- und Außenabständen muss ansonsten zumindest der Definitionsbeschreibung (dd) explizit der Außenabstand entzogen, also auf 0 gesetzt werden. In eigentlich allen Fällen sorgt sonst das jeweilige User-Agent-Stylesheet für einen Abstand, so dass die von uns gewünschte Darstellung nicht erzielt wird. Des Weiteren ist ein kleiner Unterschied zwischen Weg 1 und Weg 2 auszumachen, was den Abstand zwischen Bild und Bildunterschrift betrifft. Über die line-height-Eigenschaft könnte man daran feilen, wir verzichten aber auf eine Anpassung, da man üblicherweise nur einen der Wege beschreitet und deshalb keinerlei Darstellungsinkonsistenzen befürchten muss.
Weg 3: Ruby-Markup Wenn es um Bildunterschriften geht, taucht auch immer wieder die Überlegung auf, dafür Ruby-Markup zu benutzen (siehe den folgenden Infokasten). Auch wenn wir den Weg über Ruby skizzieren wollen, ist grundsätzlich zu bedenken, dass Ruby nicht für Bildunterschriften gedacht ist, wir also einen semantischen Fauxpas begehen, und dass uns die Anwendung von einfachem Ruby-Markup keine Bildunterschrift, sondern eine Bildüberschrift beschert (so will es die Spezifikation). Besondere Erwähnung sollte zudem der Stand der Implementierung finden: Bis dato »versteht« immer noch nur der Internet Explorer (und das auch schon seit den 5er-Versionen) Ruby-Markup. Da wir immer wieder auf Situationen stoßen, in denen uns der Internet Explorer einen Strich durch die Rechnung macht oder nach Sonderlösungen verlangt, muss diese Erwähnung gar lobend ausfallen. Das Markup der Bildunterschrift sieht wie folgt aus, wobei das äußere div-Element durch die Spezifikation verlangt wird, da Ruby-Markup kein direktes Kind von body sein darf:
230
Teil IV: Effekte, Hingucker und Zaubereien
Ein Blick in die Spezifikation
Ruby-Markup Ruby ist eine Darstellungsform, die in ostasiatischen Sprachen verwendet wird. Visuell wird ein sogenannter »Basistext« hervorgehoben, über und unter dem ein weiterer Text dargestellt werden kann, der als »Ruby-Text« die Lesart oder eine Erläuterung des Basistextes wiedergibt. Das W3C hat 2001 im Rahmen der XHTMLModularisierung ein Ruby-Modul aufgenommen, das definiert, wie Markup für solche Fälle auszusehen hat und interpretiert werden muss. Grundsätzlich gibt es zwei Arten von Ruby-Markup, nämlich einfaches und komplexes. Einfaches Ruby-Markup ermöglicht lediglich die Hervorhebung des Basistextes (rb, »Ruby Base«) sowie des entsprechenden Textes (rt, »Ruby-Text«) innerhalb eines ruby-Elements: WWW
Komplexes Ruby-Markup kann größere Zusammenhänge abbilden und stellt dafür zusätzliche Elemente bereit. Es umfasst besondere Container für Basis- wie auch RubyText, rbc (»Ruby Base Container«) und rtc (»Ruby Text Container«). Ein der Spezifikation nachempfundenes Beispiel: 31122008
Der Text »Tag Monat Jahr« würde in diesem Fall über, »Verfallsdatum« unterhalb des Basistextes »31 12 2008« stehen.
Abbildung 30-3: Darstellung von Ruby-Text und Basistext
Wir verzichten auf das noch nicht erwähnte »einfache Ruby-Markup mit Parenthesen«. Dieses dient der Kompatibilität mit User-Agents, die RubyMarkup nicht interpretieren, indem es ein rp-Element zur Verfügung stellt (»Ruby Parenthesis«). Der Ruby-Text müsste in diesem Fall wie folgt aussehen: <rp>( <rp>)
Da bei einer Nichtinterpretation von Ruby einfach der umklammerte Text ausgegeben wird, resultiert das üblicherweise in der Ausgabe »(Ein angriffslustiger Raubvogel.)«. Um im Internet Explorer die gewünschte Darstellung zu erzielen, genügen die beiden folgenden Regeln:
Die Zuweisungen für das ruby-Element haben wir auch in den anderen beiden Vorgehensweisen angewendet und erläutert: Wir lassen das Element fließen und weisen ihm einen Außenabstand nach rechts und nach unten zu. Dem rt-Element hingegen geben wir vor, die »geerbte« Schriftgröße zu adaptieren. Die Bildunterschrift ist nun zwar eine Bildüberschrift, die gewünschte Formatierung wurde jedoch auf einfache Weise erreicht. Den meisten Browsern können wir noch ein wenig entgegenkommen. Wenn wir die ruby-Regel um zwei Deklarationen erweitern, erhalten wir unter anderem in Gecko-basierten Browsern und Opera sogar das exakte Ergebnis unserer vorherigen Bemühungen: ruby { text-align: center; width: 231px; }
Da wir in Bezug auf Ruby-Markup bereits mit einigen »Besonderheiten« umgehen mussten, konstatieren wir lediglich, dass wir nun natürlich wieder die Breite des jeweiligen Bildes kennen müssen.
Fazit Wenn es um eine Empfehlung geht, was für Markup man für Bildunter schriften verwenden soll, wären mit leicht schalem Beigeschmack Definitionslisten zu nennen: Die Umsetzung verknüpft tatsächlich Bild und Bildunterschrift, das Styling ist einfach umzusetzen und die breite Unterstützung ist vorhanden. Die Nachteile der Hilfscontainer-Methode können jedoch adressiert werden, indem sie mit einem Absatz für die Bildunterschrift semantisch aufgewertet wird und die Methode bei Verzicht auf das Fließen der Bilder auch wartbar wäre. Bei der Ruby-Methode überwiegen die Nachteile jedoch eher den Nutzen. Es gibt sicherlich noch weitere Wege, zum Beispiel über Tabellen, die semantisch bestenfalls »fragwürdig« sind, oder bei breiterer Unterstützung auch über die content-Eigenschaft im Zusammenhang mit dem :afterPseudoelement. Etwas vereinfacht würde es dann reichen, folgende Regel zu verwenden:
232
Teil IV: Effekte, Hingucker und Zaubereien
img:after { content: attr(alt); display: block; }
Durch diese Regel wird hinter dem Bild sein Alternativtext ausgegeben und das Pseudoelement als Block-Element verstanden, wodurch es unter das Bild rutscht. Mit weiteren Zuweisungen, zum Beispiel den width- und textalign-Eigenschaften, könnte man die Darstellung zusätzlich aufwerten.
Hinweis
Mit dem »Media Microformat« ist aktuell ein Mikroformat in der Entwicklung, mit dem man Meta-Daten – wie eben Bildunterschriften – standardisiert mit Multimedia-Inhalten verknüpfen können soll.
Referenzen • Ruby-Spezifikation http://www.w3.org/TR/ruby/ • Ruby-Spezifikation (Übersetzung): Einfaches Ruby-Markup mit Parenthesen http://meiert.com/de/w3/TR/ruby/#simple-parenthesis • CSS-Spezifikation: Die :before- und :after-Pseudoelemente http://www.w3.org/TR/CSS21/selector.html#before-and-after • CSS-Spezifikation: Die content-Eigenschaft http://www.w3.org/TR/CSS21/generate.html#content • Microformats: Brainstorming for Media Microformat http://microformats.org/wiki/media-info-brainstorming
Kapitel 30, Bildunterschriften
233
Index A Alessandro Fulciniti 203, 209 Anne van Kesteren 19, 162, 166 anonymes Element 129
B Barrierefreiheitsrichtlinien xvii Benutzerfreundlichkeit xvii Bildersatztechniken siehe Image Replacement, Phark-Methode Bildschirmauflösungen 64 Bildschirmlesesoftware 65 blink-Wert 49 Bowman, Douglas 113, 114, 118 Boxmodell 69, 87, 88, 164 Browserkompatibilität xviii
C Cederholm, Dan 35, 37 Christian Heilmann xv CSS-Boxmodell 69 CSS 3 146, 183, 184, 207, 225 strukturelle Pseudoklassen 188
D Dan Cederholm 35, 37 Doubled Float-Margin Bug 6, 9 Douglas Bowman 113, 114, 118
E Epilepsie, fotosensitive 49 Eric Meyer 9, 212, 214
FIR 153, 154 Firefox xviii :first-child-Pseudoklasse 143 font-weight-Eigenschaft 123, 124 fotosensitive Epilepsie 49 Fulciniti, Alessandro 203, 209
G Gerrit van Aaken xx Gez Lemon 170 GMX GmbH 119
H hAccessibility 132 Hacks xviii hasLayout-Konzept xxi, 201, 202 hCalendar-Mikroformat xxi, 126, 127, 132 hCard-Mikroformat 127 Heilmann, Christian xv HTML 5 199 Hypertext-Attributsammlung 202
I IBM Home Page Reader 65, 153, 158 id-Attribut, Syntax 180 Image Replacement 141, 153, 154, 158 Inline-CSS 148 Internet Explorer xviii Doubled Float-Margin Bug 6, 9 hasLayout-Konzept 201, 202 PNGs 218 Probleme beim xix, 6, 13, 18, 24, 27, 32, 58, 73, 87, 108, 143, 149, 153, 160, 168, 170, 174, 175, 181, 195, 201, 206, 217, 218
J Jonathan Snook 170, 172
235
K Konqueror xviii
L label-Element 74 legend-Element, Probleme mit 161 Lemon, Gez 170 Lorem Ipsum-Generator xxi
M Malarkey Image Replacement 153 Media Microformat 233 Meyer, Eric 9, 212, 214 Mike Rundle xxi Mikroformate 125, 127, 132, 233 Mozilla xviii
Jens Meiert, geboren 1978, arbeitet als Frontend-Systemarchitekt für die Berliner Agentur Aperto. Er ist auf eine Vielzahl von Fachgebieten spezialisiert, die sich weitgehend um Webentwicklung, Barrierefreiheit, Usability und Informationsdesign ranken. Seine Expertise bringt Jens Meiert unter anderem in Organisationen wie W3C (bis 2006 WCAG-Arbeitsgruppe, seit 2007 HTML-Arbeitsgruppe), »Usability Professionals’ Association« (UPA) und »Interaction Design Association« (IxDA) ein, und er schreibt für diverse Magazine, von »Internet Professionell« bis »Dr. Web«. Mehr über Jens Meiert und hochwertiges Webdesign finden Sie auf seiner Webseite www.meiert.com.
Über die Autoren und Designer
Ingo Helmdach, Jahrgang 1981, arbeitet für die GMX GmbH im Bereich Konzeption und Webdesign. Auch außerhalb seines Berufs entwickelt er Websites und betreut und unterstützt verschiedenste Projekte im Internet. Er wohnt in München und beschäftigt sich gerne mit Fotografie, guten Büchern und Musik. Weitere Informationen über Ingo Helmdach und sein Schaffen finden Sie auf www.helmdach.de.
Das Design der vorliegenden Reihe wurde von David Futato mit InDesign CS entworfen. Das Coverlayout dieses Buchs hat Michael Oreal gestaltet. Als Textschrift verwenden wir die Linotype Birka, die Überschriftenschrift ist die Adobe Myriad Condensed, und die Nichtproportionalschrift für Codes ist LucasFont’s TheSansMono Condensed.