首页 >web前端 >css教程 >使用CSS文本阴影的4个凉爽悬停效果

使用CSS文本阴影的4个凉爽悬停效果

Lisa Kudrow
Lisa Kudrow原创
2025-03-13 10:21:09925浏览

4 Cool Hover Effects That Use CSS Text Shadow

上篇文章我们探讨了如何利用CSS背景属性创建炫酷的悬停效果。这次,我们将重点关注CSS text-shadow 属性,探索更多有趣的悬停效果。你可能想知道,为文本添加阴影怎么可能产生炫酷的效果,但关键在于:我们实际上不会为这些文本悬停效果创建任何阴影。

炫酷悬停效果系列:

  1. 利用背景属性实现炫酷悬停效果
  2. 利用CSS文本阴影实现炫酷悬停效果(您当前位置!)
  3. 利用背景裁剪、蒙版和3D实现炫酷悬停效果

text-shadow 但没有文本阴影?

让我通过以下演示中我们将构建的悬停效果来消除混淆:

不用看代码,你们中的许多人会直觉地认为,对于每个悬停效果,我们都会复制文本,然后独立地对其进行动画处理。现在,如果你查看代码,你会发现HTML中没有任何文本被实际复制。你有没有注意到CSS中没有使用content: "text"

文本图层完全是用text-shadow 创建的!

悬停效果 #1

让我们分解CSS代码:

.hover-1 {
  line-height: 1.2em;
  color: #0000;
  text-shadow: 
    0 0 #000, 
    0 1.2em #1095c1;
  overflow: hidden;
  transition: .3s;
}
.hover-1:hover {
  text-shadow: 
    0 -1.2em #000, 
    0 0 #1095c1;
}

