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

如何从CSS Module中读取CSS规则的transition-duration属性值?

默认CSS Module导出的styles对象仅包含类名和编译后哈希类名的映射,不会携带CSS内部的属性值,要实现时长复用可以用以下两种方案:

方案1:运行时读取DOM实际样式(无需修改构建配置,最准确)

直接通过DOM API读取元素最终计算后的过渡时长,完全以CSS实际生效值为准,无需额外依赖,修改CSS时长不需要同步改动JS代码。

// MyComponent.js
import { useState, useRef, useEffect } from "react"
import styles from "./MyComponent.module.css"

const MyComponent = () => {
    const [isAnimating, setIsAnimating] = useState(false)
    const animRef = useRef(null)
    const [transitionDuration, setTransitionDuration] = useState(0)

    // 组件挂载后读取过渡时长
    useEffect(() => {
        if (!animRef.current) return
        const computedStyle = getComputedStyle(animRef.current)
        const durationStr = computedStyle.transitionDuration
        let duration = 0
        // 适配s和ms两种单位
        if (durationStr.endsWith('ms')) {
            duration = parseFloat(durationStr)
        } else if (durationStr.endsWith('s')) {
            duration = parseFloat(durationStr) * 1000
        }
        // 存在多个过渡属性时可拆分字符串取最大值,此处为简化实现
        setTransitionDuration(duration)
    }, [])

    const classes = `${styles.animatable} ${isAnimating? styles.animating : ''}`

    const clickHandler = () => {
        setIsAnimating(true)
        setTimeout(() => setIsAnimating(false), transitionDuration)
    }

    return <div ref={animRef} className={classes} onClick={clickHandler}>Click me.</div>
}

export default MyComponent

方案2:构建时通过CSS Module导出变量复用(静态编译,无运行时开销)

使用CSS Module的@value功能(大部分React脚手架默认已支持对应postcss插件),把时长定义为公共变量,同时导出到JS侧使用,全程静态编译没有额外运行时性能损耗。
首先修改CSS文件:

/* MyComponent.module.css */
@value transition-duration: 500ms;

.animatable {
    background-color: red;
    transition-property: background-color;
    transition-duration: transition-duration;
}

.animating {
    background-color: grey;
}

再修改JS文件直接导入定义好的时长变量:

// MyComponent.js
import { useState } from "react"
import styles, { transitionDuration } from "./MyComponent.module.css"

const MyComponent = () => {
    const [isAnimating, setIsAnimating] = useState(false)
    // 把导入的时长字符串转成毫秒数
    const duration = transitionDuration.endsWith('ms') ? parseFloat(transitionDuration) : parseFloat(transitionDuration) * 1000

    const classes = `${styles.animatable} ${isAnimating? styles.animating : ''}`

    const clickHandler = () => {
        setIsAnimating(true)
        setTimeout(() => setIsAnimating(false), duration)
    }

    return <div className={classes} onClick={clickHandler}>Click me.</div>
}

export default MyComponent

内容的提问来源于stack exchange,提问作者theberzi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:54:00