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

React+Tailwind CSS渐变进度条颜色匹配问题求助

修复渐变进度条颜色异常问题

我正在使用React与Tailwind CSS开发带渐变效果的技能进度条,但当进度达到特定百分比(例如15%)时,颜色完全不符合预期——此时进度条应全部显示为蓝色,却出现了多种不同颜色。

进度条颜色异常截图

相关代码

Tailwind CSS 自定义样式

.progressbar {
    /* Size */
    height: 10px;

    /* Content alignment */
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-items: stretch;

    /* Style */
    border-radius: 60px;
    background-color: #f0ecec;
    overflow: hidden;
}

.bar {
    /* Size */
    width: 0%;

    /* Style */
    background: rgb(255, 174, 105);
    background: linear-gradient(to right, #12B0FF 0%, #4399E7 7%, #5282DF 15%, #6565D7 22%, #951CC1 30%, #A517B8 37%, #A717B3 45%, #AF18A8 52%, #C83E82 60%, #CF4978 67%, #DE5E62 75%, #E86E51 84%, #F27D42 93%, #FA8838 100%);
}

.progressbar-text-container {
    /* Size */
    width: 30px;

    /* Content alignment */
    display: flex;
    flex-direction: row;

    /* Styling */
    font-weight: bold;
    font-size: 30px;
}

ProgressBar.js 组件

import { motion, animate } from 'framer-motion';
import { useEffect, useState } from "react";

function Progressbar({ name, value })
{
    // Replaced useRef with useState
    const [progressText, setProgressText] = useState("0");

    useEffect(() =>
    {
        animate(parseInt(progressText), value, {
            duration: 1.5,
            onUpdate: (cv) =>
            {
                // Updating state instead of direct DOM manipulation
                setProgressText(cv.toFixed(0));
            }
        });
    }, [value]);

    return (
        <div className="progressbar-container py-2">
            <div className="flex py-1 justify-between">
                <p className="progress-bar-title">{name}</p>
                <div className="flex justify-end">
                    {/* Replaced ref with state variable */}
                    <p className="progress-bar-title">{progressText}</p>
                    <p className="progress-bar-title">%</p>
                </div>
            </div>
            <div className="progressbar">
                <motion.div
                    className="bar"
                    animate={{
                        width: `${value}%`,
                    }}
                    transition={{
                        duration: 1.5
                    }}
                />
            </div>
        </div>
    );
}

export default Progressbar;

问题原因

当前进度条的渐变背景直接应用在.bar元素上,渐变会根据.bar自身的宽度渲染完整的渐变序列。比如当.bar宽度为15%时,渐变会在这15%的宽度内从第一个颜色过渡到15%位置的颜色,导致进度条出现多种颜色,而非预期的单一蓝色。

修复方案

我们需要根据进度百分比,从渐变序列中匹配对应的单一颜色,将其设置为进度条的背景色:

  1. 修改Progressbar组件,添加颜色映射与匹配逻辑:
import { motion, animate } from 'framer-motion';
import { useEffect, useState } from "react";

// 定义渐变颜色的百分比映射
const colorStops = [
  { percent: 0, color: '#12B0FF' },
  { percent: 7, color: '#4399E7' },
  { percent: 15, color: '#5282DF' },
  { percent: 22, color: '#6565D7' },
  { percent: 30, color: '#951CC1' },
  { percent: 37, color: '#A517B8' },
  { percent: 45, color: '#A717B3' },
  { percent: 52, color: '#AF18A8' },
  { percent: 60, color: '#C83E82' },
  { percent: 67, color: '#CF4978' },
  { percent: 75, color: '#DE5E62' },
  { percent: 84, color: '#E86E51' },
  { percent: 93, color: '#F27D42' },
  { percent: 100, color: '#FA8838' }
];

// 根据进度百分比获取对应颜色
function getColorForPercent(percent) {
  for (let i = 1; i < colorStops.length; i++) {
    if (percent <= colorStops[i].percent) {
      return colorStops[i].color;
    }
  }
  return colorStops[colorStops.length - 1].color;
}

function Progressbar({ name, value })
{
    const [progressText, setProgressText] = useState("0");

    useEffect(() =>
    {
        animate(parseInt(progressText), value, {
            duration: 1.5,
            onUpdate: (cv) =>
            {
                setProgressText(cv.toFixed(0));
            }
        });
    }, [value]);

    // 获取当前进度对应的颜色
    const barColor = getColorForPercent(value);

    return (
        <div className="progressbar-container py-2">
            <div className="flex py-1 justify-between">
                <p className="progress-bar-title">{name}</p>
                <div className="flex justify-end">
                    <p className="progress-bar-title">{progressText}</p>
                    <p className="progress-bar-title">%</p>
                </div>
            </div>
            <div className="progressbar">
                <motion.div
                    className="bar"
                    // 设置进度条背景色为匹配到的单一颜色
                    style={{ backgroundColor: barColor }}
                    animate={{
                        width: `${value}%`,
                    }}
                    transition={{
                        duration: 1.5
                    }}
                />
            </div>
        </div>
    );
}

export default Progressbar;
  1. 移除.bar原有的渐变背景样式,保留基础尺寸设置:
.bar {
    /* Size */
    width: 0%;
}

修改完成后,当进度达到15%时,进度条会完整显示渐变序列中15%位置的蓝色,符合预期效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 15:47:33