当前位置: 首页 > Web前端 > HTML

用纯CSS实现超酷的粘性泡泡效果

时间:2023-03-28 12:32:03 HTML

最近在CodePen上看到这样一个很有意思的效果:这个效果的核心难点是泡泡的特殊融合效果。其源码在:CodePenDemo--Goeyfooter,作者主要使用SVG滤镜完成效果,感兴趣的可以查看源码。其中,要想在SVG中灵活使用feGaussianBlur滤镜,还是需要非常强大的SVG知识储备。那么,是否可以仅使用CSS来实现这种效果呢?嘿,强大的CSS当然是可以的。本文将带领大家一步步使用纯CSS实现上述效果。使用SASS完成一般效果首先,如果上面的效果没有气泡的融合效果,可能只是这样:做这样的效果比较简单,但是代码会比较多,我们可以使用SASS预处理器。假设我们有以下HTML结构:

//...200个g-bubbles
核心要做的就是让200个.g-bubbles从底部不规则的往上冒。在这里,我们需要使用我们在CSS动画一文中简单介绍过的技术——使用animation-duration和animation-delay来构建随机效果。使用animation-duration和animation-delay构建具有相同动画的随机动画,我们可以在一定范围内使用randomanimation-duration和animation-delay来有效构建更加随机的动画效果,让动画更加流畅自然。我们来模拟一下,如果我们用10个animation-duration和animation-delay都一样的圆,核心伪代码:ul{显示:flex;弹性包装:nowrap;间隙:5px;}li{背景:#000;动画:移动3s无限1s线性;}@keyframesmove{0%{transform:translate(0,0);}100%{转换:翻译(0,-100px);}}这样小球的运动就会很均匀:要让小球的运动非常随机,只需要让animation-duration和animation-delay都在一定范围内浮动,修改CSS即可:@对于$i从1到11{li:nth-child(#{$i}){animation-duration:#{random(2000)/1000+2}s;动画延迟:#{random(1000)/1000+1}s;}}我们使用SASS循环和random()函数让animation-duration在2-4秒范围内随机化,让animation-delay在1-2秒范围内随机化,这样我们就可以得到非常自然和不同的上升动画效果,基本上不会出现重复的画面,随机效果模拟的很好:CodePenDemo--使用rangerandomanimation-duration和animation-delay实现随机动画效果。我们将上面介绍的技巧应用到本文想要达到的效果中。再看一下HTML结构://...200个g气泡核心CSS代码:.g-footer{position:absolute;底部:0;左:0;高度:86px;宽度:100%;背景:#26b4f5;}@for$i从0到200{.g-bubble:nth-child(#{$i}){position:absolute;背景:#26b4f5;$宽度:随机(100)+像素;左:#{(random(100))+'%'};顶部:#{(random(100))}px;宽度:$宽度;高度:$宽度;动画:moveToTop#{(random(2500)+1500)/1000}sease-in-out-#{random(5000)/1000}sinfinite;}}@keyframesmoveToTop{90%{不透明度:1;}100%{不透明度:0.08;变换:平移(-50%,-180px)比例(.3);这里:我们使用SASS随机函数$width:random(100)+px;随机生成不同大小的div圆使用SASS随机函数左:#{(random(100))+'%'},上:#{(random(100))}px根据父元素随机定位核心是动画:moveToTop#{(random(2500)+1500)/1000}sease-in-out-#{random(5000)/1000}sinfinite,让所有div圈的移动是随机的。综合以上(1)和(2)的结果会生成这样的布局,均匀分布的圆圈:注:为了方便理解,我隐藏了最外层的g-页脚的颜色,并在其中添加了黑色边框g-bubble接下来,如果我们替换动画语句,使用统一的动画时长,去掉负延迟,变成动画:moveToTop4sease-in-outinfinite,动画会是这样的:整体整齐统一,使用随机效果没有随机效果,动画:moveToTop#{(random(2500)+1500)/1000}sease-in-out-#{random(5000)/1000}s无穷大,即可得到上面提到的不同气泡随机上升的感觉:添加融合效果接下来最重要的一步是如何制作气泡之间以及气泡与底部.g-footer之间的融合效果?这个技巧在之前的很多文章中都经常提到,就是使用滤镜:contrast()滤镜和滤镜:blur()滤镜。如果你还不知道这个技巧,可以看看我的这篇文章:你不知道的CSS过滤技巧及细节。简单描述一下技巧:分别取出两个滤镜,它们的作用是:filter:blur():给图像设置高斯模糊效果。filter:contrast():调整图像的对比度。然而,当它们“合体”时,却发生了奇妙的融合现象。仔细看两个圆相交的过程。当边缘相互接触时,会产生边界融合效应。通过contrastfilter消除高斯模糊的模糊边缘,利用高斯模糊达到融合效果。基于此,我们简单修改我们的CSS代码,需要添加的代码量非常少:.g-wrap{background:#fff;filter:contrast(8);}.g-footer{//...Otherskeepthesamefilter:blur(5px);}就这么简单,给父级添加白色背景色和对比滤镜filter:contrast(8)container,在子容器中添加filter:blur(5px),这样我们就可以得到气泡的融合效果,基本上就得到了我们想要的效果:使用backdrop-filter代替filter来消除边缘但是!filter:blur()有一个小问题。对于使用了filter:blur()的元素,元素的边缘不够模糊,会导致效果在边缘处扭曲变形。让我们仔细看看动画的边缘:如何解决?这很容易做到,在这里,我们尝试使用backdrop-filter来代替filter。两者的区别在于filter作用于元素本身,而backdrop-filter作用于元素后面区域覆盖的所有元素。如果您想了解更多关于backdrop-filter的信息,可以点击这里文章:深入了解filter和backdrop-filter的异同。简单修改一下代码,原代码:.g-footer{//...filter:blur(5px);}修改后的代码:.g-footer{//...removefilter:blur(5px)&:在{内容:“”之前;位置:绝对;顶部:-300px;左:0;右:0;底部:0;z-索引:1;背景滤镜:模糊(5px);filter:blur(5px)添加到.g-footer,通过它的伪元素,在其自身之上覆盖一个新元素,并添加替换backdrop-filter:blur(5px)。当然,因为这里的blur(5px)也需要为气泡之间的融合服务,所以为了覆盖动画的整个区域,我们还设置了top:-300px来扩大它的作用范围。最终,我们可以完美复现文章开头使用SVG滤镜实现的效果:文中我省略了大部分基本的CSS代码,完整代码可以点这里:CodePenDemo--BubbleRises的最后,这篇文章和之前熟练使用CSS实现炫酷充电动画的技巧很相似,不过这篇文章也有一些新的知识点,大家可以一起看看。好了,本文到此结束,希望对大家有所帮助:)有什么问题或者建议可以多交流,原创文章,文笔有限,知识匮乏,如有不妥之处,敬请谅解!文章,请告诉我。