最近要实现一个类似下面的层叠的效果,需要带一个hover
缓动效果。
第一反应就是直接使用:before
&:after
伪元素,配合绝对定位加z-index
轻松实现,实际操作发现并不是这么一回事。
代码如下
.box{ width:100px; height:100px; position:relative; z-index:2; box-shadow:0 3px 5px #eee; background-color:#fff; } .box:before{ content:""; position:absolute; top:5px; left:5px; right:5px; bottom:-5px; box-shadow:0 3px 5px #eee; background-color:#fff; z-index:1; }
但是得到的确实下面的效果
也就是:before
跑到上面来了,检查.box
也有postion
属性赋值,当时就有点懵逼了。因为和层叠有关,所以就翻了一些和z-index
相关的资料,也就是层叠顺序,网上相关资料很多,本文主要说说伪元素的层叠上下文。
解决方案
.box{ width:100px; height:100px; position:relative; top:0; box-shadow:0 3px 5px #eee; background-color:#fff; transiton:.5s; } .box:before{ content:""; position:absolute; top:5px; left:5px; right:5px; bottom:-5px; box-shadow:0 3px 5px #eee; background-color:#fff; z-index:-1; } .box:hover{ top:-5px; }
父元素不设置z-index
值,伪元素设置负z-index
值,父元素位移效果不使用transform
,简单说下原因。
- 同一个层叠上下文里面, 层叠顺序从后向前依次是: 背景和边框、负z-index、块级盒、浮动盒、行内盒、z-index:0、正z-index.
- 伪元素相当于子元素,也就是包含在元素内的,二者不在同一个层叠上下文中。
如果想实现层叠效果,需要元素和对应的伪元素在同一层叠上下文中,所以不能让元素创建层叠上下文。以下情况会创建层叠上下文
- 即便是
position
不为static
的元素, 如果没有指定一个非auto
值的z-index
, 该元素就不会建立一个层叠上下文。 - 元素的
transform
值不是none
。
当然还有其他情况本文就不列出了,因为transform
会创建层叠上下文,所以缓动的时候只能使用top 进行变换了。
这里有点的是,top
bottom
等属性如果没有设置初始值transition
是不会生效的,所以代码中设置了初始值top:0
。
贝总的烦恼
“X 久之前,bigfa 写过一个功能颇得我心。
慢慢有了进阶版的需求,Google 一下企图自行实现—— 未遂。
想着要不留言问下 bigfa 乐不乐意、高不高兴、有没有空下手升华一下啊”?
然后看到已有人提出相同需求,但是碰了一鼻子软钉子,啊,好可怕,快逃~
Google 时算是挖掘到了 Plan B,但对其抱有七成的不满意,等于白搭。“
@小帅比 。。。你厉害
@bigfa 果然有了答案。美女的力量是无穷的。
@小帅比 你好“人肉传呼机”。