You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中CSS Modules动态切换类名实现导航栏悬停动画问题排查

导航栏悬停动画修复方案

你的代码存在三个核心问题,直接导致功能失效,下面是修复细节:

问题排查

  1. 状态变量未正确绑定:你用styles.className访问CSS Modules类,但className是动态状态变量,必须用styles[className]的方式才能正确获取对应的类名
  2. 类名切换错误:你试图切换到line::before,但伪元素选择器不能作为类名使用,应该切换到line类,伪元素是依附在这个类上的样式
  3. 动画状态未保留:动画结束后伪元素会回到初始位置,需要添加animation-fill-mode: forwards来保持最终状态

修复后的完整代码

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;
/* 基础样式:默认状态的横线 */
.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 02:19:54