React中Card组件颜色异常:部分颜色不生效
问题:Card组件下方区域及hover状态颜色不生效
我开发了一个Card组件,通过props传入color、name、value参数。当前遇到的问题是:除第2个卡片外,其余卡片的主颜色可正常显示,但所有卡片的下方区域颜色和hover状态颜色均不生效,不过控制台输出的所有颜色类名都是正确的。
相关代码
Card.jsx
import Icon from "@mdi/react"; import { mdiArrowRightCircle } from "@mdi/js"; function Card({ color, name, value }) { const [colorName, shade] = color.split('-'); const lowerShade = (parseInt(shade) + 100).toString(); const hoverShade = (parseInt(shade) + 200).toString(); const mainColor = `bg-${colorName}-${shade}`; const lowerColor = `bg-${colorName}-${lowerShade}`; const hoverColor = `bg-${colorName}-${hoverShade}`; console.log("Main Color = "+ mainColor + "Lower Color = " + lowerColor +"Hover Color = " + hoverColor); return ( <div className="h-full w-1/6 mx-2 rounded-lg overflow-hidden flex flex-col"> <div className={`${mainColor} text-white flex flex-col h-5/6 px-4 pt-2`}> <span className="h-1/4">{name}</span> <span className="text-4xl font-semibold h-3/4 flex items-center"> {value} </span> </div> <div className={`h-1/6 ${lowerColor} flex items-center justify-center hover:${hoverColor} text-white hover:cursor-pointer`}> <span>More info </span> <Icon path={mdiArrowRightCircle} size={1} /> </div> </div> ); } export default Card;
Home.jsx
<div className="h-1/6 flex"> <Card color={"gray-400"} name={"Risk Level %"} value={initialValue} /> <Card color={"teal-400"} name={"Number of Questions"} value={initialValue} /> <Card color={"yellow-400"} name={"LOW Level Questions"} value={initialValue} /> <Card color={"red-600"} name={"MEDIUM Level Questions"} value={initialValue} /> <Card color={"purple-600"} name={"HIGH Level Questions"} value={initialValue} /> <Card color={"slate-700"} name={"Other Level Questions"} value={initialValue} /> </div>
控制台输出
Main Color = bg-gray-400 Lower Color = bg-gray-500 Hover Color = bg-gray-600 Main Color = bg-teal-400 Lower Color = bg-teal-500 Hover Color = bg-teal-600 Main Color = bg-yellow-400 Lower Color = bg-yellow-500 Hover Color = bg-yellow-600 Main Color = bg-red-600 Lower Color = bg-red-700 Hover Color = bg-red-800 Main Color = bg-purple-600 Lower Color = bg-purple-700 Hover Color = bg-purple-800 Main Color = bg-slate-700 Lower Color = bg-slate-800 Hover Color = bg-slate-900
问题原因
这是Tailwind CSS的动态类名识别机制限制导致的:
- Tailwind在构建阶段只会扫描源码中静态写死的类名,动态拼接的类名(比如
hover:${hoverColor})不会被识别,因此对应的样式不会被打包到最终CSS文件中。 - 第二个卡片的主色能正常显示,是因为项目其他地方可能静态使用过
bg-teal-400,被Tailwind扫描并保留了样式;而所有动态生成的lowerColor和hoverColor类都没被扫描到,所以无法生效。
解决方案
方案1:使用内联样式结合Tailwind工具类
直接通过style属性设置背景色,hover状态用事件监听切换:
import Icon from "@mdi/react"; import { mdiArrowRightCircle } from "@mdi/js"; import colors from 'tailwindcss/colors'; function Card({ color, name, value }) { const [colorName, shade] = color.split('-'); const baseColor = colors[colorName]; const mainColor = baseColor[shade]; const lowerShade = (parseInt(shade) + 100).toString(); const lowerColor = baseColor[lowerShade]; const hoverShade = (parseInt(shade) + 200).toString(); const hoverColor = baseColor[hoverShade]; return ( <div className="h-full w-1/6 mx-2 rounded-lg overflow-hidden flex flex-col"> <div className="text-white flex flex-col h-5/6 px-4 pt-2" style={{ backgroundColor: mainColor }} > <span className="h-1/4">{name}</span> <span className="text-4xl font-semibold h-3/4 flex items-center"> {value} </span> </div> <div className="h-1/6 flex items-center justify-center text-white hover:cursor-pointer" style={{ backgroundColor: lowerColor }} onMouseEnter={(e) => e.currentTarget.style.backgroundColor = hoverColor} onMouseLeave={(e) => e.currentTarget.style.backgroundColor = lowerColor} > <span>More info </span> <Icon path={mdiArrowRightCircle} size={1} /> </div> </div> ); } export default Card;
方案2:在Tailwind配置中添加安全列表(Safelist)
强制Tailwind包含所有可能用到的动态类,在tailwind.config.js中添加:
/** @type {import('tailwindcss').Config} */ module.exports = { content: [ "./src/**/*.{js,jsx,ts,tsx}", ], safelist: [ // 匹配所有需要的背景色类及hover变体 { pattern: /bg-(gray|teal|yellow|red|purple|slate)-[4-9]00/, variants: ['hover'], }, ], theme: { extend: {}, }, plugins: [], }
配置后,Tailwind会把匹配到的类全部打包进CSS,动态拼接的类就能正常生效。
方案3:使用CSS变量结合Tailwind自定义颜色语法
通过CSS变量传递颜色值,再用Tailwind的bg-[var(--xxx)]语法引用:
import Icon from "@mdi/react"; import { mdiArrowRightCircle } from "@mdi/js"; import colors from 'tailwindcss/colors'; function Card({ color, name, value }) { const [colorName, shade] = color.split('-'); const baseColor = colors[colorName]; const mainColor = baseColor[shade]; const lowerShade = (parseInt(shade) + 100).toString(); const lowerColor = baseColor[lowerShade]; const hoverShade = (parseInt(shade) + 200).toString(); const hoverColor = baseColor[hoverShade]; return ( <div className="h-full w-1/6 mx-2 rounded-lg overflow-hidden flex flex-col" style={{ '--main-color': mainColor, '--lower-color': lowerColor, '--hover-color': hoverColor, }} > <div className="bg-[var(--main-color)] text-white flex flex-col h-5/6 px-4 pt-2"> <span className="h-1/4">{name}</span> <span className="text-4xl font-semibold h-3/4 flex items-center"> {value} </span> </div> <div className="h-1/6 bg-[var(--lower-color)] flex items-center justify-center hover:bg-[var(--hover-color)] text-white hover:cursor-pointer"> <span>More info </span> <Icon path={mdiArrowRightCircle} size={1} /> </div> </div> ); } export default Card;
内容的提问来源于stack exchange,提问作者Walli Ahmad
相关产品推荐
相关产品推荐

