Demonstrationen und Beispiele für stacking-order
, stacking-level
, stacking-context
und z-index
-Vergabe
In allen hier demonstrierten Fällen wird der erste Container, der schwarze, den stacking-context
aufmachen, gehört also zu Level 1 (s.o.).
Zu diesem Zweck wurde ihm position: relative;
und z-index: 0;
gegeben.
Dies dient zur besseren Verdeutlichung damit nicht <body>
oder <html>
den stacking-context
bilden, was etwas unanschaulich zur erklären wäre.
Keines der divs ist positioniert und sie sind ineinander verschachtelt.
Alle divs sind Level 3. (s.o.) ausser dem schwarzen div (Level 1).
Kein z-index wurde vergeben.
Jedes div ist z-über
dem vorhergehenden aufgrund der General Regel.
Zeige Code
HTML:
<div class="first">
CSS:
<div class="second">
<div class="third">
<div class="fourth">
<div class="fifth">
<div class="sixth">
<div class="seventh">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
.first {
/* bildet stacking-context */
padding: 10px;
width: 400px;
height: 300px;
background: #000;
position: relative;
z-index: 0;}
.second {
padding: 10px;
width: 380px;
height: 280px;
background: #397A30;
}
.third {
padding: 10px;
width: 360px;
height: 260px;
background: #9E9A2F;
}
.fourth {
padding: 10px;
width: 340px;
height: 240px;
background: #AD2D3D;
}
.fifth {
padding: 10px;
width: 320px;
height: 220px;
background: #555579;
}
.sixth {
padding: 10px;
width: 300px;
height: 200px;
background: #838383;
}
.seventh {
padding: 10px;
width: 280px;
height: 180px;
background: #FFF;
}
Keines der divs ist positioniert.
Alle divs sind Level 3. (s.o.) ausser dem schwarzen (Level 1).
Kein z-index wurde vergeben.
Jedes div ist y-unter
dem vorhergehenden ausser dem ersten welches alle beherbergt.
Zeige Code
HTML:
<div class="first">
CSS:
<div class="second">
</div>
<div class="third">
</div>
<div class="fourth">
</div>
<div class="fifth">
</div>
<div class="sixth>>
</div>
<div class="seventh">
</div>
</div>
.first {
/* bildet stacking-context */
padding: 10px;
width: 400px;
height: 300px;
background: #000;
position: relative;
z-index: 0;}
.second {
padding: 10px;
width: 380px;
height: 30px;
background: #397A30;
}
.third {
padding: 10px;
width: 380px;
height: 30px;
background: #9E9A2F;
}
.fourth {
padding: 10px;
width: 380px;
height: 30px;
background: #AD2D3D;
}
.fifth {
padding: 10px;
width: 380px;
height: 30px;
background: #555579;
}
.sixth {
padding: 10px;
width: 380px;
height: 30px;
background: #838383;
}
.seventh {
padding: 10px;
width: 380px;
height: 30px;
background: #FFF;
}
In beiden Beispielen haben wir die natürliche stacking-order
demonstriert, also die Ordnung nach der General Regel.
Kein Element wurde positioniert und es wurde kein z-index vergeben.
Das schwarze div
hat Level 1., die anderen alle Level 3.
Alles ist wie oben links, nur dass wir dem vierten div, dem roten, eine negative margin gegeben haben.
So haben wir demonstriert, dass auch wirklich jeder im Quellcode folgende container z-über
dem vorhergehenden liegt, wie Sie an der Überlappung oben sehen können.
Zeige Code
HTML:
<div class="first">
CSS:
<div class="second">
<div class="third">
<div class="fourth">
<div class="fifth">
<div class="sixth">
<div class="seventh">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
.first {
/* bildet stacking-context */
padding: 10px;
width: 400px;
height: 300px;
background: #000;
position: relative;
z-index: 0;}
.second {
padding: 10px;
width: 380px;
height: 280px;
background: #397A30;
}
.third {
padding: 10px;
width: 360px;
height: 260px;
background: #9E9A2F;
}
.fourth {
padding: 10px;
width: 340px;
height: 240px;
background: #AD2D3D;
margin-top: -13px;
}
.fifth {
padding: 10px;
width: 320px;
height: 220px;
background: #555579;
}
.sixth {
padding: 10px;
width: 300px;
height: 200px;
background: #838383;
}
.seventh {
padding: 10px;
width: 280px;
height: 180px;
background: #FFF;
}
Hier ist alles wie oben rechts. Wir haben allerdings dem fünften div, dem violetten, eine negative margin gegeben.
Gleichzeitig haben wir es in der width etwas verkleinert um die Überlappung deutlicher zu machen.
Zeige Code
HTML:
<div class="first">
CSS:
<div class="second">
</div>
<div class="third">
</div>
<div class="fourth">
</div>
<div class="fifth">
</div>
<div class="sixth>>
</div>
<div class="seventh">
</div>
</div>
.first {
/* bildet stacking-context */
padding: 10px;
width: 400px;
height: 300px;
background: #000;
position: relative;
z-index: 0;}
.second {
padding: 10px;
width: 380px;
height: 30px;
background: #397A30;
}
.third {
padding: 10px;
width: 380px;
height: 30px;
background: #9E9A2F;
}
.fourth {
padding: 10px;
width: 380px;
height: 30px;
background: #AD2D3D;
}
.fifth {
padding: 10px;
width: 340px;
height: 30px;
background: #555579;
margin-top: -15px;
}
.sixth {
padding: 10px;
width: 380px;
height: 30px;
background: #838383;
}
.seventh {
padding: 10px;
width: 380px;
height: 30px;
background: #FFF;
}
Auch in den letzten beiden Beispielen ist die natürliche stacking-order
nach der General Regel demonstriert worden.
Die Überlappungen sollen die stacking-order
deutlich machen.
Das schwarze div
hat Level 1., die anderen alle Level 3.
Schauen wir einmal was passiert, wenn wir einem der Container einen Level 2. geben, also ihn poistionieren und ihm einen negativen z-index
geben.
Irgendein Text befindet sich hier, blablabla, blablabla
Und noch mehr Text befindet sich hier, blablabla, blablabla
Zeile drei des blablabla-Texts.
Zeige Code
HTML:
<div class="first">
CSS:
<div class="second">
<div class="third">
<div class="fourth">
<div class="fifth">
<div class="sixth">
<div class="seventh">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
.first {
/* bildet stacking-context */
padding: 10px;
width: 400px;
height: 300px;
background: #000;
position: relative;
z-index: 0;}
.second {
padding: 10px;
width: 280px;
height: 280px;
background: #397A30;
}
.third {
padding: 10px;
width: 260px;
height: 260px;
background: #9E9A2F;
}
.fourth {
padding: 10px;
width: 240px;
height: 240px;
background: #AD2D3D;
}
.fifth {
padding: 10px;
width: 220px;
height: 220px;
background: #555579;
}
.sixth {
padding: 10px;
width: 300px;
height: 200px;
background: #838383;
position: relative;
z-index: -1;
}
.seventh {
padding: 10px;
width: 280px;
height: 180px;
background: #FFF;
}
Links haben wir nun dem sechsten div
, dem grauen, eine position: relative;
und einen z-index: -1;
gegeben.
Gleichzeitig haben wir die vorherigen div
in der width
verkleinert, um das nun nach z-hinten
gewanderte div
sichtbar zu machen.
Unser sechster Container hat also nun Level 2.
Natürlich befinden sich die anderen Container (ausser dem schwarzen, welcher ja das Elternelement ist welches den stacking-context
bildet) über dem grauen
und das obwohl sie doch Elternelemente des grauen sind.
Erklärung s.u.
Zeige Code
HTML:
<div class="first">
CSS:
<div class="second">
</div>
<div class="third">
</div>
<div class="fourth">
</div>
<div class="fifth">
</div>
<div class="sixth>>
</div>
<div class="seventh">
</div>
</div>
.first {
/* bildet stacking-context */
padding: 10px;
width: 400px;
height: 300px;
background: #000;
position: relative;
z-index: 0;}
.second {
padding: 10px;
width: 380px;
height: 30px;
background: #397A30;
}
.third {
padding: 10px;
width: 380px;
height: 30px;
background: #9E9A2F;
}
.fourth {
padding: 10px;
width: 380px;
height: 30px;
background: #AD2D3D;
}
.fifth {
padding: 10px;
width: 320px;
height: 30px;
background: #555579;
opacity: .8;
}
.sixth {
padding: 10px;
width: 380px;
height: 30px;
background: #838383;
margin-top: -10px;
position: relative;
z-index: -1;
}
.seventh {
padding: 10px;
width: 320px;
height: 30px;
background: #FFF;
margin-top: -10px;
opacity: .8;
}
Rechts haben wir ebenfalls dem sechsten div
, dem grauen, eine position: relative;
und einen z-index: -1;
gegeben.
Gleichzeitig haben wir, um das Ergebnis besser sichtbar zu machen, ihm eine negative margin
gegeben.
Dem vorhergehenden div
, dem violetten, und auch dem nachfolgenden, dem weißen, haben wir eine opacity: .8;
vergeben, um den dahinterliegenden grauen Container besser sichtbar zu machen. Dem weißen div
haben wir ebenfalls eine negative margin
gegeben.
! Der IE7 hat opacity
noch nicht implementiert und zeigt das Durchscheinen somit nicht.
Wir können hier wunderbar sehen, daß wir die natürliche stacking-order
nach der General Regel aushebeln können wenn wir Elementen andere Level aufzwingen (Hier Level 2. für das graue div
).
Zeigen wir das einmal an einem Beispiel, welches die stacking-order
mit allen Leveln demonstriert:
Hier befindet sich ein Text, mal sehen ob der sichtbar wird...
Zeige Code
HTML:
<div class="first">
CSS:
<div class="second">
<div class="third">
<div class="fourth">
<div class="fifth">
<div class="sixth">
<div class="seventh">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
.first {
/* bildet stacking-context */
padding: 10px;
width: 400px;
height: 300px;
background: #000;
position: relative;
z-index: 0;}
.second {
/* neuer st.-context */
padding: 10px;
width: 290px;
height: 280px;
background: #397A30;
position: relative;
z-index: 1;}
.third {
padding: 10px;
width: 260px;
height: 260px;
background: #9E9A2F;
position: relative;
}
.fourth {
/* n. st.-cont. */
padding: 10px;
width: 240px;
height: 240px;
background: #AD2D3D;
float: left;
}
.fifth {
padding: 10px;
width: 210px;
height: 220px;
background: #555579;
}
.sixth {
padding: 10px;
width: 300px;
height: 200px;
background: #838383;
position: relative;
z-index: -1;}
.seventh {
padding: 10px;
width: 280px;
height: 180px;
background: #FFF;
}
Links haben wir versucht alle möglichen Level darzustellen (schauen sie in den Code).
Der sechste Container, der graue, hat position: relative; z-index: -1;
verpasst bekommen.
Er wird z-unter
den Containern drei, vier und fünf dargestellt, weil erstgenannter nun Level 2. hat, die anderen aber Level 3.
Der zweite, der grüne Container, bleibt z-unter
dem grauen, da das grüne div
positioniert ist und einen positiven z-index
hat und somit einen neuen stacking-context
für seine Kindelemente aufmacht, also für den gelben Container und dessen Kindelemente.
Zwar hat der grüne Container nun Level 7., müsste also z-über
allen anderen Levels liegen, die folgenden Container sind aber ja Kindelemente des grünen und somit an seinen stacking-context
gebunden. D.h. in Wahrheit hat der gelbe Container zwar Level 6. (weniger als der grüne mit Level 7.), dies aber ja im stacking-context
des grünen und nicht im ursprünglichen schwarzen.
Dem vierten, dem roten, Container haben wir ein float: left;
verpasst (Level 4.). Warum überdeckt er trotzdem nicht Container fünf (violett), welcher ja Level 3. hat (normales Block-Element im normalen Fluss, ohne Positionierung und ohne z-index
) ?
Ganz einfach: Container fünf (violett) ist ein Kindelement von Container vier (rot) und floated als Inhalt des roten Containers mit, ist also gar nicht Level 3., weil er nicht mehr im normalen Fluss steht (gefloatete Elemente stehen ja ausserhalb des normalen Flusses).
Was ist denn eigentlich mit dem gelben div
?
Das hat doch Level 6. innerhalb des neu gebildeten grünen stacking-context
.
Warum wird erstgenanntes dann nicht über dem roten mit Level 4. angezeigt ?
Nun, der rote Container ist ja ein Kindelement des gelben und somit ja indirekt positioniert.
Nicht dass position: relative;
automatisch vererbar wäre, also dass das rote div
nun auch positioniert wäre, aber als Kindelement des gelben kann es ja aus dessen Positionierung nicht entkommen, es sei denn es würde seinerseits positioniert. Der rote Container ist also eigentlich gar nicht nicht Level 4., weil er durch sein Elternelement indirekt eben doch positioniert ist.
Verwirrend ?
Wir müssen beim Betrachten der stacking-order
nach unseren Regeln (s.o.) also auch immer beachten, ob zwischendurch
1. ein neuer stacking-context
aufgemacht wurde und
2. ob der von uns bestimmte Level auch wirklich stimmt, was bei Kindes-Kindelementen mit Bedacht beurteilt werden muß.
Im rechten Beispiel kann man sehen was, bei gleichen CSS-Eigenschaften wie im vorliegenden Beispiel, passiert, wenn die Container nicht Kindelemente voneinander sind sondern y-untereinander
dargestellt werden.
Zeige Code
HTML:
<div class="first">
CSS:
<div class="second">
</div>
<div class="third">
</div>
<div class="fourth">
</div>
<div class="fifth">
</div>
<div class="sixth>>
</div>
<div class="seventh">
</div>
</div>
.first {
/* bildet stacking-context */
padding: 10px;
width: 400px;
height: 300px;
background: #000;
position: relative;
z-index: 0;}
.second {
padding: 10px;
width: 300px;
height: 30px;
background: #397A30;
position: relative;
z-index: 1;
}
.third {
padding: 10px;
width: 320px;
height: 30px;
background: #9E9A2F;
margin-top: -13px;
position: relative;
}
.fourth {
padding: 10px;
width: 340px;
height: 30px;
background: #AD2D3D;
margin: -13px 0 -13px 0;
float: left;
}
.fifth {
padding: 10px;
width: 360px;
height: 30px;
background: #555579;
clear: left;
}
.sixth {
padding: 10px;
width: 380px;
height: 30px;
background: #838383;
margin-top: -13px;
position relative;
z-index: -1;
}
.seventh {
padding: 10px;
width: 360px;
height: 30px;
background: #FFF;
margin-top: -13px;
}
Rechts haben wir die gleichen Eigenschaften auf die verschiedenen div
verteilt wie links.
Hier allerdings sind die Container ja nicht ineinander verschachtelt sondern stehen y-untereinander
.
Sogleich haben unsere vergebenen Eigenschaften einen starken Effekt. Wir haben die komplette natürliche Ordnung umgeworfen. Kein div
sitzt mehr auf der z-Achse in der Reihenfolge des Vorkommens im Quelltext.
Um dies sichtbar zu machen haben wir einige negative margin
vergeben damit die div
sich überlappen.
Folgend die Level-Verteilung:
schwarz: Level 1. (bildet stacking-context
grün: Level 7. (positioniert und z-index: 1;
gelb: Level 6. (positioniert)
rot: Level 4. (float: left;
)
violett: Level 3. (block-level-element
in normalem Fluss)
grau: Level 2. (positioniert und z-index: -1;
weiß: Level 3. (block-level-element
in normalem Fluss)
Was Level 5. betrifft (inline-elements
im normalen Fluss), haben wir diese hier nicht aufgeführt, da das Verhalten von diesen Elementen stark davon abhängt in welchem elternelement sie sich befinden (meist ja ein Level 3. Element (z.B. <p>
).
Wir wissen aber ja, dass Text und Bilder immer z-über
ihrem Elternelement sitzen (anders wäre es sicher auch nicht sinnvoll ;-) ) und es ist leicht nachzuvollziehen, dass in einem stacking-context
Elemente mit höherem Level beispielsweise Text überdecken.
Siehe dazu auch die Abhandlung über reine CSS-Tooltips.
In der Abhandlung über CSS-Tooltips kommt zum Tragen, dass jedes inline-element
auch zu einem block-level-element
gemacht werden kann. Zum einen mit display: block;
und zum anderen durch Positionierung. Positionierung macht ein Element ja auch zu einem Block-Element. Der stacking-context
und die z-index
-Eigenschaft sind bei den CSS-Tooltips von grosser Bedeutung.
IE7 hat hier einen seiner vielen Bugs.
Das vierte div
, das rote, hat die Eigenschaft float: left;
und das fünfte, das violette clear: left;
um es y-unter
dem roten darzustellen.
Das rote div
hat folglich Level 4. und das violette nur Level 3.
Trotzdem stellt IE7 das violette div
z-über
dem roten dar, was verkehrt ist.
Es dürfte klar sein, daß, würden in obigem Beispiel alle Container auf einer y-Ebene liegen, sie in der z-Reihenfolge Ihres Levels nach am Anfang aufgeführten Regel dargestellt werden müssten, was wir hier durch lediglich leichte Überlappung demonstriert haben.
Die Beispiele lassen sich teilweise schwerlich auf dem zweidimensionalen Bildschirm darstellen und wir können hier nicht alle erdenklichen Konstellationen demonstrieren. Zum Schluss aber noch ein interaktives Beispiel:
Level 7.
Level 6.
Level 4.
Level 3.
--- Level 6. ---
Das weiße div mit blauem Rand ist ein Kindelement des violetten div.
Es ist positioniert und erlangt somit Level 6.
--- Level 6. ---
Lediglich mit negativen margins wird das div nun verschoben und wir sehen, dass es alle divs mit niedrigerem Level überlagert.
Wir erinnern uns, das rote div ist gefloated, also Level 4.
--- Level 6. ---
Das schwarze div bildet ohnehin den stacking-context und gehört somit zu Level 1., wird also auch überlagert.
--- Level 6. ---
Das gelbe div hat ebenfalls Level 6. (positioniert), es wird jedoch durch unser weißes div überlagert, da dieses im Quelltext später steht (siehe General Regel).
--- Level 6. ---
Das grüne div ist positioniert und hat z-index: 1; womit es Level 7. hat. Somit muß sich unser div "fügen" und wird von dem grünen verdeckt.
Level 2.
Level 3.
Zeige Code
HTML:
<div class="first">
CSS:
<div class="second">
</div>
<div class="third">
</div>
<div class="fourth">
</div>
<div class="fifth">
<div></div>
</div>
<div class="sixth>>
</div>
<div class="seventh">
</div>
</div>
.first {
/* bildet stacking-context */
padding: 10px;
width: 400px;
height: 300px;
background: #000;
position: relative;
z-index: 0;}
.second {
padding: 10px;
width: 270px;
height: 30px;
background: #397A30;
position: relative;
z-index: 1;
}
.third {
padding: 10px;
width: 290px;
height: 30px;
background: #9E9A2F;
margin-top: -13px;
position: relative;
}
.fourth {
padding: 10px;
width: 310px;
height: 30px;
background: #AD2D3D;
margin: -13px 0 -13px 0;
float: left;
}
.fifth {
padding: 10px;
width: 340px;
height: 30px;
background: #555579;
clear: left;
}
.fifth div {
position: relative;
width: 120px;
height: 22px;
border: 4px solid #0053FA;
left: 222px;
}
.sixth {
padding: 10px;
width: 350px;
height: 30px;
background: #838383;
margin-top: -13px;
position relative;
z-index: -1;
}
.seventh {
padding: 10px;
width: 330px;
height: 30px;
background: #FFF;
margin-top: -13px;
}
Die interaktive Demonstration wurde nur mit CSS entwickelt.
Mit dem Fehler im IE7, der das violette div (Level 3.) über dem roten div (Level 4.) darstellt, habe ich mich nicht weiter befasst.
Wenn jemand einen Tip hat, ist er willkommen.
Ich hoffe meine Ausführungen waren nicht allzu chaotisch und Sie konnten etwas an Erkenntnis mitnehmen.