如何实现clip-path熔岩灯效果?让白色section透出body渐变背景
实现Clip-Path风格熔岩灯效果的解决方案
问题概述
想要将红色熔岩区域变成白色section的“镂空部分”,透过这些镂空看到body上的动态渐变背景,且不想给熔岩单独加渐变(存在动画对齐问题)。
可行方案:用混合模式替代Clip-Path
由于熔岩效果依赖SVG的Goo滤镜实现像素级融合,直接用CSS clip-path无法捕捉滤镜生成的模糊融合边缘。改用**混合模式(mix-blend-mode)**可以完美实现需求,步骤如下:
- 将熔岩色块的红色改为黑色
- 给白色容器添加混合模式,让黑色区域变为透明,透出下方body的渐变
- 调整文字层级,避免被混合效果影响
修改后的代码
HTML(无需改动)
<section class="content"> <div class="lamp"> <div class="lava"> <div class="blob"></div> <div class="blob"></div> <div class="blob"></div> <div class="blob"></div> <div class="blob"></div> <div class="blob"></div> <div class="blob"></div> <div class="blob"></div> <div class="blob top"></div> <div class="blob bottom"></div> </div> </div> <svg> <defs> <filter id="goo"> <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" /> <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" result="goo" /> <feBlend in="SourceGraphic" in2="goo" /> </filter> </defs> </svg> <h1>trying to make the red lava a clip-path. </h1> <p>so i can see the gradient background behind the white section</p> </section>
CSS 修改版
body { background: linear-gradient(-45deg, #E26373, #0098C3, #359F68); background-size: 400% 400%; animation: gradient 15s ease infinite; transition: all .3s ease-in-out; height:100vh; } section.content { position: relative; height:80vh } .lamp { background:white; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); height: 100%; overflow: hidden; width: 100vw; min-width: 100vw; z-index: 1; mix-blend-mode: screen; /* 添加混合模式 */ } .lava { filter: url("#goo"); position: absolute; height: 100%; width: 100%; top: 0; left: 0; } .blob { border-radius: 50%; position: absolute; background: #000; /* 替换原红色为黑色 */ } .blob.top { border-radius: 50%; width: 100%; height: 4%; top: -3%; left: 0; } .blob.bottom { border-radius: 50%; width: 110%; height: 4%; bottom: -3%; left: -50px; } .blob:nth-child(1) { width: 200px; height: 200px; left: 35%; bottom: -15%; animation: wobble 4s ease-in-out alternate infinite, blob-one ease-in-out 13s infinite; } .blob:nth-child(2) { width: 230px; height: 230px; right: 24%; bottom: -65%; animation: wobble 5s ease-in-out alternate infinite, blob-two ease-in-out 22s infinite; } .blob:nth-child(3) { width: 150px; height: 150px; bottom: -15%; left: 34%; animation: wobble 6s ease-in-out alternate infinite, blob-three ease-in-out 16s infinite; } .blob:nth-child(4) { width: 35px; height: 35px; bottom: -19%; left: 30%; animation: wobble 8s ease-in-out alternate infinite, blob-four ease-in-out 12s infinite; } .blob:nth-child(5) { width: 55px; height: 55px; bottom: -25%; left: 34%; animation: wobble 9s ease-in-out alternate infinite, blob-five ease-in-out 32s infinite; } .blob:nth-child(6) { width: 35px; height: 35px; bottom: -25%; right: 34%; animation: wobble 10s ease-in-out alternate infinite, blob-six ease-in-out 12s infinite; } .blob:nth-child(7) { width: 235px; height: 35px; bottom: -85%; right: 40%; animation: wobble 11s ease-in-out alternate infinite, blob-seven ease-in-out 32s infinite; } /* 确保文字在混合容器上方 */ .content h1, .content p { position: relative; z-index: 2; color: #333; } @keyframes blob-one { 0%,100% { transform: translatey(0); } 50% { transform: translatey(-700%); } } @keyframes blob-two { 0%,100% { transform: translatey(0); } 50% { transform: translatey(-420%); } } @keyframes blob-three { 0%,100% { transform: translatey(0); } 50% { transform: translatey(-305%); } } @keyframes blob-four { 0%,100% { transform: translatey(0); } 50% { transform: translatey(-605%); } } @keyframes blob-five { 0%,100% { transform: translatey(0); } 50% { transform: translatey(-700%); } } @keyframes blob-six { 0%,100% { transform: translatey(0); } 50% { transform: translatey(-700%); } } @keyframes blob-seven { 0%,100% { transform: translatey(0); } 50% { transform: translatey(-300%); } } @keyframes wobble { 50% { border-radius: 42% 58% 70% 30% / 45% 45% 55% 55%; } 100% { border-radius: 38% 52% 75% 36% / 50% 40% 50% 60%; } } @keyframes gradient { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
原理说明
mix-blend-mode: screen会让黑色区域与白色背景混合后完全透明,直接透出下方的body渐变;白色区域则保持原有白色- SVG的Goo滤镜效果完全保留,熔岩的融合动画不受影响
- 无需给熔岩添加渐变,完美复用body的动态渐变背景,彻底避免动画对齐问题
内容的提问来源于stack exchange,提问作者will
相关产品推荐
相关产品推荐

