1459 字
7 分钟

12.3号学习内容

欢迎来到我的博客!#

这是我的第 3 篇文章,使用 Markdown 格式编写。

今天学到了什么#

  • 3D悬停相册

代码比较简单,但是在自己写的过程中,总能发现一些小问题

疑问1#

<style>
.box ul:has(.item:nth-child(1):hover) {
grid-template-columns: 2fr 1fr 1fr 1fr;
}
.item:nth-child(1):hover ul {
grid-template-columns: 2fr 1fr 1fr 1fr;
}
</style>

第二种写法是:

.item:nth-child(1):hover ul :用于当某个 itemhover 时,改变 该 item 内部的 <ul> 元素 的样式。如果 item 内部没有 <ul> ,则无效。(本质应该是一个后代选择器

感觉冒号后面更多的是形容词,主体还是item

疑问2#

刚写到最后一行的时候我就有疑问了

我明明没有设置z-index=1,但是,被鼠标选中的元素 不会 被后面的元素遮住

<style>
.box {
display: flex;
justify-content: center;
align-items: center;
margin: 200px auto;
gap: 2px;
}
.box .item {
width: 120px;
height: 120px;
transition: all 0.6s ease;
}
.box .item img {
width: 100%;
height: 100%;
border-radius: 8px;
}
.box .item:hover {
transform: scale(1.2);
}
</style>

写到这里我还没有深究,直到我快写完这个案例的时候

<style>
.box .item {
width: 120px;
height: 120px;
transition: all 0.6s ease;
-webkit-box-reflect: below 1px linear-gradient(transparent, #0002);
/* 写到这里的时候我就发现不对劲了,经过我慢慢探索,发现了。。。 */
}
/* 鼠标经过某个盒子,其余的子盒子都变形,当前盒子保持不变 */
.box:hover .item:not(:hover) {
transform: perspective(500px) rotateY(45deg);
margin: 0 -20px;
}
</style>

我发现,我加了倒影之后,后面的图片就会压在 鼠标经过的图片 的上面,我不加倒影,就不会这样

这背后的原因就是 CSS 堆叠上下文 (Stacking Context) 。

堆叠上下文 (Stacking Context) 是什么?#

堆叠上下文是 HTML 元素的一个三维概念,它沿着 Z 轴(垂直于屏幕的轴)对元素进行分层。每个堆叠上下文都有自己的 Z 轴,并且其子元素在其中进行堆叠。

哪些属性会创建新的堆叠上下文?#

有很多 CSS 属性可以创建新的堆叠上下文,其中最常见和与你情况相关的就是:

  1. position 属性 :

    • 当一个元素的 position 属性值为 absolute 或 relative ,并且设置了 z-index 属性(即使 z-index 的值是 auto 或 0 ,只要不是 static 且设置了 z-index 就会创建)。
    • 注意 : position: fixed 和 position: sticky 也会创建堆叠上下文。
  2. transform 属性 :

    • 当一个元素设置了 transform 属性,并且其值不是 none 时,它会创建一个新的堆叠上下文。
    • 这就是你遇到的情况!
  3. opacity 属性 :

    • 当一个元素的 opacity 属性值小于 1 时,它会创建一个新的堆叠上下文。
  4. filter 属性 :

    • 当一个元素的 filter 属性值不是 none 时,它会创建一个新的堆叠上下文。
  5. will-change 属性 :

    • 如果 will-change 属性的值是 transform 、 opacity 、 filter 或 perspective ,它会创建一个新的堆叠上下文。 还有其他一些属性,比如 perspective 、 clip-path 、 mask 等,也会创建堆叠上下文。

问题的核心: -webkit-box-reflect 也创建了堆叠上下文

-webkit-box-reflect 这个属性,同样会为元素创建一个新的堆叠上下文。

详细解释:#

  1. 不加倒影时(没有 -webkit-box-reflect ) :

    • 只有当你鼠标滑过某个 .item 元素时,它才会被应用 transform: scale(1.2); 。
    • 此时, 只有被滑过的那个 .item 元素创建了新的堆叠上下文 。
    • 其他未被滑过的 .item 元素没有 transform 属性,也没有 -webkit-box-reflect ,所以它们 没有创建新的堆叠上下文 。
    • 根据堆叠上下文的规则,一个创建了堆叠上下文的元素,会堆叠在没有创建堆叠上下文的兄弟元素之上。所以,被滑过的图片自然就浮在了最上面。
  2. 加了倒影之后(所有 .item 都应用了 -webkit-box-reflect ) :

    • 当你给所有的 .item 元素都加上 -webkit-box-reflect 之后, 所有的 .item 元素都创建了各自的堆叠上下文 。
    • 现在,所有的 .item 元素都在同一个父堆叠上下文(通常是 body 或 html )中,并且它们都创建了自己的子堆叠上下文。
    • 在这种情况下,它们的堆叠顺序不再是“有堆叠上下文的在上面,没有的在下面”那么简单了。而是要根据它们各自的 z-index 值来决定。
    • 如果所有 .item 的 z-index 都是默认的 auto 或 0 ,那么它们的堆叠顺序将由它们在 HTML 中的 文档流顺序 决定。 也就是说,HTML 中写在后面的元素会覆盖写在前面的元素。
    • 当你滑过一个图片时,它会应用 transform: scale(1.2); ,并且你的代码中通常会同时设置 z-index: 1; 。
    • 关键在于: 如果你 没有 在 .item 中设置 z-index: 1; ,那么即使它被 transform: scale(1.2); 放大,它的 z-index 仍然是默认值。由于所有元素都创建了堆叠上下文,并且 z-index 相同,那么文档流顺序就会生效,导致后面的图片覆盖前面的图片。

结束:完整代码演示#

最终我也是把照片换成了她的照片❤️

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #1A252C;
}
.box {
display: flex;
justify-content: center;
align-items: center;
margin: 200px auto;
gap: 2px;
}
.box .item {
width: 120px;
height: 120px;
transition: all 0.6s ease;
-webkit-box-reflect: below 1px linear-gradient(transparent, #0002);
}
.box .item img {
width: 100%;
height: 100%;
border-radius: 8px;
}
.box .item:hover {
transform: scale(1.2);
z-index: 1;
}
/* 鼠标经过某个盒子,其余的子盒子都变形,当前盒子保持不变 */
.box:hover .item:not(:hover) {
transform: perspective(500px) rotateY(45deg);
margin: 0 -20px;
}
.box .item:hover~.item {
transform: perspective(500px) rotateY(-45deg);
}
</style>
<body>
<div class="box">
<div class="item"><img src="../代码/img/1.png"></div>
<div class="item"><img src="../代码/img/2.png"></div>
<div class="item"><img src="../代码/img/3.png"></div>
<div class="item"><img src="../代码/img/4.png"></div>
<div class="item"><img src="../代码/img/5.png"></div>
</div>
</body>
</html>

很高兴与你分享这些知识!

赞助支持

如果这篇文章对你有帮助,欢迎赞助支持!

赞助
12.3号学习内容
https://firefly.cuteleaf.cn/posts/2025-12-3今日学习/
作者
LJC
发布于
2025-12-03
许可协议
CC BY-NC-SA 4.0
最后更新于 2025-12-03

目录