Skip to content

Allt om WordPress, webbutveckling — och mer därtill

🔄 Objektanimering vid skrollning: steg-för-steg-guide

🔄 Objektanimering vid skrollning: steg-för-steg-guide

Du landar på en sajt, scrollar sidan, och logotypen i hörnet roterar mjukt och reagerar på varje rörelse med scrollhjulet. Det ser levande och tekniskt kunnigt ut, och ger den där speciella touchen som folk lägger märke till.

Att skapa den här rotationen är enklare än det verkar. Du behöver inga tunga bibliotek eller megabyte av animeringsramverk. Allt du behöver är en div, några rader CSS och bokstavligen ett block JavaScript.

Här följer en steg-för-steg-genomgång: från att förbereda bilden till att anpassa för mobila skärmar. Koden är testad, fungerande och har inga beroenden.

💡 Snabb översikt:

  • Förbered ett SVG- eller PNG-objekt och infoga det i HTML
  • Fixera positionen med position: fixed och sätt avstånd med viewport-enheter
  • Lägg till en JavaScript scroll-hanterare som roterar objektet med transform: rotate()
  • Justera rotationshastigheten genom att dividera window.scrollY med en koefficient
  • För mobil, lägg till en media query med ny positionering och övergångstid

1. Förbereda objektet

Objektet kan vara vad som helst: en ikon, logotyp, vektorform, pilsymbol. Jag rekommenderar SVG, det tappar inte skärpa vid transformationer och väger nästan ingenting. Om transparens är avgörande och du inte har en vektor, fungerar PNG.

Placera bilden inuti en container-div och lägg den i body, helst nära toppen. En separat div förenklar hanteringen: senare kan du lägga till angränsande element eller byta ut bilden utan att röra positioneringslogiken.

1<div id="scrollContainer">
2 <img src="img/scrollObject.svg" alt="scrollObject" id="scrollObject">
3</div>

Du kan ha flera objekt, ge bara varje ett unikt id och duplicera JS-logiken med bindning till sitt eget element. Men just nu bygger vi en fungerande instans.

2. Positionering med CSS

Var ska objektet placeras? Beror på målet:

  • Nedre högra hörnet, en miniatyrikon som inte stör innehållet. Klassiskt för bloggar och portföljer.
  • Övre vänstra hörnet, indikator för scrollposition (framstegshjul).
  • Mitten av nedre kanten, stort dekorativt element som drar uppmärksamhet till sidfoten.

Låt oss titta på scenariot med nedre högra hörnet, det är universellt och täcker inte navigationen. I CSS, skriv:

1#scrollObject {
2 position: fixed;
3 right: 3vw;
4 bottom: 3vh;
5 top: auto;
6 width: 7vh;
7 height: auto;
8 transition: 0.1s ease-out;
9}

Nyckeln är position: fixed. Detta fixerar elementet relativt webbläsarfönstret, inte dokumentet. Vid scrollning rör sig innehållet men objektet stannar på plats. Enheterna vw och vh (procentandelar av viewportens bredd och höjd) justerar automatiskt avstånden för alla skärmar, från smartphone till 4K-skärm.

Egenskapen transition: 0.1s ease-out mjukar upp ryck vid positionsändring. För rotation är dess roll sekundär, men vid storleksändring eller media query-ändringar ser övergången renare ut.

3. Rotationsanimering med JavaScript

CSS kan göra enkla @keyframes, men vår uppgift är att knyta rotationsvinkeln till scrollpositionen. Det är här JavaScript kommer in. Minimal fungerande kod:

1const scrollObject = document.getElementById("scrollObject");
2
3window.addEventListener("scroll", () => {
4 scrollObject.style.transform = `rotate(${window.scrollY}deg)`;
5});

Vad som händer här: window.scrollY returnerar antalet pixlar sidan har scrollats vertikalt. Detta nummer infogas i CSS-funktionen rotate(), en pixels scrollning motsvarar en grads rotation.

Om objektet roterar för snabbt, dividera värdet med en koefficient:

1const speedFactor = window.scrollY / 2;
2const scrollObject = document.getElementById("scrollObject");
3
4window.addEventListener("scroll", () => {
5 scrollObject.style.transform = `rotate(${speedFactor}deg)`;
6});

Välj en divisor som passar din sidlängd. Ett värde på /2 halverar rotationen, /4 gör den mjuk och knappt märkbar. För långa landningssidor använd /6 eller /8 så att objektet inte gör tio fulla varv halvvägs ner på sidan.

Prestandanotering

Händelsen scroll avfyras dussintals gånger per sekund. På en enkel sajt med en transform är detta omärkligt, men om du har flera animerade objekt eller tung DOM, linda in logiken i requestAnimationFrame:

1const scrollObject = document.getElementById("scrollObject");
2let ticking = false;
3
4window.addEventListener("scroll", () => {
5 if (!ticking) {
6 requestAnimationFrame(() => {
7 scrollObject.style.transform = `rotate(${window.scrollY}deg)`;
8 ticking = false;
9 });
10 ticking = true;
11 }
12});

requestAnimationFrame grupperar anrop i webbläsarens synkroniseringsramar (vanligtvis 60 fps) och kör inte stilomberäkning vid varje scroll-händelse, vilket sparar CPU och batteri på mobilen.

Lägg också till will-change: transform i CSS-regeln för #scrollObject. Detta talar om för webbläsaren att allokera ett GPU-kompositeringslager i förväg, och rotationen kommer att vara hårdvaruaccelererad:

