使用CSS伪元素制作动感超酷的hover动画

J.sky
CSS
2023/5/7

css 有很多神奇的效果都是使用 CSS 伪元素利用视觉差来制作的,以前没怎么深入的研究过 css,这次复习 css 的知识点才恍然大悟,原来 css 这么 cool。

动画实现原理

这个组动画的实现原理很简单,前边是一个 div,这个 div 后边再加一个 div 做动画就可以实现了,那么我们需要前后两个 div 叠加在一起?NoNoNo,这个时候就需要 CSS 伪元素::before 和::after 出场了。

CSS 伪元素::before::after

CSS 伪元素::after 用来创建一个伪元素,作为已选中元素的最后一个子元素。通常会配合 content 属性来为该元素添加装饰内容。这个虚拟元素默认是行内元素。

::before::after 的区别就是一前一后,举个简单的例子:

举个例子:

<div id="demo1">这是顶部的div</div> <style> #demo1{ position: relative; width:100px; height:100px; color: white; background-color: black; } #demo1::before{ content:''; position: absolute; width:110px; height:110px; z-index: -1; top:-5px; left:-5px; background-image: linear-gradient( var(--rotate), #5ddcff, #3c67e3 43%, #4e00c2); } #demo1::after{ content:''; position: absolute; width:120px; height:120px; z-index: -2; top:-10px; left:-10px; background: linear-gradient(115deg, #4fcf70, #fad648, #a767e5, #12bcfe, #44ce7b); } </style> <br>

代码如下:

<div id="demo1">这是顶部的div</div>
<style>
    #demo1{
        position: relative;
        width:100px;
        height:100px;
        color: white;
        background-color: black;
    }
    #demo1::before{
        content:'';
        position: absolute;
        width:110px;
        height:110px;
        z-index: -1;
        top:-5px;
        left:-5px;
        background-image: linear-gradient(
                    var(--rotate), #5ddcff, #3c67e3 43%, #4e00c2);
    }
    #demo1::after{
        content:'';
        position: absolute;
        width:120px;
        height:120px;
        z-index: -2;
        top:-10px;
        left:-10px;
        background: linear-gradient(115deg, #4fcf70, #fad648, #a767e5, #12bcfe, #44ce7b);
    }
</style>

这段 css 代码中有几个关键的属性

  1. div 必须作为伪元素定位的父类 position: relative;
  2. 伪元素为相对于 div 定位 position: absolute;
  3. 通过其他css属性来定义伪元素的属性,产生层叠和视觉上的错位。

最后就是利用 animation 来制作动画了,动画的效果可以选择移动旋转或是透明度,可以产生各种超酷的效果。

看下最后的效果:

<div id="demo2">这是顶部的div</div> <style> @property --rotate { syntax: "<angle>"; initial-value: 132deg; inherits: false; } #demo2{ position: relative; width:103px; height:103px; color: white; background-color: black; border-radius: 8px; padding: 3px; } #demo2::before { content: ""; width: 112px; height: 112px; border-radius: 8px; background-image: linear-gradient( var(--rotate), #5ddcff, #3c67e3 43%, #4e00c2); position: absolute; z-index: -1; top: -5px; left: -5px; animation: spin1 2.5s linear infinite; } #demo2::after{ position: absolute; content: ""; top:30px; left: 0; right: 0; z-index: -1; height: 100%; width: 100%; margin: 0 auto; transform: scale(0.8); filter: blur(30px); background-image: linear-gradient( var(--rotate), #5ddcff, #3c67e3 43%, #4e00c2); opacity: 1; transition: opacity .5s; animation: spin1 2.5s linear infinite; } @keyframes spin1 { 0% { --rotate: 0deg; } 100% { --rotate: 720deg; } } </style> <br> 完整的效果代码如下:
<div id="demo2">这是顶部的div</div>
<style>
    @property --rotate {
            syntax: "<angle>";
            initial-value: 132deg;
            inherits: false;
        }
    #demo2{
        position: relative;
        width:103px;
        height:103px;
        color: white;
        background-color: black;
        border-radius: 8px;
        padding: 3px;
    }
    #demo2::before {
        content: "";
        width: 112px;
        height: 112px;
        border-radius: 8px;
        background-image: linear-gradient(
                    var(--rotate), #5ddcff, #3c67e3 43%, #4e00c2);
        position: absolute;
        z-index: -1;
        top: -5px;
        left: -5px;
        animation: spin1 2.5s linear infinite;
        }
    #demo2::after{
        position: absolute;
        content: "";
        top: calc(var(--card-height) / 6);
        left: 0;
        right: 0;
        z-index: -1;
        height: 100%;
        width: 100%;
        margin: 0 auto;
        transform: scale(0.8);
        filter: blur(calc(var(--card-height) / 5));
        background-image: linear-gradient(
                    var(--rotate), #5ddcff, #3c67e3 43%, #4e00c2);
        opacity: 1;
        transition: opacity .5s;
        animation: spin1 2.5s linear infinite;
    }
    @keyframes spin1 {
            0% {
                --rotate: 0deg;
            }
            100% {
                --rotate: 720deg;
            }
        }
</style>

这个 css 的效果主要是靠伪类的动画来实现的,具体的细节还需要自己多多调试修改各个参数,使之达到自己的期望的动效。