CSS 2.1 ::Artikel
Flexible Layouts mit CSS-Positionierungen
Das Original dieses Textes wurde zuerst am 15. November 2002 unter dem Titel Flexible Layouts with CSS Positioning im Online-Magazin A List Apart veröffentlicht. Der Autor ist Dug Falby. Die Übersetzung erfolgte mit Genehmigung von A List Apart und dem Autor.
Translated with the permission of A List Apart Magazine and the author.
Einleitung
Der Grund, aus dem dieser Aufsatz geschrieben wurde, war die wachsende Zahl von Artikeln mit Tipps und Tricks, die in den letzten Jahren aufgetaucht ist. Typische Merkmale dieser Artikel sind die dreispaltigen Designs mit fest positionierten Spalten in den Margins rechts und links sowie die Verwendung von @import
anstelle von JavaScript, um unterschiedliche Browser mit passenden Stylesheets zu versorgen.
Diese Konzepte sind alle sehr gut, aufrichtiges und deutliches Lob für ihre Autoren ist deshalb auch sicher angebracht, aber ich werde das Gefühl nicht los, dass wir genau so etwas schon einmal hatten.
Erinnern Sie sich noch an die Zeiten, als Sie versuchten, eine Tabelle mit Images ohne Lücken auszugeben? Oder daran, wie Sie versuchten, dem Tabellenalgorithmus Ihres Browsers auf die Spur zu kommen und Extrareihen einfügten, um die korrekte Ausgabe zu garantieren? Oder denken Sie manchmal an den durchaus noch größeren Sündenfall, als Sie nicht-standardskompatible Attribute wie marginwidth
verwendet haben?
Natürlich: als Webdesigner fühlen wir uns zu Tricks, Gimmicks, und Umgehungsregeln hingezogen, um das unmittelbar anstehende Problem zu lösen. Wir sollten uns aber besser auf die Dinge konzentrieren, die wir auf lange Sicht erreichen wollen.
Reelle Probleme
- Von meinen Designern erwarte ich, dass sie CSS verwenden. Sie sollen sich nicht hinter WYSIWIG - Programmen verstecken, sondern wirklich verstehen, was sie tun.
- Ich möchte universelle, flexible Layouts. Idealerweise sollte eine Zeile Text so breit wie eine bestimmte Anzahl Textzeichen sein, nicht eine willkürlich bestimmte Länge in Pixeln haben. Die Information des Kunden muss auf einem PDA-Display von 160×160 Pixel genauso nützlich sein wie auf einem Bildschirm der Größe 1024×768.
- Es ist wichtig, dass das Team weniger Zeit in CSS-Hacks steckt und mehr für die direkte Umsetzung des Designs aufwendet.
- Ich brauche ein flexibles Grid-Design. Wenn das Konzept ein sechs-spaltiges Layout nahelegt, dann benötige ich ein 6-spaltiges Gitter. Dasselbe gilt, wenn ein 8-spaltiger Abschnitt über einem mit nur 4 Spalten stehen soll.
Praktische Einschränkungen
Auf der Suche nach der besten praxisorientierten Technik zum Aufbau eines Gitters hab ich mir selbst einige Einschränkungen auferlegt. Diese hängen davon ab, wie ich die Durchführbarkeit einer Designlösung bestimme: zum einen für mein Arbeitsumfeld (das Design-Studio), zum anderen für die Menschen, die diese Technik anwenden und weiterentwickeln müssen (Dreamweaver-verliebte Webdesigner).
- Einige Browser verstehen zwar die Regel
@import
, aber nicht das Box- Modell (besonders iCab ist in allem, was nicht CSS 2 betrifft, ein fantastischer Browser). Deshalb sollten keine@import
-Hacks verwendet werden. - Verschiedene Stylesheets für verschiedene Browser zu erstellen, ist oft unvermeidbar. Wenn man es tut, dann sollten die Stylesheets sich strukturell soweit wie möglich gleichen. Besonders die verwendeten ID-Selektoren sollten in allen Stylesheets gleich sein. Dadurch wird es für die Designer einfacher, mit dem Grid zu arbeiten.
- Ebenfalls um den Designern zu helfen, sollte jede Box innerhalb des Gitters einen eigenen Namen erhalten. Damit lassen sich typografische oder Rahmeneffekte verwirklichen, ohne einen Selektor einzufügen.
Lösungsmöglichkeiten
Im Folgenden schlage ich zwei Designmethoden vor, die den oben beschriebenen Erfordernissen entgegen kommen. Sie können als eine Art Überbrückung bis zu dem Zeitpunkt gesehen werden, an dem CSS-Design für alle Designer zur natürlichen Denkweise geworden ist.
Ein Webdesigner notiert ein dreiteiliges Layout mit mehreren Spalten so:
<div id="top-section"> <div id="top-col-1"> Inhalte hier </div> </div> <div id="mid-section"> <div id="mid-col-1"> Inhalte hier </div> <div id="mid-col-2"> Inhalte hier </div> <div id="mid-col-3"> Inhalte hier </div> <div id="mid-col-4"> Inhalte hier </div> </div> <div id="bottom-section"> <div id="bottom-col-1"> Inhalte hier </div> </div>
Der Designer sieht in diesem Code die XHTML-Struktur für einen einspaltigen Kopfteil, einen vierspaltigen Mittelteil und einen einspaltigen Fußteil. Er möchte, dass Mittel- und Fußteil der Seite ordentlich nach oben oder unten gleiten, ohne dass sie sich gegenseitig überdecken, abhängig von der Schriftgröße, die der Benutzer gewählt hat.
Diese Lösung ist schon relativ einfach, warum muss er nun noch mehr tun?
Weil er in der Lage sein sollte, beliebig viele Spalten zu ergänzen, ohne dass das Layout auseinanderfällt und ohne dass komplizierte Positionierungen notwendig sind.
Dazu kommt ein anderer Punkt: es ist sinnvoll, die Layoutstruktur in der Reihenfolge zu notieren, in der der Nutzer sie auch lesen soll. Was wir nicht brauchen, sind verdrehte Codierungen, um verrückte Probleme mit der Kompatibilität älterer Browser zu lösen. Die Grundidee ist, die Erstellung von strukturiertem Layout so einfach wie möglich zu machen.
Absolute und relative Positionierung
Wie ich es sehe, gibt es zwei Wege, das zu erreichen. Beide nutzen die grundlegenden Prinzipien der absoluten und relativen Positionierung. Was viele dabei missverstehen, ist, dass die Position eines mit position: absolute
deklarierten Blocks sich am umschließenden Element orientiert, nicht am Dokument oder am Browserfenster.
Bezogen auf unser Beispiel bedeutet das, dass vier absolut positionierte Elemente div
innerhalb eines relativ positionierten Containers div
aufgereiht sein können, die sich dennoch abhängig von der gewählten Schriftgröße auf und ab bewegen und dabei ihre Position relativ zueinander behalten. Nicht nur das, das Layout soll auch unabhängig von der Anzahl der Spalten zusammenhalten.
Theoretisch hätten wir es damit geschafft. Aber wie immer im Webdesign gibt es natürlich einen Browser-Bug mit dem dazu gehörenden Hack. Im Folgenden skizziere ich zwei Methoden zur Umsetzung dieses Grids. Keine von beiden ist perfekt. Eine verwendet JavaScript, um ein Elternelement zu zwingen, Eigenschaften des Kindelementes zu übernehmen. Die andere beinhaltet die einfachste mögliche Definition per CSS, benötigt aber eine Browserweiche, um IE/Mac 5 mit einem anderen Stylesheet zu versorgen.
Methode 1: Reines CSS
Unsere erste Methode basiert auf reinem CSS und geht davon aus, dass der Designer eine der vier Spalten als anpassungsfähiges Element mit Textinhalt geplant hat. Das bedeutet praktisch, zu wissen, dass die mittlere (Text-)Sektion immer länger als die Navigationssektion auf der linken Seite ist.
Die Hauptcontainer sind so definiert:
#top-section { position:relative; left:0; top:0; } #mid-section { position:relative; left:0; top:0; } #bottom-section { position:relative; left:0; top:0; }
Das sieht noch nicht besonders außergewöhnlich aus. Diejenigen, die die Eigenschaft position
genau kennen, werden aber gemerkt haben, dass diese Container sich nicht ausdehnen, wenn sie nur mit absolut positionierten Elementen gefüllt sind.
Sich auszudehnen, bedeutet für diese Sektionen, dass mid-section
direkt unter top-section
liegt und bottom-section
direkt unter mid-section
. Damit das passiert, müssen die drei Container entweder relativ positionierte Divs enthalten oder ihre Höhe muss manuell berechnet und deklariert werden.
Wenn die Designvorgabe nun bestimmt, dass mid-col-2
die längste Spalte des mittleren Abschnitts sein soll, dann positionieren wir diese Spalte relativ und die anderen drei Spalten absolut. Die Abschnitte oben und unten enthalten beide relativ positionierte Container, bereiten uns also keine Probleme. Das Stylesheet sieht dann so aus:
#top-col-1 { position:relative; padding-left:20%; padding-right:10px; } #mid-col-1 { position:absolute; top:0; left:0; width:20%; } #mid-col-2 { position:relative; top:0; left:20%; width:40%; } #mid-col-3 { position:absolute; top:0; left:60%; width:20%; } #mid-col-4 { position:absolute; top:0; left:80%; width:20%; } #bottom-col-1 { position:relative; padding-left:20%; padding-right:10px; }
Dies funktioniert in den meisten standardstreuen Browsern gut, mit Ausnahme von IE/Mac 5. Und das ist der Browser, den ich täglich benutze.
Der Bug hat mit der Berechnung der Breite in Prozenten für relativ positionierte Container zu tun. Das Problem löst sich, wenn wir mid-col-2
auch absolut positionieren.
Methode 2: Mit JavaScript-Hilfe
Diese Methode ist praktisch die Übergabe der Höhe eines absolut positionierten div
an sein relativ positioniertes Elternelement. Wenn wir, wie oben angedeutet, alle vier Spalten der mittleren Sektion absolut positionieren, haben wir das Problem, dass der untere Abschnitt Teile des mittleren Abschnitts abdeckt.
Ein kleines Script, mit dem ich mich zur Zeit befasse, könnte hier Abhilfe schaffen. Es ist noch nicht besonders ausgereift, deshalb nutze ich bis jetzt noch die Methode 1 oben. Dies ist der Trick: ich verwende den Event-Handler onload
im Starttag <body>
. Dieser ruft ein Script auf, das die Höhe von mid-col-2
liest und an mid-section
übergibt. Bottom-section
wird so in eine Lage unterhalb des mittleren Abschnitts gezwungen.
Das folgende Script ist noch sehr minimalistisch. Es wäre eleganter, wenn es alle Elemente des DOM durchginge und sich selbst an jedem Container eines bestimmten Typs anwenden würde. Auf diese Art könnte man tatsächlich die Höhe der längsten Spalte feststellen, anstatt wie hier willkürlich nur mid-col-2
zu übergeben. Auch könnte man den Transfer bezogen auf eine beliebige Anzahl relativer div
s durchführen. Wenn ein JavaScript-Experte das Script vervollkommnen könnte, wäre ich ihm sehr verbunden. Bis dahin müssen wir mit diesem kleinen Hack zufrieden sein:
function inherit(objidParent,objidChild,objidGrandchild) { if (document.layers) { alert('sorry, no pretty layouts for netscape 4'); } else if (document.getElementById) { Parent = document.getElementById(objidParent); Child = document.getElementById(objidChild); Grandchild = document.getElementById(objidGrandchild); Parent.style.height = Child.offsetHeight + 'px'; Grandchild.style.display = 'block'; return true } }
Der untere Abschnitt ist zuerst unsichtbar, um langsamere Rechner davor zu bewahren, überlappende Container darzustellen:
#bottom-section { position:relative; left:0; top:0; display:none; }
Nachdem dem Elternelement die berechnete Höhe zugewiesen wurde, setzt das Script den Wert der Eigenschaft display
auf block
und stellt damit das Layout fertig. Wir könnten das noch weiter verfeinern, indem wir das Script in Verbindung mit einem Styleswitcher aufrufen, damit der Fußteil auch bei Anwendung eines neuen Stylesheets seine Position behält.
Ausblick
Mein Ziel war, ein Gittersystem zu entwickeln, mit dem meine Designer bessere Arbeit machen und schneller vorankommen. Der einzige Zweck eines Systems ist aber letztendlich, dass man sich nicht daran hält. Denn während wir immer neue Webdesignideen haben, neigen wir doch dazu, voneinander zu kopieren und die kreierten Websites sehen tendenziell ähnlich aus. Dies ist das größte Problem, das ich mit Flash habe: die typografischen Animationen sind so cool, dass jeder sie verwendet.
Mein Weblog donkeyontheedge.com ist ein Funtionsbeispiel dieses Gridsystems, und tatsächlich: es sieht jedem anderen ein bisschen ähnlich.
TOP
Hinweis:
Das Original dieses Textes wurde zuerst am 15. November 2002 unter dem Titel Flexible Layouts with CSS Positioning im Online-Magazin A List Apart veröffentlicht. Der Autor ist Dug Falby. Die Übersetzung erfolgte mit Genehmigung von A List Apart und dem Autor.
Translated with the permission of A List Apart Magazine and the author.