解决display隐藏下拉菜单CSS渐入动画失效问题

问题情境

群里的一位同学想要用纯css实现鼠标移到菜单上,菜单下拉栏渐现,鼠标移出下拉栏渐出的效果,使用透明度opacity和display的组合动画后发现并没有渐隐渐现的动画。下图的现在的效果和代码,确实下拉栏没有渐隐渐现的效果。
现在的效果

1
2
3
4
5
6
7
8
9
10
.side-bar .qr .qr-hover-box {
    display: none;
    opacity: 0;
    transition: .3s;
}

.side-bar .qr:hover .qr-hover-box {
    display: block;
    opacity: 1;
}

问题原因

这里动画失效的原因是由于用了display这个属性。
在做这个效果之前,我们先简单了解一下css动画原理。css的动画运作机理是关键帧线性动画,在这个线性的过渡表达中,从始至终都需要这个元素的存在。
但是当display:none时,元素将从文档流中消失,这时候动画作用的元素不见了,自然也就没有动画效果了。

解决方案

通过对问题原因的剖析,我们知道只有文档流占位存在时才能有动画效果。那这里可不可以直接用opacity透明度属性的变化,把display去掉呢?
答案是不可以,透明度的变化只会让元素不可见,但是元素还是处于可以点击的状态。也就是说,如果你的下拉菜单里有超链接之类的可以点击的地方,即使下拉菜单透明度为0时被隐藏,但是这些超链接还是可以点击的。
最佳的解决方案是将display属性换成visibility属性就可以了,用下面的表格来展示这三个属性的区别。

display visibility opacity
实现效果 隐藏/出现 隐藏/出现 隐藏/出现
文档流占位 不占位 占位 占位
内容是否可点击 不可以 不可以 可以

最终效果

将display属性换成visibility属性之后就实现了最终的效果,我们给二维码图片加上了超链接,此时在二维码隐藏的情况下也是不能被电机的。
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
.side-bar .qr .qr-hover-box {
    visibility: hidden;
    opacity: 0;
    transition: .3s;
}

.side-bar .qr:hover .qr-hover-box {
    visibility: visible;
    opacity: 1;
}