可以看到并不是简单地hover改变文字颜色,而是颜色滑动改变效果
方法1:使用背景渐变
<a href="#">A smile hovered on her lips</a>
a{
position: relative;
font-size: 30px;
color: #333;/*无效*/
overflow: hidden;
background: linear-gradient(to right, #1890ff, #1890ff 50%, #333 50%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 200% 100%;
background-position: 100%;
transition: background-position 0.3s ease;
}
a:hover {
background-position: 0 100%;
}
实现该效果的要点
background: linear-gradient------背景渐变,这个不用多说
background-clip: text------设置背景的绘制区域只针对文字
text-fill-color: transparent------文字的填充颜色,值为透明时,背景渐变才会对文字生效;该属性跟color同时设置时,会覆盖掉color
background-size: 200% 100%------使背景的长度扩大为原来的两倍,也就是文字长度的两倍
background-position: 100%------这个属性的百分比并不是根据父元素的宽度来计算的,它有自己的一些计算原理
background-position: x y
x:{容器(container)的宽度—背景图片的宽度}*x百分比,超出的部分隐藏。
y:{容器(container)的高度—背景图片的高度}*y百分比,超出的部分隐藏。
- top left, left top 等价于 0% 0%.
- top, top center, center top 等价于 50% 0%.
- right top, top right 等价于 100% 0%.
- left, left center, center left 等价于 0% 50%.
- center, center center 等价于 50% 50%.
- right, right center, center right 等价于 100% 50%.
- bottom left, left bottom 等价于 0% 100%.
- bottom, bottom center, center bottom 等价于 50% 100%.
- bottom right, right bottom 等价于 100% 100%.
方法2:伪元素+宽度变化
<a href="#" data-content="A smile hovered on her lips">A smile hovered on her lips</a>
a{
position: relative;
font-size: 30px;
color: #333;
font-weight: 800;
text-decoration: underline;
overflow: hidden;
}
a::before {
position: absolute;
top: 0;
left: 0;
width: 0;
content: attr(data-content);
color: #1890ff;
text-decoration: underline;
transition: width .3s ease;
overflow: hidden;
white-space: nowrap;
}
a:hover::before {
width: 100%;
}
这个方法比较简单,主要是伪元素使用attr属性获取标签自定义属性的值,伪元素初始宽度为0,并定位到a标签的最左边,然后设置伪元素的内容强制不换行
方法3:伪元素+clip-path
<a href="#" data-content="A smile hovered on her lips">A smile hovered on her lips</a>
a::before {
position: absolute;
content: attr(data-content);
color: #1890ff;
text-decoration: underline;
clip-path: polygon(0 0, 0 0, 0% 100%, 0 100%);
transition: clip-path .3s ease;
}
a:hover::before {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
要点:跟第二种方法有点类似,只不过换了种思路,使用了clip-path:路径剪切
先看下clip-path的值
0 0= 左上方0 0= 右上方100% 0= 右下0 100%= 左下角
如果不太理解,这里分享一个很有意思的网站css路径剪切生成器,可能你会豁然开朗
方法4:伪元素+translate
<a href="#">
<span data-content="A smile hovered on her lips">
</span>
A smile hovered on her lips
</a>
a span{
position: absolute;
top: 0;
left: 0;
overflow: hidden;
transform: translateX(-100%);
color: #1890ff;
transition: transform 0.3s ease;
}
span::before {
display: inline-block;
content: attr(data-content);
color: #1890ff;
transform: translateX(100%);
transition: transform .3s ease;
text-decoration: underline;
}
a:hover span {
transform: translateX(0);
}
a:hover span::before {
transform: translateX(0);
}
要点:这里在a标签里面嵌套了一个span元素,然后用translateX把该元素移动到了a标签的外面;span元素设置了一个伪元素,同上面一样,用attr属性获取标签自定义属性的值,也用translateX把伪元素移动到跟a标签重合的位置,因为span元素设置了overflow: hidden,所以该元素不会表现出来,hover的时候同时移动span跟伪元素使他们重合
来看下放慢并去掉overflow:hidden的效果
只从视觉效果可以看到span标签的伪元素并没有发生移动,但其实是在相对span元素在移动
总结一下
上面四种方法相对来说,第二种方法兼容性较好,第四种方法采用transform过度,表现得更为平滑
本文的方法跟部分内容来自于原文链接