z-index是一个CSS属性,允许您将图层中的元素放在彼此的顶部。不幸的是,z-index是那些并不总是以直观方式表现的属性之一。 一开始似乎很简单,更高的z指数表示该元素将位于具有较低z-index数的元素之上。 但是有一些额外的规则会使事情变得更加复杂。 并且你不能总是通过将z-index设置为999999来解决问题!?
本文将详细解释z-index不适合您的四个最常见原因,以及您如何解决它。
我们将通过一些实际的代码示例和问题解决它们。 阅读本文后,您将能够理解并避免那些常见的z-index陷阱!
1. 相同堆叠上下文中的元素将按外观顺序显示,后面的元素位于前一元素的顶部。
1.2.3用到的html结构
<section class="content">
<div class="cat-top"></div>
<div class="content-block">
Meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meowmeow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow
</div>
<div class="cat-bottom"></div>
</section>
.content-block {
padding: 1rem;
background: #FFF;
padding: 30px;
min-height: 180px;
border-radius: 15px;
box-shadow: 0 0 25px rgba(0,0,0,0.25);
}
.cat-top, .cat-bottom {
width: 120px;
height: 120px;
background-image: url('https://www.dropbox.com/s/mqapcs2hsf7k4yp/cat-expressions_03.png?dl=1');
background-size: cover;
background-position: center center;
}
.cat-top {
margin-bottom: -60px;
}
.cat-bottom {
float: right;
margin-top: -60px;
}
最终效果
相同堆叠上下文中的元素将按外观顺序显示,后面的元素位于前一元素的顶部。
在我们与猫和白色块的例子中,他们遵守这个规则。这就是为什么第一只猫在白色块元素下面,白色块在第二只猫下面。
好吧,堆叠顺序一切都很好,但是我们如何修改CSS让第二只猫在白色块下?
让我们看看第二个原因:
2. 元素是否设置定位
确定堆叠顺序的其他指导原则之一是元素是否设置了位置,要设置元素的位置,请将CSS position属性添加到static之外的任何值,例如relative或absolute。 根据此规则,定位元素将显示在未定位元素的顶部,因此,将白色块设置为position:relative,两个cat元素保持未定位状态,最终白色块将位于猫的顶部。
.content-block {
position: relative;
padding: 1rem;
background: #FFF;
padding: 30px;
min-height: 180px;
border-radius: 15px;
box-shadow: 0 0 25px rgba(0,0,0,0.25);
}
.cat-top, .cat-bottom {
width: 120px;
height: 120px;
background-image: url('https://www.dropbox.com/s/mqapcs2hsf7k4yp/cat-expressions_03.png?dl=1');
background-size: cover;
background-position: center center;
}
.cat-top {
margin-bottom: -60px;
}
.cat-bottom {
float: right;
margin-top: -60px;
}
哇噢!
现在,我们要做的下一件事是使用transform属性将底部猫倒置;这样,两只猫都会在白色的块下面,只有它们的头部伸出来。
但这样做会导致更多与z-index相关的混淆。我们将在下一部分解决问题和解决方案。
3. 设置一些CSS属性(如不透明度或变换)将把元素放在新的堆叠上下文中。
正如我们刚刚提到的,我们希望颠倒底部的猫,为此,我们将添加transform:rotate(180deg)。
.content-block {
position: relative;
padding: 1rem;
background: #FFF;
padding: 30px;
min-height: 180px;
border-radius: 15px;
box-shadow: 0 0 25px rgba(0,0,0,0.25);
}
.cat-top, .cat-bottom {
width: 120px;
height: 120px;
background-image: url('https://www.dropbox.com/s/mqapcs2hsf7k4yp/cat-expressions_03.png?dl=1');
background-size: cover;
background-position: center center;
}
.cat-top {
margin-bottom: -60px;
}
.cat-bottom {
float: right;
margin-top: -60px;
transform: rotate(180deg);
}
效果
给cat-bottom元素添加transform:rotate(180deg),这会导致底部猫再次显示在白色块的顶部。
堆叠顺序的另一个方面是某些CSS属性(如变换或不透明度)会将元素放入其自己的新堆叠上下文中,transform添加到.cat-bottom元素会使其行为就像它的z-index为0,即使它没有设置其位置或z-index!
请记住,我们从未在白色块中添加z-index值,只有position:relative,这足以将白色块放置在未定位的猫的顶部,但是由于.cat-bottom元素设置transform的作用就好像它与z-index:0 相对定位,因此导致底部猫显示在白色块的顶部。
对此的解决方案是设置位置:相对并且至少在白色块上显式设置z-index。你可以更进一步,在cat元素上设置position:relative和一个较低的z-index,只是为了更加安全。
.content-block {
position: relative;
z-index: 2;
}
.cat-top, .cat-bottom {
position: relative;
z-index: 1;
}
在我看来,这样做可以解决大多数(如果不是全部)更基本的z-index问题。
现在,让我们继续讨论您的z-index无法正常工作的最后一个原因。 这个有点复杂,因为它涉及父元素和子元素。
4. 由于父元素的z-index水平,元素处于较低的堆叠上下文中
<section class="content">
<a class="figure-link">
<figure>
<img src="http://placekitten.com/289/220" />
<figcaption>
Click the photo to load cute kitty!
</figcaption>
</figure>
</a>
<div class="txt-box">
<p>
Etiam ultrices, augue in eleifend commodo, ex mi vulputate massa, ut convallis elit mi at quam. Etiam aliquet non massa in auctor. Nunc sagittis ac felis sit amet cursus. Suspendisse dictum, purus in accumsan rutrum, nibh urna gravida purus, sit amet aliquam eros est eu ex. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam efficitur mauris leo, at consectetur magna malesuada vitae. Morbi consectetur eget ipsum vitae cursus. Praesent lacinia ultricies tempor. Quisque dictum feugiat est, in gravida tortor tincidunt sed. Aliquam erat volutpat. Etiam dictum suscipit dolor. Nam dictum cursus diam non suscipit.
</p>
<p>
Donec scelerisque aliquet tristique. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean dictum urna id placerat sagittis. Vestibulum et interdum urna, pulvinar volutpat eros. Fusce consequat rhoncus nisl, vel malesuada nulla lacinia sit amet. Nulla in aliquet magna, eu malesuada orci. Nullam ligula lacus, sollicitudin ac metus a, condimentum efficitur ligula. Aliquam posuere, magna eget fringilla ornare, purus tortor ullamcorper eros, ut fringilla justo dolor eu est. Fusce sagittis lacus et finibus tincidunt.
</p>
</div>
<!-- modal -->
<div id="openModal" class="modal">
<div class="modal-content">
<a class="close">+</a>
<b>MEOW MEOW MEOW</b>
<img src="https://www.dropbox.com/s/mqapcs2hsf7k4yp/cat-expressions_03.png?dl=1" />
</div>
</div>
</section>
<!-- sidetab -->
<div class="side-tab">
Send Feedback
</div>
*{
margin: 0;
padding: 0;
}
.content{
position: relative;
z-index: 1;
padding: 20px;
}
.content figure{
float: left;
margin: 0 30px 10px 0;
}
.content figure figcaption{
padding: 8px;
text-align: center;
font-size: 0.9rem;
background-color: #333;
color: #FFF;
}
.txt-box {
margin: 0 auto;
}
.txt-box p{
line-height: 30px;
margin-bottom: 10px;
}
.modal{
display: none;
position: fixed;
z-index: 100;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,0.7);
transition: opacity 300ms ease-in-out;
}
.modal-content{
position: absolute;
width: 100%;
max-width: 240px;
padding: 20px;
background-color: #ffffff;
top: 50%;
left: 50%;
border-radius: 20px;
box-shadow: 0 0 10px rgba(0,0,0,0.25);
transform: translate(-50%, -50%);
}
.modal-content img{
width: 140px;
}
.modal-content .close{
position: absolute;
top: 8px;
right: 2px;
font-size: 60px;
line-height: 23px;
color: rgba(0,0,0,0.75);
transform: rotate(45deg);
cursor: pointer;
transition: all 50ms ease-in-out;
}
.side-tab{
position: fixed;
z-index: 5;
bottom: 20%;
right: -68px;
padding: 15px 30px;
background: #AD2266;
color: #FFF;
transform: rotate(-90deg);
box-shadow: 0 -3px 7px rgba(0, 0, 0, 0.3);
}
document.querySelector('.figure-link').addEventListener('click', function(){
document.getElementById('openModal').style.display = 'block';
});
document.querySelector('#openModal .close').addEventListener('click', function(){
document.getElementById('openModal').style.display = 'none';
});
See the Pen Z-index: #4 different stacking contexts by oheart(@oheart) on CodePen.
当您单击猫的照片时,会打开一个带有透明灰色背景覆盖的模态窗口,虽然模态框的z-index要大于侧边栏的z-index,但侧面标签仍然位于灰色叠加层的顶部。我们希望模态框显示在所有内容上,包括侧边标签。
让我们来看看有问题的元素的CSS:
.content {
position: relative;
z-index: 1;
}
.modal {
position: fixed;
z-index: 100;
}
.side-tab {
position: fixed;
z-index: 5;
}
侧面标签的z-index为5,模态框具有z-index:100,模态框应该将其置于侧面选项卡的顶部。但是,模式框位于侧面选项卡的下方。为什么会这样?
之前,我们解决了堆叠上下文中的一些因素,例如元素是否具有定位设置,以及它在标记中的顺序,但堆叠上下文的另一个方面是子元素仅限于其父元素的堆叠上下文。
让我们仔细看看这三个元素。
<section class="content">
<div class="modal"></div>
</section>
<div class="side-tab"></div>
查看标记,我们可以看到内容和侧面标签元素是兄弟,也就是说,它们在标记中存在于同一级别(这与z-index级别不同)。模态是内容元素的子元素,因为模态在content元素内,所以它的z-index为100只在其父元素content元素中有效。
例如,如果有其他子元素是模态的兄弟元素,则它们的z-index值会将它们置于彼此之上或之下,但是这些子元素的z-index值并不表示父元素之外的任何内容,因为父元素元素的z-index设置为1,所以它的孩子,包括模态,不能突破那个z-index限制。
(你可以用这个略显令人沮丧的比喻来记住它:一个孩子可能受到父母的限制,并且无法摆脱它们。)
这个问题有几个解决方案:
解决方案:将模式移动到内容父级之外,并移动到页面的主堆叠上下文中。
修正后的html将如下所示:
<section class="content"></section>
<div class="modal"></div>
<div class="side-tab"></div>
现在,模态元素是另外两个元素的兄弟元素。
这会将所有三个元素放在与它们相同的堆叠上下文中,因此它们的每个z-index级别现在都会相互影响。
在这个新的堆叠上下文中,元素将按以下顺序显示,从上到下:
模态(z-index:100)
侧面标签(z-index:5)
内容(z-index:1)
替代解决方案:从内容中删除定位,因此不会限制模态的z-index。
如果您不想或不能更改标记,可以通过从content元素中删除位置设置来解决此问题。
.content {
// No position set
}
.modal {
position: absolute;
z-index: 100;
}
.side-tab {
position: absolute;
z-index: 5;
}
由于父级元素现在未被定位,因此模态的z-index值不再受其父级的影响。因此,模态将位于侧面标签元素的顶部,因为其z-index最高。
虽然这确实有效,但我个人会选择第一个解决方案。
因为如果由于某种原因将来你必须定位内容元素,它将再次限制模式在堆叠上下文中的顺序。
综上所述
总而言之,z-index的大多数问题都可以通过遵循以下两条准则来解决:
检查元素的位置设置和z-index数字的顺序是否正确。
确保您没有父元素限制其子项的z-index级别。