Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

158
Views
Appending styling in reactjs whilst using tailwind

I want to animate an element when the user clicks on a button. The element displays a count of how many times the button has been clicked. This is managed through a state that is incremented on every button click.

Whenever the button is clicked, the displayed number should bounce/animate, to emphasize its change.

In essence I want to conditionally append a CSS class. There's many examples of how to do this, but almost all of them only have a single class applied to them, not lots of classes.

I use tailwindcss for styling. This means lots of CSS classes on lots of elements.

What I have considered

String concatenation

Having a classNames array, where the animation class can be added and removed easily.

const [count, setCount] = useState(0);
const [classNames, setClassNames] = useState([
    'text-2xl', 'mb-2', 'font-bold', 'text-black', 'dark:text-white'
]);

const countElement = <p className={classNames.join(' ')}>{count}</p>;

const handleClick = () => {
    
    setCount(count + 1);
    
    // Append the animation class.
    setClassNames(classNames.concat('animate-bounce'));

    // Remove the animation class after the animation is done.
    setTimeout(() => {
        setClassNames(classNames.filter(className => 
            className !== 'animate-bounce'));
    }, 1000);
};

return <>
    {count > 0 ? countElement : null}
    <button className="px-4 py-3 mb-2 rounded-lg font-semibold transition-colors duration-300
                       bg-cardinal-default hover:bg-cardinal-dark active:bg-cardinal-darkest
                       text-black dark:text-white" 
                       onClick={handleClick}>Click me</button>
</>;

Though with tailwindcss this is kind of ugly as it separates all of the styling from its actual element. Not exactly ideal. It feels very hacky.

Animate an inner element

    const [isBouncing, setIsBouncing] = useState(false);

    const countElement = (
        <p className="text-2xl mb-2 font-bold text-black dark:text-white">
            <span className={isBouncing ? 'inline-block animate-spin' : ''}>{count}</span>
        </p>
    );

    ...
    
        setCount(count + 1);
        setIsBouncing(true);

        setTimeout(() => setIsBouncing(false), 1000);
    
    ... 
    

This is better, yet it still requires me to set inline-block

Is there a better way of doing this? Or have I exhausted all worthwhile solutions?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

You could use a css-in-js solution like styled-components which will make it really easy to enable/disable styles.

For tailwind there is a library to help with css-in-js called twin

This allows you to conditionally enable styles:

const Button = styled.button`
  ${tw`your tailwind styles here`}
  ${props => props.shouldAnimate ? `some animation css here` : "" }
`
about 4 years ago · Juan Pablo Isaza Report

0

TailwindCSS is a utility first CSS Framework, so there's probably no other option other than appending classes to your elements.

If you were to use an animation library, like Framer Motion, it wouldn't be necessary to append Tailwind classes. On the other hand, you would need to create the animation yourself, which is quite easy.

Regarding your considerations, the first alternative seems indeed very hacky, whereas the second one doesn't and should work as well.

Nonetheless, it's up to you to decide which method suits you best.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!