1#scrollObject {
2 /* ... other properties ... */
3 will-change: transform;
4}

4. Mobilanpassning

På skärmar mindre än 600 pixlar kan nedre högra hörnet krocka med burgarmeny eller "till toppen"-knappar. En vettig lösning är att flytta objektet till nedre mitten så att det inte täcker interaktiva element:

1@media only screen and (max-width: 600px) {
2 #scrollObject {
3 transition: 0.2s ease-out;
4 margin-left: -4vh;
5 width: 8vh;
6 height: auto;
7 top: 10px;
8 left: 50%;
9 }
10}

Objektet flyttas till skärmens överkant, centrerat med left: 50% och negativ margin-left, en klassisk teknik för horisontell centrering. Bredden ökas något (8vh istället för 7vh) för att kompensera för kortare visningsavstånd.

Notera transition: 0.2s ease-out i media queryn. Vid växling från desktop till mobil (eller vid fönsterstorleksändring) "hoppar" inte objektet direkt utan skiftar mjukt till den nya positionen under 0,2 sekunder.

Skrollikon på mobil smarttelefonskärm

Om du arbetar i Vue eller React, extrahera scrollobjektet till en separat komponent. Du kan fästa den i roten App.vue eller i layout så att animationen finns på alla sidor samtidigt, utan kodduplicering.

Skrollobjektanimationsresultat efter anpassning

Modernt alternativ: CSS-scrolldrivna animationer

Under 2024-2025 fick Chromium-webbläsare (Chrome, Edge, Opera) inbyggt stöd för animation-timeline: scroll(), scroll-länkade animationer utan en enda rad JavaScript. Det ser ut så här:

1@keyframes rotate {
2 to { transform: rotate(360deg); }
3}
4
5#scrollObject {
6 animation: rotate linear;
7 animation-timeline: scroll();
8}

Fördel: noll JavaScript, nackdel: endast i Chromium för närvarande (Firefox och Safari implementerar). För progressiv förbättring kan du kombinera: ge CSS-versionen till moderna webbläsare och behåll JS-hanteraren som en fallback för resten. Detaljer på MDN.

⁉️🤔 Vanliga frågor

Kan jag animera inte bara rotation, utan även skala eller opacitet?

Ja. transform stöder flera funktioner samtidigt. För att få ett objekt att rotera och krympa vid scrollning: scrollObject.style.transform = \rotate(${window.scrollY}deg) scale(${1 - window.scrollY / 5000});. Opacitet hanteras separat från transform med opacity. Kombinera upp till fem eller sex parametrar, men testa, flera transformationer på svaga enheter kan orsaka mikrohack. En eller två parametrar plus will-change: transform är ett säkert tak för 60 fps.

Vilket är bäst: SVG eller PNG för animering?

SVG, utan tvekan. Det skalas utan att tappa skärpa vid vilken rotation och skärmupplösning som helst, väger mindre, och webbläsaren renderar det som vektor (inga pixeltrappor på kanter efter rotate). Ta PNG endast om du redan har färdig rastergrafik och inte har tid att göra om den. Undvik JPEG för roterande objekt, komprimeringsartefakter blir mer märkbara efter rotation.

Hur får jag animationen att starta först när objektet är i det synliga området?

Använd IntersectionObserver. Istället för att binda till global scroll, spårar du om objektet har kommit in i viewporten och aktiverar först då rotation. Detta sparar resurser när elementet är utanför skärmen. Grundmall: skapa en observer med threshold: 0, i callbacken lägg till/ta bort en .active-klass, och bind JS-scrollhanteraren till närvaron av denna klass.

Varför hackar animationen på min sajt?

Tre typiska orsaker. Första: ingen will-change: transform, webbläsaren lämnar inte över elementet till GPU-kompositering och räknar om layout vid varje bildruta. Andra: egenskaper som orsakar reflow (såsom width, height, margin eller padding) appliceras på elementet inuti samma scroll-hanterare. Ersätt dem med transform: scale() och transform: translate(). Tredje: scroll-callbacken körs utan requestAnimationFrame och skapar extra ommålningar mellan bildrutor. Linda in logiken i rAF-mönstret (exempel i avsnittet "Prestandanotering").

Krävs JavaScript? Det finns rena CSS-lösningar.

CSS @keyframes är knutna till tid, inte scrollposition. Ja, animation-timeline: scroll() förändrar spelet, men webbläsarstödet är fortfarande ofullständigt (se avsnitt 4). Från och med mitten av 2026 är JavaScript-lösningen med scrollY + transform fortfarande det mest pålitliga sättet över webbläsare att knyta rotation till scrollning. Hela koden ryms på 5 rader, drar inga beroenden och fungerar från Internet Explorer 10 till färska Chrome.

Bör du lägga till scrollanimering på din sajt?

Att rotera ett objekt vid scrollning är inte bara ett "coolt trick". Det är en mikrointeraktion som ger besökaren taktil återkoppling: "Jag rör sidan och något händer". Rätt konfigurerad irriterar eller distraherar den inte, utan ger sajten personlighet.

Om sajten är minimalistisk, begränsa dig till ett litet objekt i hörnet och en koefficient på /4 eller /6. För landningssidor och portföljer kan du leka djärvare: ett stort centralt element med /2, kombinerad rotations- och skalanimering, bildbyte när en viss scrollY nås.

Huvudregel: scrollanimering ska komplettera innehåll, inte konkurrera med det om uppmärksamhet. Ett objekt, mjuk rörelse, ingen påträngandehet, så kommer din sajt att bli ihågkommen.