Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

159
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda