为何box-shadow的transition属性不生效?按钮悬停过渡失效排查
内外box-shadow无法平滑过渡的原因及解决办法
问题根源
你遇到的问题核心在于:普通外部阴影(无inset关键字)和内部阴影(带inset)是两种不同类型的阴影属性值,浏览器无法在这两种完全不同的阴影形态之间进行插值计算,所以直接通过:hover切换时,不会有平滑过渡效果,只会瞬间切换状态。
解决方案:用伪元素分离阴影,通过opacity过渡实现
我们可以用两个伪元素分别承载外部阴影和内部阴影,通过调整伪元素的opacity来实现平滑的视觉切换,避开内外阴影无法直接过渡的限制:
body{ background: rgb(180, 181, 180); } .btn{ height: 100px; width: 100px; margin: auto; border-radius: 20%; background-image: linear-gradient(135deg,rgb(215, 215, 215),rgb(84, 84, 84)); position: relative; } /* 承载外部阴影的伪元素 */ .btn::before { content: ''; position: absolute; inset: 0; border-radius: inherit; box-shadow: 3px 3px 5px rgb(84, 84, 84),-3px -3px 5px rgb(255, 255, 255); transition: opacity 1s ease-in-out; pointer-events: none; /* 不干扰按钮的交互事件 */ } /* 承载内部阴影的伪元素 */ .btn::after { content: ''; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 3px 3px 5px rgb(84, 84, 84),inset -3px -3px 5px rgb(255, 255, 255); opacity: 0; transition: opacity 1s ease-in-out; pointer-events: none; } /* 悬停时切换两个伪元素的透明度 */ .btn:hover::before { opacity: 0; } .btn:hover::after { opacity: 1; }
原理说明
- 两个伪元素完全覆盖按钮区域,分别负责显示外部阴影和内部阴影
- 默认状态下内部阴影伪元素透明度为0,外部阴影伪元素完全显示
- 悬停时通过过渡动画切换两者的透明度,视觉上就呈现出阴影从外部平滑转为内部的效果
内容的提问来源于stack exchange,提问作者Mohiul Islam
相关产品推荐
相关产品推荐

