使用css实现女神异闻录5的按钮特效

512 阅读3分钟

1. 简介

效果预览:
4 00_00_00-00_00_30.gif

2. 实现

2.1. 基础布局

先把基本的布局写好,代码如下:

<body>
    <style>
        .container {
            width: 100%;
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        .item {
            position: relative;
            margin: 10px 0;
        }
    </style>

    <div class='container'>
        <div class="item">Button 1</div>
        <div class="item">Button 2</div>
        <div class="item">Button 3</div>
        <div class="item">Button 4</div>
    </div>
</body>

先看看朴素的效果~ 1.PNG

2.2. 伪元素

由于仅使用css,所以此处用before和after两个伪元素来充当红色和蓝色背景。style的代码如下:

<style>
    .container {
        width: 100%;
        display: flex;
        flex-direction: column;
        align-items: center;
     }

     .item {
         position: relative;
         margin: 10px 0;
      }
      
     /***2.2.新增代码***/
    .item:hover:before{
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        background-color: #1cfeff; /*蓝色*/
        z-index: -1; /*避免遮住文字*/
    }
    .item:hover:after{
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        background-color: #ff0022; /*红色*/
        z-index: -1; /*避免遮住文字*/
    }
</style>

依旧先看看效果~

2.png
由于两个伪元素的位置都为 top: 0; left: 0,所以两者都重叠了,只能显示出红色的背景。不过没关系,等它们都动起来就能看出区别。

2.3. 添加css animation

此处通过 skew 扭曲背景,同时通过 scale 进行背景缩放,以达到动态效果。这部分动画我写的比较及简单,有兴趣的朋友可以自己修改。
代码如下:

<style>
    .container {
        width: 100%;
        display: flex;
        flex-direction: column;
        align-items: center;
     }

     .item {
         position: relative;
         margin: 10px 0;
      }
      
     /***2.2.新增代码***/
    .item:hover:before{
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        background-color: #1cfeff; /*蓝色*/
        z-index: -1; /*避免遮住文字*/
        
        animation: bgBlue 1s ease-in infinite; /***2.3.新增代码***/
    }
    .item:hover:after{
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        background-color: #ff0022; /*红色*/
        z-index: -1; /*避免遮住文字*/
        
        animation: bgRed 1s ease-out infinite; /***2.3.新增代码***/ 
    }
    
    /***2.3.新增代码***/
    @keyframes bgBlue {
        0% {top: 6%; transform: skew(-30deg, -2deg) scale(0.7);}
        20% {top: 3%; transform: skew(45deg, 4deg) scale(0.8);}
        40% {top: -2%; transform: skew(-20deg, -2deg) scale(0.9);}
        60% {top: -4%; transform: skew(20deg, 2deg) scale(1);}
        80% {top: 3%; transform: skew(-45deg, -4deg) scale(0.85);}
        100% {top: 6%; transform: skew(45deg, 4deg) scale(0.7);}
    }
    
    @keyframes bgRed {
        0% {top: -4%; transform: skew(45deg, 4deg) scale(1);}
        20% {top: -1%; transform: skew(-30deg, -3deg) scale(0.9);}
        40% {top: 2%; transform: skew(60deg, 6deg) scale(0.75);}
        60% {top: 3%; transform: skew(-20deg, -2deg) scale(0.7);}
        80% {top: -2%; transform: skew(30deg, 3deg) scale(0.85);}
        100% {top: -4%; transform: skew(45deg, 4deg) scale(1);}
    }
</style>

看一下此时的效果: 3.gif
可以看出,现在已经基本完成了,就差背景重叠时的混色效果了。

2.4. mix-blend-mode

该部分更简单,只要在before或after处加一行 mix-blend-mode: screen; 就行。mix-blend-mode是一个很强大的混色属性,详细信息可以自行百度。本文所用的 screen 值表示两种颜色的滤色效果。
整体的style代码如下:

<style>
    .container {
        width: 100%;
        display: flex;
        flex-direction: column;
        align-items: center;
     }

     .item {
         position: relative;
         margin: 10px 0;
      }
      
     /***2.2.新增代码***/
    .item:hover:before{
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        background-color: #1cfeff; /*蓝色*/
        z-index: -1; /*避免遮住文字*/
        
        animation: bgBlue 1s ease-in infinite; /***2.3.新增代码***/
    }
    .item:hover:after{
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        background-color: #ff0022; /*红色*/
        z-index: -1; /*避免遮住文字*/
        
        mix-blend-mode: screen; /***2.4.新增代码***/ 
       
        animation: bgRed 1s ease-out infinite; /***2.3.新增代码***/ 
    }
    
    /***2.3.新增代码***/
    @keyframes bgBlue {
        0% {top: 6%; transform: skew(-30deg, -2deg) scale(0.7);}
        20% {top: 3%; transform: skew(45deg, 4deg) scale(0.8);}
        40% {top: -2%; transform: skew(-20deg, -2deg) scale(0.9);}
        60% {top: -4%; transform: skew(20deg, 2deg) scale(1);}
        80% {top: 3%; transform: skew(-45deg, -4deg) scale(0.85);}
        100% {top: 6%; transform: skew(45deg, 4deg) scale(0.7);}
    }
    
    @keyframes bgRed {
        0% {top: -4%; transform: skew(45deg, 4deg) scale(1);}
        20% {top: -1%; transform: skew(-30deg, -3deg) scale(0.9);}
        40% {top: 2%; transform: skew(60deg, 6deg) scale(0.75);}
        60% {top: 3%; transform: skew(-20deg, -2deg) scale(0.7);}
        80% {top: -2%; transform: skew(30deg, 3deg) scale(0.85);}
        100% {top: -4%; transform: skew(45deg, 4deg) scale(1);}
    }
</style>

完整代码可见1.简介处的Github链接~