使用CSS filter: brightness导致元素消失的问题求助
问题描述
制作仿OS X Lion风格按钮时,尝试用@keyframes结合filter: brightness(x)实现激活状态的发光效果,但按钮元素会莫名消失,仅伪元素可见。分别测试背景渐变和图片背景,结果一致,怀疑问题和伪元素实现边框的方式有关。
相关代码
HTML
<button>Button</button>
CSS
button { padding: 5px 16px; border-radius: 4px; outline: none; background: linear-gradient(to bottom, #fff 0 30%, #e2e2e2 70% 100%); color: black; border: none; position: relative; transform-style: preserve-3d; letter-spacing: -0.3px; text-shadow: -0.5px -0.5px 1px rgba(0, 0, 0, 0.1); transition: 0s; font-family: "Lucida Grande", sans-serif; transform: scale(4); margin: 200px; } button::after { content: ''; position: absolute; background: rgb(120, 120, 120); width: calc(100% + 2px); height: calc(100% + 2px); left: -1px; top: -1px; transform: translateZ(-1px); border-radius: 5px; opacity: 1; z-index: -1; } button:active { background: linear-gradient(to bottom, rgb(188, 206, 233) 0, rgb(115, 158, 227) 50%, rgb(92, 145, 226) 51%, rgb(174, 215, 231) 100%); animation: glow 1s infinite; } button:active::after { content: ''; position: absolute; background: linear-gradient(to bottom, rgb(89, 92, 169) 0 40%, rgb(80, 89, 142) 60% 100%); width: calc(100% + 2px); height: calc(100% + 2px); left: -1px; top: -1px; transform: translateZ(-1px); border-radius: 5px; opacity: 1; } @keyframes glow { 0% { filter: brightness(1.1); } 50% { filter: brightness(1.2); } 100% { filter: brightness(1.1); } }
问题原因
核心矛盾在于transform-style: preserve-3d和filter的兼容性:当给元素添加filter属性时,浏览器会强制为该元素创建新的层叠上下文,同时完全破坏原有的3D变换空间——preserve-3d的效果被忽略,原本通过translateZ(-1px)设置在按钮后方的伪元素,会因为3D空间失效而覆盖到按钮主体上方,造成按钮“消失”的视觉假象。
解决办法
提供两种可行方案,可根据需求选择:
方案1:移除3D变换相关属性(推荐)
由于你的伪元素仅用于模拟边框,不需要复杂的3D空间,直接移除按钮上的transform-style: preserve-3d,同时去掉伪元素的translateZ(-1px),仅通过z-index: -1就能保证伪元素在按钮下方:
button { /* 移除 transform-style: preserve-3d; */ padding: 5px 16px; border-radius: 4px; outline: none; background: linear-gradient(to bottom, #fff 0 30%, #e2e2e2 70% 100%); color: black; border: none; position: relative; letter-spacing: -0.3px; text-shadow: -0.5px -0.5px 1px rgba(0, 0, 0, 0.1); transition: 0s; font-family: "Lucida Grande", sans-serif; transform: scale(4); margin: 200px; } button::after { content: ''; position: absolute; background: rgb(120, 120, 120); width: calc(100% + 2px); height: calc(100% + 2px); left: -1px; top: -1px; /* 移除 transform: translateZ(-1px); */ border-radius: 5px; opacity: 1; z-index: -1; } button:active::after { content: ''; position: absolute; background: linear-gradient(to bottom, rgb(89, 92, 169) 0 40%, rgb(80, 89, 142) 60% 100%); width: calc(100% + 2px); height: calc(100% + 2px); left: -1px; top: -1px; /* 移除 transform: translateZ(-1px); */ border-radius: 5px; opacity: 1; z-index: -1; }
方案2:将滤镜动画转移到伪元素
如果需要保留3D变换效果,可把glow动画从按钮主体转移到伪元素上,避免按钮被滤镜影响:
button:active { background: linear-gradient(to bottom, rgb(188, 206, 233) 0, rgb(115, 158, 227) 50%, rgb(92, 145, 226) 51%, rgb(174, 215, 231) 100%); /* 移除按钮上的animation */ } button:active::after { content: ''; position: absolute; background: linear-gradient(to bottom, rgb(89, 92, 169) 0 40%, rgb(80, 89, 142) 60% 100%); width: calc(100% + 2px); height: calc(100% + 2px); left: -1px; top: -1px; transform: translateZ(-1px); border-radius: 5px; opacity: 1; animation: glow 1s infinite; /* 将动画移至伪元素 */ } @keyframes glow { 0% { filter: brightness(1.1); } 50% { filter: brightness(1.2); } 100% { filter: brightness(1.1); } }
内容的提问来源于stack exchange,提问作者clos
相关产品推荐
相关产品推荐