首先要注意的是,为了隐藏实际文本,我将实际文本的颜色设置为透明(使用#0000)。之后,我使用text-shadow 创建两个阴影,每个阴影只定义两个长度值。这意味着没有模糊半径,从而产生清晰锐利的阴影,有效地产生了具有指定颜色的文本副本。

这就是为什么我在引言中声称这里没有阴影的原因。我们所做的与其说是“经典”阴影,不如说是复制文本的一种简单方法。

我们有两个文本图层,我们在悬停时移动它们。如果我们隐藏溢出内容,则重复的文本将不可见,移动会使它看起来像是实际文本被其他文本替换了。这是使本文中所有示例都能正常工作的主要技巧。

让我们优化代码。我多次使用值1.2em 来定义阴影的高度和偏移量,使其成为CSS自定义属性(我们称之为--h)的理想候选者:

.hover-1 {
  --h: 1.2em;

  line-height: var(--h);
  color: #0000;
  text-shadow: 
    0 0 #000, 
    0 var(--h) #1095c1;
  overflow: hidden;
  transition: .3s;
}
.hover-1:hover {
  text-shadow: 
    0 calc(-1 * var(--h)) #000, 
    0 0 #1095c1;
}

我们还可以进一步使用更多calc() 计算来简化代码,以便我们只使用一次text-shadow。(我们在上一篇文章中也做了同样的事情。)

.hover-1 {
  --h: 1.2em;   

  line-height: var(--h);
  color: #0000;
  text-shadow: 
    0 calc(-1*var(--_t, 0em)) #000, 
    0 calc(var(--h) - var(--_t, 0em)) #1095c1;
  overflow: hidden;
  transition: .3s;
}
.hover-1:hover {
  --_t: var(--h);
}

如果你想知道为什么我要在--_t 变量中添加下划线,这只是我用来区分用户可以更新的控制效果的变量(如--h)和仅用于优化目的、不需要更改的内部变量(如--_t)的命名约定。换句话说,下划线是变量名的一部分,没有任何特殊含义。

我们还可以更新代码以获得相反的效果,其中重复的文本从顶部滑入:

我们只对text-shadow 属性做了一个小的更新——我们没有触及其他任何东西!

悬停效果 #2

对于这个效果,我们将动画化两个属性:text-shadowbackground。关于text-shadow,我们仍然像之前的示例一样有两个图层,但这次我们将只移动其中一个,同时在交换期间将另一个图层的颜色设置为透明。

.hover-2 {
  /* 高度 */
  --h: 1.2em;

  line-height: var(--h);
  color: #0000;
  text-shadow: 
    0 var(--_t, var(--h)) #fff,
    0 0 var(--_c, #000);
  transition: 0.3s;
}
.hover-2:hover {
  --_t: 0;
  --_c: #0000;
}

在悬停时,我们将白色文本图层移动到顶部,同时将另一个图层的颜色更改为透明。为此,我们添加了一个应用于渐变的background-size 动画:

最后,我们添加overflow: hidden 以使动画仅在元素的边界内可见:

.hover-2 {
  /* 高度 */
  --h: 1.2em;

  line-height: var(--h);
  color: #0000;
  text-shadow: 
    0 var(--_t,var(--h)) #fff,
    0 0 var(--_c, #000);
  background: 
    linear-gradient(#1095c1 0 0) 
    bottom/100% var(--_d, 0) no-repeat;
  overflow: hidden;
  transition: 0.3s;
}
.hover-2:hover {
  --_d: 100%;
  --_t: 0;
  --_c: #0000;
}

我们在这里所做的是结合CSS text-shadowbackground 属性来创建炫酷的悬停效果。此外,我们能够使用CSS变量来优化代码。

如果背景语法看起来很奇怪,我强烈建议你阅读我之前的文章。下一个悬停效果也依赖于我在那篇文章中详细介绍的动画。除非你熟悉CSS背景技巧,否则我建议你在继续阅读本文之前阅读那篇文章以了解更多背景信息。

在之前的文章中,你向我们展示了如何只使用一个变量来创建悬停效果——在这里可以这样做吗?

是的,绝对可以!我们确实可以使用相同的DRY切换技术,这样我们只需要处理一个CSS自定义属性,该属性仅在悬停时切换值:

.hover-2 {
  /* 高度 */
  --h: 1.2em;

  line-height: var(--h);
  color: #0000;
  text-shadow: 
    0 var(--_i, var(--h)) #fff,
    0 0 rgb(0 0 0 / calc(var(--_i, 1) * 100%) );
  background: 
    linear-gradient(#1095c1 0 0) 
    bottom/100% calc(100% - var(--_i, 1) * 100%) no-repeat;
  overflow: hidden;
  transition: 0.3s;
}
.hover-2:hover {
  --_i: 0;
}

悬停效果 #3

这个悬停效果只不过是我们已经制作的两个效果的组合:上一篇文章中的第二个悬停效果和本文中的第一个悬停效果。

.hover-3 {
  /* 颜色 */
  --c: #1095c1;
  /* 高度 */
  --h: 1.2em;

  /* 本文中第一个悬停效果 */
  line-height: var(--h);  
  color: #0000;
  overflow: hidden;
  text-shadow: 
    0 calc(-1 * var(--_t, 0em)) var(--c), 
    0 calc(var(--h) - var(--_t, 0em)) #fff;
  /* 上一篇文章中的第二个悬停效果 */
  background: 
    linear-gradient(var(--c) 0 0) no-repeat 
    calc(200% - var(--_p, 0%)) 100% / 200% var(--_p, .08em);
  transition: .3s var(--_s, 0s), background-position .3s calc(.3s - var(--_s, 0s));
}
.hover-3:hover {
  --_t: var(--h);
  --_p: 100%;
  --_s: .3s
}

我所做的只是复制和粘贴其他示例中的效果,并对变量名进行了一些小的调整。当它们组合在一起时,它们会产生一个简洁的悬停效果!乍一看,这种效果可能看起来很复杂且难以实现,但最终,它仅仅是将两个相对简单的效果组合成一个。

如果我们考虑我们已经完成的之前的优化,那么使用DRY切换变量技术优化代码也应该是一项简单的任务:

.hover-3 {
  /* 颜色 */
  --c: #1095c1;
  /* 高度 */
  --h: 1.2em;

  line-height: var(--h);  
  color: #0000;
  overflow: hidden;
  text-shadow: 
    0 calc(-1 * var(--h) * var(--_i, 0)) var(--c), 
    0 calc(var(--h) * (1 - var(--_i, 0))) #fff;
  background: 
    linear-gradient(var(--c) 0 0) no-repeat
    calc(200% - var(--_i, 0) * 100%) 100% / 200% calc(100% * var(--_i, 0)   .08em);
  transition: .3s calc(var(--_i, 0) * .3s), background-position .3s calc(.3s - calc(var(--_i, 0) * .3s));
}
.hover-3:hover {
  --_i: 1;
}

悬停效果 #4

此悬停效果是对第二个悬停效果的改进。首先,让我们引入一个clip-path 动画来显示其中一个文本图层,然后再移动它:

这是一个更好的说明,以便更好地理解正在发生的事情:

最初,我们使用inset(0 0 0 0),这类似于overflow: hidden,因为我们只看到实际文本。在悬停时,我们使用等于高度的负值更新第三个值(表示底部偏移量),以显示放置在底部的文本图层。

从那里,我们可以将其添加到我们在本文中制作的第二个悬停效果中,这就是我们得到的结果:

我们越来越近了!请注意,我们需要首先运行clip-path 动画,然后运行其他所有内容。为此,我们可以为悬停时的所有属性添加延迟,除了clip-path

transition: 0.4s 0.4s, clip-path 0.4s;

在鼠标移出时,我们做相反的操作:

transition: 0.4s, clip-path 0.4s 0.4s;

最后的润色是添加一个box-shadow 来创建蓝色矩形的滑动效果。不幸的是,background 无法产生这种效果,因为背景默认情况下会被裁剪到内容区域。同时,box-shadow 可以超出内容区域。

.hover-4 {
  /* 颜色 */
  --c: #1095c1;
  /* 高度 */
  --h: 1.2em;

  line-height: var(--h);
  color: #0000;
  text-shadow: 
    0 var(--_t, var(--h)) #fff,
    0 0 var(--_c, #000);
  box-shadow: 0 var(--_t, var(--h)) var(--c);
  clip-path: inset(0 0 0 0);
  background: linear-gradient(var(--c) 0 0) 0 var(--_t, var(--h)) no-repeat;
  transition: 0.4s, clip-path 0.4s 0.4s;
}
.hover-4:hover {
  --_t: 0;
  --_c: #0000;
  clip-path: inset(0 0 calc(-1 * var(--h)) 0);
  transition: 0.4s 0.4s, clip-path 0.4s;
}

如果你仔细观察box-shadow,你会发现它与text-shadow 内的白色文本图层具有相同的值。这是合乎逻辑的,因为两者都需要以相同的方式移动。两者都会滑到顶部。然后box-shadow 位于元素后面,而text-shadow 位于顶部。

这是一个修改了一些值的演示,用于可视化图层如何移动:

等等,背景语法与第二个悬停效果中使用的语法略有不同!

好眼力!是的,我们正在使用不同的背景技术来产生相同的效果。我们不是将大小从0%动画化为100%,而是动画化位置。

如果我们没有在渐变上指定大小,则它默认情况下会占据整个宽度和高度。由于我们知道元素的高度(--h),我们可以通过将位置从0 var(--h) 更新到0 0 来创建滑动效果。

.hover-4 {
  /* ... */
  background: linear-gradient(var(--c) 0 0) 0 var(--_t, var(--h)) no-repeat;
}
.hover-4:hover {
  --_t: 0;
}

我们可以使用background-size 动画来获得相同的效果,但我们只是向我们的技巧列表中添加了另一个技巧!

在演示中,你还使用了inset(0 0 1px 0)……为什么?

我有时会在此处添加或删除一些像素或百分比来完善看起来不太好的任何内容。在这种情况下,底部出现了一条坏线,添加1px将其删除了。

DRY切换变量优化怎么样?

我把这项任务留给你!在看完这四个悬停效果和之前的文章后,你应该能够更新代码,使其只使用一个变量。我很想在评论中看到你的尝试!

轮到你了!

让我分享最后一个悬停效果,它是前一个效果的另一个版本。你能在不查看代码的情况下找出它是如何实现的吗?这是一个很好的练习,所以不要作弊!

总结

我们查看了许多示例,这些示例展示了如何使用一个元素和几行CSS就足以在文本元素上创建一些看起来相当复杂悬停效果——不需要伪元素!我们甚至能够结合多种技术,以较小的努力实现更复杂的动画。

如果你有兴趣深入研究本文中这四个文本阴影悬停效果之外的内容,请查看我的500种悬停效果合集,我在其中探索了各种不同的技术。

以上是使用CSS文本阴影的4个凉爽悬停效果的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn