问题
This has been asked before, but only where z-index
is explictly defined in the CSS.
I am trying to use clip-path on a heading, but then pull up an image from within an element beneath this back over the top of that header. However, as soon as I define a clip-path
on the header, the image (which should be higher up the stacking order as it appears later in the code) goes underneath the header:
body {
padding: 1em;
}
header {
background: #a00;
clip-path: polygon(0 0, 100% 0, 100% calc(100% - 5em), 0 100%);
}
h1 {
margin: 0;
padding: 2em;
font: 300%;
color: white;
text-align: center;
}
section {
background: #ccc;
padding-top:5em;
margin-top:-5em;
}
img {
margin-top: -10em;
}
<header>
<h1>Header Content</h1>
</header>
<section>
<img src="https://via.placeholder.com/330/0000FF/808080"/>
</section>
I would expect the image to be above the header. After playing around some more, I found that if I set position:relative
on the image - it works:
body {
padding: 1em;
}
header {
background: #a00;
clip-path: polygon(0 0, 100% 0, 100% calc(100% - 5em), 0 100%);
}
h1 {
margin: 0;
padding: 2em;
font: 300%;
color: white;
text-align: center;
}
section {
background: #ccc;
padding-top:5em;
margin-top:-5em;
}
img {
margin-top: -10em;
position:relative;
}
<header>
<h1>Header Content</h1>
</header>
<section>
<img src="https://via.placeholder.com/330/0000FF/808080"/>
</section>
But why? What's happening here please and why does clip-path appear to affect the stacking order of elements later in the page?
回答1:
From the specifcation:
A computed value of other than none results in the creation of a stacking context the same way that CSS opacity does for values other than 1.
Then considering the painting order:
- All positioned, opacity or transform descendants, in tree order that fall into the following categories:
- All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order. For those with 'z-index: auto', treat the element as if it created a new stacking context, but any positioned descendants and descendants which actually create a new stacking context should be considered part of the parent stacking context, not this new one. For those with 'z-index: 0' treat the stacking context generated atomically.
- All opacity descendants with opacity less than 1, in tree order, create a stacking context generated atomically.
- All transform descendants with transform other than none, in tree order, create a stacking context generated atomically.
The element with clip-path
is painted at the step (8) and the image will be painted before if has no position set
- For all its in-flow, non-positioned, block-level descendants in tree order: If the element is a block, list-item, or other block equivalent ...
If you add position:relative
to image it will be postioned and will fall under the step (8) and the tree order will decide making it above the clip-path
element
Here is the same code with opacity
where you will have the same painting order:
body {
padding: 1em;
}
header {
background: #a00;
opacity:0.8;
}
h1 {
margin: 0;
padding: 2em;
font: 300%;
color: white;
text-align: center;
}
section {
background: #ccc;
padding-top:5em;
margin-top:-5em;
}
img {
margin-top: -10em;
}
<header>
<h1>Header Content</h1>
</header>
<section>
<img src="https://via.placeholder.com/330/0000FF/808080"/>
</section>
Related:
Why does position:relative; appear to change the z-index?
Why can't an element with a z-index value cover its child?
来源:https://stackoverflow.com/questions/57327586/why-does-clip-path-affect-the-stacking-order-z-index-of-elements-later-in-dom