eduardweb.
Animații (Framer Motion)Începător#performance#tailwind-css#web-design#css-tricks

Gradient animat în Tailwind fără biblioteci externe: Trucul cu background-position

De Dan Ciobanu, 29 apr. 2026 · 3 vizualizări · 3 like-uri

Postat acum 1 zi
javascript
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      keyframes: {
        gradient: {
          '0%, 100%': { 'background-position': '0% 50%' },
          '50%': { 'background-position': '100% 50%' },
        },
      },
      animation: {
        gradient: 'gradient 8s ease infinite',
      },
    },
  },
}

// Utilizare in HTML/React
// <div class="bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 bg-[length:200%_200%] animate-gradient">
//   Conținutul tău aici
// </div>

Am văzut zeci de proiecte unde se instalează Framer Motion sau GSAP doar pentru un amărât de gradient care se mișcă pe fundalul unui buton sau în hero section. Mi se pare overkill. Mai ales când încerci să scoți un scor bun de Core Web Vitals și te bați pentru fiecare milisecundă la Time to Interactive.

Săptămâna trecută am refăcut un landing page unde clientul voia un „vibe modern”. Inițial, echipa folosise o librărie greoaie pentru animații. Am aruncat tot ce era inutil și am implementat un gradient infinit folosind doar utilitățile din Tailwind și câteva linii în config. Am economisit cam 35kb la bundle size (gzipped) și am scăpat de un layout shift enervant pe mobile.

De ce nu merge gradientul „din prima”?

Problema e simplă: browserul nu știe să animeze culorile dintr-un linear-gradient în mod direct. Dacă încerci să treci de la un gradient albastru la unul roșu prin transition-all, o să vezi un salt brusc, nu o tranziție fină. CSS-ul pur și simplu nu are (încă) implementată interpolarea culorilor pe imagini de fundal generate dinamic.

Soluția pe care o folosesc de ani de zile e să fac fundalul mult mai mare decât elementul (de vreo 200% sau 400%) și apoi să-i mișc poziția. Practic, te plimbi pe o „pânză” uriașă de culori.

Configurarea în Tailwind

Poți să scrii clase arbitrare, dar eu prefer să îmi pun animația în tailwind.config.js dacă o folosesc în mai mult de două locuri. E mult mai curat și echipa înțelege imediat ce se întâmplă acolo.

Aici definim keyframes pentru background-position. Secretul e să plecăm de la 0% 50%, să mergem la 100% 50% și să ne întoarcem. Asta creează acel efect de „loop” infinit fără să se vadă unde se termină animația.

Trade-off-uri și performanță

Mersul pe varianta asta e super rapid, dar are o mică hibă: background-position este procesat pe CPU, nu pe GPU (spre deosebire de transform: translate). Pe desktop nu vei simți nicio diferență. Totuși, dacă ai un element imens, cât tot ecranul, pe un telefon vechi de acum 6 ani, s-ar putea să vezi un mic „stutter”.

Pentru majoritatea butoanelor, cardurilor sau secțiunilor de tip hero, metoda asta e sfântă. E sigură, nu crapă dacă nu se încarcă vreun script și funcționează identic în Chrome, Safari sau Firefox. Dacă chiar vrei performanță extremă pentru ecrane 4K, poți anima un ::before cu transform, dar codul devine de trei ori mai lung.

La proiectul de care ziceam, cu vreo 8k useri activi simultan, n-am avut nicio plângere de lag. CSS-ul e de multe ori subestimat doar pentru că ne-am obișnuit să aruncăm cu pachete de npm în orice problemă mică.

Voi cum procedați când aveți de făcut chestii vizuale simple? Tot pe librării de JS mergeți sau mai „murdăriți” config-ul de Tailwind?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.