React中CSS Modules动态切换类名实现导航栏悬停动画问题排查
导航栏悬停动画修复方案
你的代码存在三个核心问题,直接导致功能失效,下面是修复细节:
问题排查
- 状态变量未正确绑定:你用
styles.className访问CSS Modules类,但className是动态状态变量,必须用styles[className]的方式才能正确获取对应的类名 - 类名切换错误:你试图切换到
line::before,但伪元素选择器不能作为类名使用,应该切换到line类,伪元素是依附在这个类上的样式 - 动画状态未保留:动画结束后伪元素会回到初始位置,需要添加
animation-fill-mode: forwards来保持最终状态
修复后的完整代码
Navbar.jsx
import React, { useState } from "react"; import { Link } from "react-router-dom"; import styles from "../styles/Navbar.module.css"; const Navbar = () => { // 初始状态绑定line-after类 const [activeClass, setActiveClass] = useState("line-after"); return ( <div className="navbar" // 鼠标进入切换到line类,触发伪元素动画 onMouseEnter={() => setActiveClass("line")} // 鼠标离开切回初始类 onMouseLeave={() => setActiveClass("line-after")} > <nav> <Link to="/about" className="home-page"> Bob <br /> Jones </Link> <ul> <li> <Link to="/about" className="about-page"> About </Link> </li> <li> <Link to="/resume" className="resume-page"> Resume </Link> </li> <li> <Link to="/contact" className="contact-page"> Contact </Link> </li> </ul> </nav> // 用方括号语法访问动态类名 <div className={styles[activeClass]}></div> </div> ); }; export default Navbar;
Navbar.module.css
/* 基础样式:默认状态的横线 */ .line-after { margin: 40px; width: 55px; height: 1px; background: white; position: relative; } /* 悬停状态:触发伪元素动画 */ .line { /* 继承基础样式,避免代码重复 */ composes: line-after; } .line::before { content: ""; position: absolute; top: 0; left: 0; width: 55px; height: 1px; background: black; animation-name: animate; animation-duration: 1s; /* 保持动画结束后的状态 */ animation-fill-mode: forwards; } @keyframes animate { 0% { left: 0; } 100% { left: 100%; } }
额外说明
- 用
composes让.line继承.line-after的样式,减少冗余代码 - 把状态变量名从
className改成activeClass,语义更清晰,也避免和原生className属性混淆 - 动画添加
forwards后,鼠标离开时切回line-after类即可恢复初始状态,逻辑已在代码中实现
内容的提问来源于stack exchange,提问作者codebeginner
相关产品推荐
相关产品推荐

