waving underline 滚动的下划线

🤔问题

在浏览张鑫旭前辈的博客时看到了这个下滑波浪线的效果,并参考了前辈的《CSS实现文字下面波浪线动画效果》一文,自己也对照着实现了一下。本文主要是对纯CSS实现波浪下划线效果的思路分析。在继续往下看之前,屏幕前的你会想着怎么实现呢?

💡思路

实现思路有三个关键点:一是使用径向渐变画两个圈圈;二是利用background的大小、位置、重复等属性调整圈圈,实现波浪效果;三是做成动画animation让波浪动起来。如果你并不能马上回忆起径向渐变的相关知识点,页底给出了MDN连接。下面就一步步来实现这个效果。

Step1:画两个圈

现在给一个div设置 20*20大小的背景图,并放置在元素左下角。背景图上以中心为圆心,画两个圈圈,分别为蓝色和红色:

1
2
3
4
5
6
7
.wave-underline{
background-image:radial-gradient(circle at 10px 10px,transparent 9px,red 9px,red 10px,transparent 10px),
radial-gradient(circle at 10px 10px,transparent 9px,blue 9px,blue 10px,transparent 10px);
background-size:20px 20px;
background-repeat: no-repeat;
background-position:0px 100%,0px 100%;
}
 

因为两个圈圈除了颜色,其他设置一模一样,所以重叠了。

Step2:移动两个圈圈的圆心坐标

分别移动两个圆的圆心垂直坐标,因为超出背景范围的部分不会被渲染,所以看起来就像圆被裁掉了。现仅保留每个圆3px高的圆弧,即一个圆向下移动17px,此时垂直坐标为17px+10px=27px,同样另一个圆向上移动后坐标为10px-17px=-7px

1
2
background-image:radial-gradient(circle at 10px 27px,transparent 9px,red 9px,red 10px,transparent 10px),                                 radial-gradient(circle at 10px -7px,transparent 9px,blue 9px,blue 10px,transparent 10px)
background-position:0px 100%,0px 100%;
 

Step3:移动背景图位置

分别移动两个圆弧的background-position,使它们能够连续起来,这个时候可以把background-repeat设置成repeat-x 方便调试。

1
2
background-repeat: repeat-x;
background-position:-10px calc(100% - 8px),0px calc(100% + 10px);
 

Step4:使波浪动起来

定义一个移动动画:

1
2
3
4
@keyframes movingWaving{
from{background-position-x:-10px,0px;}
to{background-position-x:-30px,-10px;}
}

使用动画:

1
animation:1s movingWaving infinite linear;
 

🎉解决方案

一步一步走下来,代码思路是不是清晰了很多呢?最后一步是统一颜色,如果希望波浪线能够自动和字体颜色同步,可以用currentcolor代替具体的颜色值。最后给出全部实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
 @keyframes movingWaving{
from{background-position-x:0px,10px;}
to{background-position-x:-20px,-10px;}
}
.wave-underline:hover,.wave-underline:focus{
background-image:radial-gradient(circle at 10px 27px,transparent 9px,currentcolor 9px,currentcolor 10px,transparent 10px),
radial-gradient(circle at 10px -7px,transparent 9px,currentcolor 9px,currentcolor 10px,transparent 10px);
background-size:20px 20px;
background-repeat: repeat-x;
background-position:-10px calc(100% - 8px),0px calc(100% + 10px);
animation:1s movingWaving infinite linear;
}
试试把鼠标移到我身上

🚧注意

仔细观察,其实纯css实现的波浪线并不是那么平滑,如果希望线条更完美,你可以用SVG图形方案。 下面给出代码:

1
2
3
4
5
6
7
8
9
10
@keyframes waveMove {
from { background-position: 0 100%; }
to{ background-position: -20px 100%; }
}
.svg-wave:hover,.svg-wave:focus{
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 4'%3E%3Cpath fill='none' stroke='%23F30' d='M0 3.5c5 0 5-3 10-3s5 3 10 3 5-3 10-3 5 3 10 3'/%3E%3C/svg%3E") repeat-x 0 100%;
background-size: 20px auto;

animation: waveMove 1s infinite linear;
}
鼠标指向我看效果

这种方案的波浪线颜色需要手动修改。修改位置是 stroke='%23F30'。其中%23就是#,现在的颜色就是#F30。如果要改颜色为#333,就是设置成stroke='%23333'

🌵最后

0%