文字悬停效果
效果展示
CSS 知识点
- CSS 变量使用回顾
- -webkit-text-stroke 属性的运用与回顾
页面整体结构实现
<ul>
<li style="--clr: #e6444f">
<a href="#" class="text">First</a>
</li>
<li style="--clr: #f0b024">
<a href="#" class="text">Attempt</a>
</li>
<li style="--clr: #00a492">
<a href="#" class="text">In</a>
</li>
<li style="--clr: #af579b">
<a href="#" class="text">Learning</a>
</li>
</ul>
实现页面文字整体布局效果
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #222;
overflow: hidden;
}
ul {
position: relative;
display: flex;
flex-direction: column;
gap: 20px;
}
ul li {
list-style: none;
}
ul li .text {
font-size: 4em;
text-transform: uppercase;
cursor: pointer;
text-decoration: none;
font-weight: 800;
line-height: 1em;
display: flex;
align-items: center;
}
使用 JavaScript 拆分文字
为了方便实现我们需要的效果,需要把每个单词进行拆分,并且为每个字母添加同的样式和动画效果。具体的拆分代码如下:
const texts = document.querySelectorAll(".text");
texts.forEach((text) => {
// 获取A标签中的单词,使用trim()函数进行字符串的切割,然后添加到A标签中
const spans = Array.from(text.textContent.trim())
.map((char) => `<span>${char === "" ? " " : char}</span>`)
.join("");
text.innerHTML = spans;
const spanList = text.querySelectorAll("span");
spanList.forEach((span, index) => {
span.addEventListener("mouseover", () => {
spanList.forEach((s, i) => {
const distance = Math.abs(index - i);
const delay = (distance * 0.1).toFixed(1);
s.style.transitionDelay = `${delay}s`;
});
});
});
});
为每个单词添加基础样式
ul li .text span:not(:first-child) {
letter-spacing: 0.1em;
}
ul li .text span {
position: relative;
-webkit-text-stroke: 1px #fff;
color: transparent;
transition: 1s;
transform: rotateX(0deg);
}
ul li .text span:nth-child(1) {
width: 70px;
height: 70px;
background: var(--clr);
color: #222;
-webkit-text-stroke: 0px #fff;
display: flex;
justify-content: center;
align-items: center;
margin-right: 5px;
}
为每个单词添加悬停样式
ul li .text:hover span:not(:first-child) {
color: var(--clr);
transition: 1s;
transform: rotateX(360deg);
-webkit-text-stroke: 1px transparent;
}
完整代码下载
完整代码下载