Vergleich
position: relative vs absolute: der Unterschied und warum beide zusammengehören
relative verschiebt ein Element von seinem normalen Platz, ohne den Platz aufzugeben. absolute nimmt es aus dem Fluss und setzt es relativ zum nächsten positionierten Vorfahren. Das häufigste Muster benutzt beide: relative am Container, absolute am Kind.
position: relative · position: absolute.probe { position: relative; top: 20px; left: 20px; }
Das Labor schaltet zwischen den verglichenen Deklarationen um; die Anzeige darunter nennt den berechneten Wert und die Maße der Probe.
Bezugspunkt
Bei relative beziehen sich top, right, bottom und left auf die Stelle, an der das Element ohne Positionierung stünde. Bei absolute auf den nächsten Vorfahren, der selbst positioniert ist (relative, absolute, fixed oder sticky). Gibt es keinen, ist der Bezug das Anfangs-Containing-Block – in der Praxis das Fenster.
Platz im Fluss
Ein relativ positioniertes Element behält seinen Platz; die Nachbarn verhalten sich, als wäre es nicht verschoben, und es überlappt sie. Ein absolut positioniertes Element gibt seinen Platz auf; die Nachbarn rücken zusammen. Ohne width schrumpft es auf die Breite seines Inhalts.
Das Muster: relative außen, absolute innen
.karte { position: relative; }
.marke { position: absolute; top: 8px; right: 8px; }relative ohne Versatz tut dem Container nichts – es macht ihn nur zum Bezug. Das Kind landet in seiner Ecke, egal wo die Karte auf der Seite steht. Dieses Muster löst Ecken-Marken, Tooltips, Schließen-Schaltflächen und das vertikale Zentrieren aus Div zentrieren.
Stapelkontext
Beide Werte erlauben z-index; mit einem z-index ungleich auto entsteht ein neuer Stapelkontext, innerhalb dessen die Kinder gestapelt werden. Ein Kind kann dann nicht mehr über Elemente außerhalb dieses Kontexts gelegt werden, egal wie hoch sein z-index ist – die Referenz zu z-index erklärt die Regeln.
Die vier Kantenangaben und was auto bedeutet
top, right, bottom und left haben bei beiden Werten dieselben Namen und verschiedene Bedeutungen. Relativ versetzt verschieben sie das Element von seiner eigenen Position weg: top: 10px schiebt es zehn Pixel nach unten, weil der Abstand zur Oberkante wächst. Werden gegenüberliegende Angaben gemacht, die sich widersprechen, gewinnt bei linksläufigem Text die linke und die obere; die andere wird verworfen.
Absolut versetzt geben dieselben vier Eigenschaften den Abstand zu den Kanten des enthaltenden Blocks an. Bleibt eine von ihnen auf auto, setzt der Browser das Element an die Stelle, an der es ohne die Positionierung in dieser Richtung gestanden hätte – die sogenannte statische Position. Deshalb bleibt ein Element mit position: absolute ohne jede Kantenangabe optisch dort stehen, wo es war, und nimmt trotzdem keinen Platz mehr ein. Werden zwei gegenüberliegende Kanten gleichzeitig gesetzt und ist keine Breite angegeben, streckt sich die Box zwischen beiden.
Was der enthaltende Block wirklich ist
Der Bezugsrahmen einer absolut positionierten Box ist der nächste Vorfahr, der selbst positioniert ist – und zwar dessen Innenkante des Rahmens, also die Kante um Inhalt und Innenabstand herum, nicht die Außenkante. Findet sich kein solcher Vorfahr, ist es der ursprüngliche enthaltende Block, praktisch also die Fläche des Dokuments. Diese Kette ist der Grund, warum eine kleine Marke in einer Ecke ohne den relativ versetzten Container quer über die Seite wandert.
Nach CSS 2.1 sind noch weitere Auslöser hinzugekommen: Ein Element mit einer Transformation, mit einem Filter oder mit einer erklärten Eindämmung wird ebenfalls zum Bezugsrahmen für seine absolut positionierten Nachfahren, auch wenn position dort auf static steht. Das erklärt eine Klasse von Fehlern, die sonst rätselhaft wirkt: Eine Anordnung funktioniert, bis irgendwo weiter oben eine Animation eine Transformation setzt – und plötzlich hängt die Marke am falschen Kasten.
Der dritte und der vierte Wert
CSS 2.1 kennt vier Werte. Neben den beiden verglichenen gibt es den Ausgangswert für den normalen Fluss, bei dem die vier Kantenangaben wirkungslos bleiben, und die feste Verankerung, die sich wie die absolute verhält, aber am Anzeigebereich misst statt an einem Vorfahren – und beim Rollen stehen bleibt. Im Druck bedeutet dasselbe Schlüsselwort etwas anderes: Dort wird das Element auf jeder Seite wiederholt.
Ein fünfter Wert kam später hinzu und verbindet beide Verhaltensweisen: Das Element bleibt im Fluss, bis eine gesetzte Kante beim Rollen erreicht wird, und haftet von da an. Damit lässt sich eine Überschrift am oberen Rand halten, solange ihr Abschnitt sichtbar ist – etwas, das mit den vier Werten von CSS 2.1 nur mit einem Skript möglich war.
Wenn der Bezugsrahmen rollt
Rollt ein Bereich, dann rollt eine absolut positionierte Box mit, sofern ihr Bezugsrahmen innerhalb dieses Bereichs liegt. Liegt er außerhalb, bleibt sie stehen, während der Inhalt darunter wegzieht – ein Verhalten, das gelegentlich gewünscht und häufiger ein Versehen ist. Wer eine Marke fest an einer Karte in einer Liste halten will, muss den relativ versetzten Container also innerhalb des rollenden Bereichs setzen, nicht darum herum.
Dazu kommt das Abschneiden: Schneidet ein Vorfahr seinen Überlauf ab, wird eine absolut positionierte Box nur dann mitgeschnitten, wenn dieser Vorfahr auch ihr Bezugsrahmen ist. Ein Aufklappmenü, das aus seinem Kasten herausragen soll, funktioniert deshalb, solange der abschneidende Kasten nicht selbst positioniert ist – und bricht in dem Moment, in dem jemand ihm position: relative gibt. Für den dritten Wert der Eigenschaft, das feste Verankern am Fenster, gilt die Bezugsregel ebenfalls, nur ist der Rahmen dort das Fenster selbst.
Häufige Fragen
Wozu position: relative ohne top oder left?
Um das Element zum Bezugspunkt für absolut positionierte Kinder zu machen. Es bleibt an seinem Platz und verändert sonst nichts.
Warum landet mein absolutes Element im Fenster statt im Container?
Weil kein Vorfahre positioniert ist. Der Container braucht position: relative (oder einen anderen Wert außer static).
Rücken Nachbarn nach, wenn ich ein Element relativ verschiebe?
Nein. Der ursprüngliche Platz bleibt reserviert; das Element überlappt seine Nachbarn.
Warum ist mein absolutes Element so schmal?
Weil es aus dem Fluss genommen wurde und ohne width nur so breit wie sein Inhalt ist. left: 0; right: 0 oder eine Breite hilft.
Was ist der Unterschied zu fixed und sticky?
fixed bezieht sich immer auf das Fenster und scrollt nicht mit. sticky verhält sich wie relative, bis ein Schwellenwert beim Scrollen erreicht ist, und bleibt dann wie fixed stehen.