Kortversionen
- En CSS gradient hover-effekt kan inte göras genom att låta background-image övergå, eftersom webbläsare byter gradient direkt i stället för att interpolera dem.
- Den mest kompatibla tekniken är en överdimensionerad gradient med en transition på background-position, som glider in nya färger.
- Att registrera färgstopp eller vinklar med @property låter webbläsaren övergå mjukt mellan dem, och fungerar i alla aktuella stora webbläsare.
- Att tona opaciteten på en andra gradient i ett pseudoelement är den billigaste tekniken att rendera, eftersom opacitetsändringar inte målar om.
- Hover-effekter bör ligga inuti en hover-mediafråga och respektera prefers-reduced-motion.
På den här sidan
En CSS gradient hover-effekt kräver en omväg, eftersom webbläsare inte låter background-image övergå: ändra gradienten i :hover så hoppar den. Fyra tekniker ger ett mjukt resultat. Glid en överdimensionerad gradient med background-position, animera registrerade färgstopp med @property, korstona en andra gradient på ett pseudoelement, eller flytta ett radiellt sken med markören. Var och en passar olika element, och alla finns nedan med kod.
Varför transition inte fungerar på gradienter
För webbläsaren är en gradient en bild. Den kan interpolera ett tal eller en färg, men inte en bild till en annan, så background-image interpoleras inte och den nya gradienten ersätter den gamla direkt. Anpassade egenskaper som används i gradienten beter sig likadant om du inte registrerar dem, eftersom en oregistrerad egenskap bara är text.
/* This snaps, with no easing */
.btn {
background-image: linear-gradient(135deg, #1e1b4b, #6d28d9);
transition: background-image 400ms ease;
}
.btn:hover {
background-image: linear-gradient(135deg, #6d28d9, #f472b6);
}Teknik 1: glid en överdimensionerad gradient
Gör bakgrunden större än elementet och måla in båda lägena i den, och flytta den sedan. background-position kan övergå, så de nya färgerna glider in. Det fungerar i alla webbläsare och kräver ingen registrering.
.btn {
background-image: linear-gradient(90deg, #1e1b4b 0%, #6d28d9 50%, #f472b6 100%);
background-size: 200% 100%;
background-position: 0% 50%;
transition: background-position 500ms ease;
}
.btn:hover {
background-position: 100% 50%;
}linear-gradient(90deg, #1e1b4b 0%, #6d28d9 50%, #f472b6 100%)Rörelsen läses som en svepning, vilket passar knappar och länkar. Den är mindre övertygande på stora kort, där du ser gradienten färdas. Att animera background-position målar om, vilket är okej för små element; för en stor yta använder du teknik 3. Gradientknappar i CSS har fler knappmönster byggda på detta.
Teknik 2: animera färgstopp med @property
Registrera stoppfärgerna som typade anpassade egenskaper så kan webbläsaren interpolera dem. Gradienten byter då färg på plats, utan att glida. @property fungerar i alla aktuella stora webbläsare; äldre hoppar helt enkelt, vilket är en acceptabel reservlösning för en hover. Registreringsreglerna går vi igenom i CSS @property.
@property --stop-a {
syntax: "<color>";
inherits: false;
initial-value: #1e1b4b;
}
@property --stop-b {
syntax: "<color>";
inherits: false;
initial-value: #6d28d9;
}
.card {
background-image: linear-gradient(135deg, var(--stop-a), var(--stop-b));
transition: --stop-a 450ms ease, --stop-b 450ms ease;
}
.card:hover {
--stop-a: #6d28d9;
--stop-b: #f472b6;
}Samma trick animerar vinkeln. Registrera --angle med syntax: "<angle>", använd den i linear-gradient(var(--angle), ...) och ändra den vid hover: en gradient som vrids från 135 till 225 grader när pekaren kommer är en subtil, välgjord detalj för kort och gradientramar.
Båda teknikerna hittills fungerar också på gradienttext. Text som klipps med background-clip: text visar vad bakgrunden än gör, så en glidning eller en stopptransition på en rubrik får färgen att löpa genom bokstäverna vid hover. Håll ändringen lugn på rubriker som folk behöver läsa, och se till att båda lägena klarar kontrasten mot sidan.
Teknik 3: korstona två gradienter
Lägg hover-gradienten på ett pseudoelement ovanför basen och tona dess opacitet. Opacitetsändringar hanteras av kompositören utan omritning, så detta är det mjukaste valet för stora kort, hjältepaneler och allt i ett långt rutnät.
.tile {
position: relative;
isolation: isolate;
background-image: linear-gradient(135deg, #1e1b4b, #6d28d9);
}
.tile::before {
content: "";
position: absolute;
inset: 0;
z-index: -1;
border-radius: inherit;
background-image: linear-gradient(135deg, #6d28d9, #f472b6);
opacity: 0;
transition: opacity 400ms ease;
}
.tile:hover::before {
opacity: 1;
}z-index: -1 med isolation: isolate håller pseudoelementet bakom brickans text men ovanför dess basgradient.Teknik 4: ett sken som följer markören
En radiell gradient som positioneras med anpassade egenskaper kan följa pekaren. Sätt --x och --y från ett litet skript så rör sig ljuset med handen. Håll det mjukt och håll det borta från text: det ska kännas som ljus på en yta, aldrig en gloria kring ord.
.panel {
background-image:
radial-gradient(circle 220px at var(--x, 50%) var(--y, 50%), rgb(244 114 182 / 0.35), transparent 70%),
linear-gradient(135deg, #1e1b4b, #312e81);
}
/* JavaScript:
panel.addEventListener("pointermove", (e) => {
const r = panel.getBoundingClientRect();
panel.style.setProperty("--x", `${e.clientX - r.left}px`);
panel.style.setProperty("--y", `${e.clientY - r.top}px`);
});
*/Välj en teknik
Ser ut som
Renderingskostnad
Bäst för
Ser ut som
Renderingskostnad
Bäst för
Ser ut som
Renderingskostnad
Bäst för
Renderingskostnad
Bäst för
För gradienter som rör sig av sig själva i stället för vid hover, se animerade CSS-gradienter. För den större bilden av vad som kostar målningstid, se CSS gradient prestanda.
Pekskärmar och reducerad rörelse
Undvik
- Hover-stilar som sitter kvar efter ett tryck på mobiler
- Information som bara visas vid hover
- Långa, loopande hover-animationer
- Att ignorera inställningen för reducerad rörelse
Gör
- Linda in hover-regler i
@media (hover: hover) - Visa samma läge på
:activeför touch - Håll övergångarna mellan 200 och 500 ms
- Ta bort rörelse under
prefers-reduced-motion, behåll färgändringen
@media (hover: hover) {
.btn:hover { background-position: 100% 50%; }
}
@media (prefers-reduced-motion: reduce) {
.btn { transition: none; }
}Hover-effekter får en webbplats att leva. På sociala inlägg finns ingen pekare, så rörelsen måste ligga i själva designen. Gradiently-Marks kan bära sin egen milda rörelse, och med Pro exporteras en design som MP4, WebM eller GIF där webbläsaren stöder inspelning, redo för en story eller ett inlägg.
Vanliga frågor
Kan man låta en CSS-gradient övergå vid hover?
Inte direkt. background-image ändras omedelbart. Låt background-position övergå på en överdimensionerad gradient, animera registrerade stopp med @property, eller tona opaciteten på en andra gradient.
Hur får jag en gradientknapp att byta färg mjukt vid hover?
Använd background-size: 200% 100% med en gradient på tre stopp, och låt sedan background-position övergå från 0% 50% till 100% 50% vid hover.
Fungerar @property i alla webbläsare?
Det fungerar i aktuella versioner av Chrome, Edge, Safari och Firefox. Äldre webbläsare hoppar mellan lägena i stället för att mjukt övergå.
Vilken gradient hover-effekt är mest prestandaeffektiv?
En opacitetskorstoning: hover-gradienten ligger på ett pseudoelement och bara dess opacitet ändras, vilket undviker omritning.
Bör gradient hover-effekter respektera reducerad rörelse?
Ja. Under prefers-reduced-motion: reduce tar du bort rörelsen och behåller en enkel färgändring.
Skriven av Gradiently
Teamet bakom Gradiently, ett designverktyg byggt kring Marks: levande gradienter som får allt du gör att kännas som ditt.
Se vår profil