Animasi CSS yang Bikin Website Lo Terlihat Premium: 15 Efek Keren
Tutorial lengkap membuat animasi CSS yang smooth dan modern untuk website premium. Dari hover effects hingga loading animations yang bikin user terkesan.

✨ Animasi CSS yang Bikin Website Lo Terlihat Premium
Animasi CSS yang tepat bisa mengubah website biasa jadi terlihat premium dan profesional. Di tutorial ini, kita akan belajar 15 efek animasi CSS yang bikin user terkesan dan meningkatkan user experience secara signifikan.
“Animation is not the art of drawings that move but the art of movements that are drawn.” - Norman McLaren
🎯 Yang Akan Kita Pelajari
- ✨ Hover effects yang smooth dan menarik
- 🎭 Loading animations yang engaging
- 🌊 Scroll-triggered animations
- 🎨 Micro-interactions yang premium
- ⚡ Performance optimization tips
🚀 1. Premium Button Hover Effects
Glow Effect Button
.btn-glow {
position: relative;
padding: 12px 24px;
background: linear-gradient(45deg, #667eea, #764ba2);
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
overflow: hidden;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}
.btn-glow::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.3),
transparent
);
transition: left 0.5s ease;
}
.btn-glow:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.5);
}
.btn-glow:hover::before {
left: 100%;
}
Morphing Button
.btn-morph {
padding: 12px 24px;
background: #3b82f6;
color: white;
border: none;
border-radius: 25px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
}
.btn-morph::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
background: rgba(255, 255, 255, 0.1);
border-radius: 50%;
transform: translate(-50%, -50%);
transition: width 0.6s ease, height 0.6s ease;
}
.btn-morph:hover {
border-radius: 8px;
transform: scale(1.05);
}
.btn-morph:hover::before {
width: 300px;
height: 300px;
}
🎨 2. Card Hover Animations
3D Flip Card
.card-3d {
width: 300px;
height: 200px;
perspective: 1000px;
margin: 20px;
}
.card-inner {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.8s;
transform-style: preserve-3d;
}
.card-3d:hover .card-inner {
transform: rotateY(180deg);
}
.card-front, .card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}
.card-front {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.card-back {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
color: white;
transform: rotateY(180deg);
}
Floating Card Effect
.card-float {
background: white;
border-radius: 16px;
padding: 24px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
position: relative;
overflow: hidden;
}
.card-float::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.1), transparent);
transform: translateX(-100%);
transition: transform 0.6s ease;
}
.card-float:hover {
transform: translateY(-8px) scale(1.02);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
}
.card-float:hover::before {
transform: translateX(100%);
}
🌊 3. Loading Animations
Skeleton Loading
.skeleton {
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: loading 1.5s infinite;
}
@keyframes loading {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
.skeleton-text {
height: 16px;
border-radius: 4px;
margin-bottom: 8px;
}
.skeleton-text:last-child {
width: 60%;
}
.skeleton-avatar {
width: 60px;
height: 60px;
border-radius: 50%;
}
Pulse Loading
.pulse-loader {
display: inline-block;
width: 40px;
height: 40px;
background: #3b82f6;
border-radius: 50%;
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0% {
transform: scale(0);
opacity: 1;
}
100% {
transform: scale(1);
opacity: 0;
}
}
/* Multiple pulse dots */
.pulse-container {
display: flex;
gap: 8px;
}
.pulse-dot {
width: 12px;
height: 12px;
background: #3b82f6;
border-radius: 50%;
animation: pulse-dot 1.4s ease-in-out infinite both;
}
.pulse-dot:nth-child(1) { animation-delay: -0.32s; }
.pulse-dot:nth-child(2) { animation-delay: -0.16s; }
.pulse-dot:nth-child(3) { animation-delay: 0; }
@keyframes pulse-dot {
0%, 80%, 100% {
transform: scale(0);
}
40% {
transform: scale(1);
}
}
🎭 4. Text Animations
Typewriter Effect
.typewriter {
overflow: hidden;
border-right: 2px solid #3b82f6;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0.1em;
animation:
typing 3.5s steps(40, end),
blink-caret 0.75s step-end infinite;
}
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
@keyframes blink-caret {
from, to { border-color: transparent; }
50% { border-color: #3b82f6; }
}
Gradient Text Animation
.gradient-text {
background: linear-gradient(
45deg,
#667eea,
#764ba2,
#f093fb,
#f5576c,
#4facfe,
#00f2fe
);
background-size: 400% 400%;
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: gradient-shift 3s ease infinite;
font-size: 2rem;
font-weight: bold;
}
@keyframes gradient-shift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
🎯 5. Scroll-Triggered Animations
Fade In on Scroll
.fade-in {
opacity: 0;
transform: translateY(30px);
transition: all 0.6s ease;
}
.fade-in.visible {
opacity: 1;
transform: translateY(0);
}
/* Staggered animation */
.fade-in-stagger {
opacity: 0;
transform: translateY(30px);
transition: all 0.6s ease;
}
.fade-in-stagger:nth-child(1) { transition-delay: 0.1s; }
.fade-in-stagger:nth-child(2) { transition-delay: 0.2s; }
.fade-in-stagger:nth-child(3) { transition-delay: 0.3s; }
.fade-in-stagger:nth-child(4) { transition-delay: 0.4s; }
// JavaScript untuk trigger animation
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, observerOptions);
document.querySelectorAll('.fade-in').forEach(el => {
observer.observe(el);
});
Parallax Scroll Effect
.parallax-container {
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
perspective: 1px;
}
.parallax-element {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
transform: translateZ(-1px) scale(2);
}
.parallax-back {
transform: translateZ(-2px) scale(3);
}
.parallax-mid {
transform: translateZ(-1px) scale(2);
}
⚡ 6. Micro-Interactions
Interactive Icon Buttons
.icon-btn {
width: 50px;
height: 50px;
border: none;
border-radius: 50%;
background: #f8fafc;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.icon-btn::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
background: #3b82f6;
border-radius: 50%;
transform: translate(-50%, -50%);
transition: all 0.3s ease;
z-index: 0;
}
.icon-btn:hover::before {
width: 100%;
height: 100%;
}
.icon-btn:hover {
transform: scale(1.1);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.3);
}
.icon-btn svg {
position: relative;
z-index: 1;
transition: color 0.3s ease;
}
.icon-btn:hover svg {
color: white;
}
Progress Bar Animation
.progress-container {
width: 100%;
height: 8px;
background: #e5e7eb;
border-radius: 4px;
overflow: hidden;
position: relative;
}
.progress-bar {
height: 100%;
background: linear-gradient(90deg, #3b82f6, #8b5cf6);
border-radius: 4px;
position: relative;
transform: translateX(-100%);
animation: progress-fill 2s ease-out forwards;
}
.progress-bar::after {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.3),
transparent
);
animation: progress-shine 1.5s ease-in-out infinite;
}
@keyframes progress-fill {
to {
transform: translateX(0);
}
}
@keyframes progress-shine {
0% { transform: translateX(-100%); }
100% { transform: translateX(100%); }
}
🎨 7. Advanced Animations
Morphing Shapes
.morph-shape {
width: 100px;
height: 100px;
background: linear-gradient(45deg, #667eea, #764ba2);
border-radius: 50%;
animation: morph 4s ease-in-out infinite;
margin: 50px auto;
}
@keyframes morph {
0%, 100% {
border-radius: 50%;
transform: rotate(0deg);
}
25% {
border-radius: 25% 75% 75% 25%;
transform: rotate(90deg);
}
50% {
border-radius: 75% 25% 25% 75%;
transform: rotate(180deg);
}
75% {
border-radius: 25% 75% 25% 75%;
transform: rotate(270deg);
}
}
Floating Elements
.floating {
animation: floating 3s ease-in-out infinite;
}
.floating:nth-child(1) { animation-delay: 0s; }
.floating:nth-child(2) { animation-delay: 0.5s; }
.floating:nth-child(3) { animation-delay: 1s; }
@keyframes floating {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(-20px);
}
}
/* Floating with rotation */
.floating-rotate {
animation:
floating 3s ease-in-out infinite,
rotate 10s linear infinite;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
🎯 8. Navigation Animations
Animated Menu Toggle
.menu-toggle {
width: 30px;
height: 20px;
position: relative;
cursor: pointer;
}
.menu-line {
width: 100%;
height: 2px;
background: #333;
position: absolute;
transition: all 0.3s ease;
}
.menu-line:nth-child(1) { top: 0; }
.menu-line:nth-child(2) { top: 50%; transform: translateY(-50%); }
.menu-line:nth-child(3) { bottom: 0; }
.menu-toggle.active .menu-line:nth-child(1) {
transform: rotate(45deg);
top: 50%;
margin-top: -1px;
}
.menu-toggle.active .menu-line:nth-child(2) {
opacity: 0;
}
.menu-toggle.active .menu-line:nth-child(3) {
transform: rotate(-45deg);
bottom: 50%;
margin-bottom: -1px;
}
Slide-in Navigation
.nav-menu {
position: fixed;
top: 0;
right: -300px;
width: 300px;
height: 100vh;
background: white;
box-shadow: -5px 0 15px rgba(0, 0, 0, 0.1);
transition: right 0.3s ease;
z-index: 1000;
}
.nav-menu.active {
right: 0;
}
.nav-item {
padding: 20px;
border-bottom: 1px solid #eee;
transform: translateX(50px);
opacity: 0;
transition: all 0.3s ease;
}
.nav-menu.active .nav-item {
transform: translateX(0);
opacity: 1;
}
.nav-menu.active .nav-item:nth-child(1) { transition-delay: 0.1s; }
.nav-menu.active .nav-item:nth-child(2) { transition-delay: 0.2s; }
.nav-menu.active .nav-item:nth-child(3) { transition-delay: 0.3s; }
🌟 9. Image Hover Effects
Zoom and Overlay
.image-container {
position: relative;
overflow: hidden;
border-radius: 12px;
cursor: pointer;
}
.image-container img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s ease;
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(
45deg,
rgba(59, 130, 246, 0.8),
rgba(139, 92, 246, 0.8)
);
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.3s ease;
}
.image-container:hover img {
transform: scale(1.1);
}
.image-container:hover .image-overlay {
opacity: 1;
}
.overlay-text {
color: white;
font-size: 1.2rem;
font-weight: bold;
transform: translateY(20px);
transition: transform 0.3s ease 0.1s;
}
.image-container:hover .overlay-text {
transform: translateY(0);
}
Tilt Effect
.tilt-card {
perspective: 1000px;
transition: transform 0.1s ease;
}
.tilt-inner {
transform-style: preserve-3d;
transition: transform 0.1s ease;
}
/* JavaScript untuk tilt effect */
document.querySelectorAll('.tilt-card').forEach(card => {
card.addEventListener('mousemove', (e) => {
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const centerX = rect.width / 2;
const centerY = rect.height / 2;
const rotateX = (y - centerY) / 10;
const rotateY = (centerX - x) / 10;
card.querySelector('.tilt-inner').style.transform =
`rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
});
card.addEventListener('mouseleave', () => {
card.querySelector('.tilt-inner').style.transform =
'rotateX(0deg) rotateY(0deg)';
});
});
⚡ 10. Performance Optimization
Hardware Acceleration
/* Gunakan transform dan opacity untuk animasi yang smooth */
.optimized-animation {
will-change: transform, opacity;
transform: translateZ(0); /* Force hardware acceleration */
}
/* Avoid animating these properties */
.avoid {
/* ❌ Jangan animate ini */
/* width, height, padding, margin, border-width */
/* ✅ Animate ini instead */
transform: scale(1.1); /* Instead of width/height */
opacity: 0.8; /* Instead of visibility */
}
Reduce Motion for Accessibility
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
Animation Performance Tips
/* Use transform instead of changing layout properties */
.good-performance {
transform: translateX(100px); /* ✅ Good */
}
.bad-performance {
left: 100px; /* ❌ Causes layout recalculation */
}
/* Contain animations */
.animation-container {
contain: layout style paint;
}
/* Use will-change sparingly */
.will-change-element {
will-change: transform;
}
.will-change-element.animation-done {
will-change: auto; /* Remove after animation */
}
🎯 11. Complete Example: Premium Card
Mari gabungkan semua teknik dalam satu contoh lengkap:
<div class="premium-card">
<div class="card-image">
<img src="product.jpg" alt="Product">
<div class="card-overlay">
<button class="overlay-btn">View Details</button>
</div>
</div>
<div class="card-content">
<h3 class="card-title">Premium Product</h3>
<p class="card-description">Amazing product description here</p>
<div class="card-footer">
<span class="price">$99</span>
<button class="add-to-cart">Add to Cart</button>
</div>
</div>
</div>
.premium-card {
width: 320px;
background: white;
border-radius: 16px;
overflow: hidden;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
position: relative;
}
.premium-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, #667eea, #764ba2);
transform: scaleX(0);
transition: transform 0.3s ease;
}
.premium-card:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
}
.premium-card:hover::before {
transform: scaleX(1);
}
.card-image {
position: relative;
height: 200px;
overflow: hidden;
}
.card-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s ease;
}
.card-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.3s ease;
}
.overlay-btn {
padding: 12px 24px;
background: white;
color: #333;
border: none;
border-radius: 25px;
cursor: pointer;
transform: translateY(20px);
transition: transform 0.3s ease 0.1s;
}
.premium-card:hover .card-image img {
transform: scale(1.1);
}
.premium-card:hover .card-overlay {
opacity: 1;
}
.premium-card:hover .overlay-btn {
transform: translateY(0);
}
.card-content {
padding: 24px;
}
.card-title {
font-size: 1.25rem;
font-weight: bold;
margin-bottom: 8px;
color: #333;
}
.card-description {
color: #666;
margin-bottom: 16px;
line-height: 1.5;
}
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
}
.price {
font-size: 1.5rem;
font-weight: bold;
color: #3b82f6;
}
.add-to-cart {
padding: 8px 16px;
background: #3b82f6;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
}
.add-to-cart:hover {
background: #2563eb;
transform: scale(1.05);
}
🎯 12. JavaScript Integration
Intersection Observer untuk Scroll Animations
// Advanced scroll animation controller
class ScrollAnimationController {
constructor() {
this.elements = document.querySelectorAll('[data-animate]');
this.observer = null;
this.init();
}
init() {
this.observer = new IntersectionObserver(
this.handleIntersection.bind(this),
{
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
}
);
this.elements.forEach(el => {
this.observer.observe(el);
});
}
handleIntersection(entries) {
entries.forEach(entry => {
if (entry.isIntersecting) {
const element = entry.target;
const animationType = element.dataset.animate;
const delay = element.dataset.delay || 0;
setTimeout(() => {
this.animateElement(element, animationType);
}, delay);
this.observer.unobserve(element);
}
});
}
animateElement(element, type) {
switch (type) {
case 'fadeIn':
element.classList.add('animate-fade-in');
break;
case 'slideUp':
element.classList.add('animate-slide-up');
break;
case 'scaleIn':
element.classList.add('animate-scale-in');
break;
default:
element.classList.add('animate-default');
}
}
}
// Initialize
new ScrollAnimationController();
Mouse Follow Effect
class MouseFollower {
constructor() {
this.cursor = document.createElement('div');
this.cursor.className = 'custom-cursor';
document.body.appendChild(this.cursor);
this.init();
}
init() {
document.addEventListener('mousemove', this.updatePosition.bind(this));
document.addEventListener('mouseenter', this.show.bind(this));
document.addEventListener('mouseleave', this.hide.bind(this));
// Add hover effects for interactive elements
document.querySelectorAll('a, button, [data-cursor="pointer"]')
.forEach(el => {
el.addEventListener('mouseenter', () => this.cursor.classList.add('hover'));
el.addEventListener('mouseleave', () => this.cursor.classList.remove('hover'));
});
}
updatePosition(e) {
this.cursor.style.left = e.clientX + 'px';
this.cursor.style.top = e.clientY + 'px';
}
show() {
this.cursor.style.opacity = '1';
}
hide() {
this.cursor.style.opacity = '0';
}
}
// CSS for custom cursor
const cursorStyles = `
.custom-cursor {
position: fixed;
width: 20px;
height: 20px;
background: rgba(59, 130, 246, 0.5);
border-radius: 50%;
pointer-events: none;
z-index: 9999;
transition: transform 0.1s ease, opacity 0.2s ease;
transform: translate(-50%, -50%);
}
.custom-cursor.hover {
transform: translate(-50%, -50%) scale(1.5);
background: rgba(59, 130, 246, 0.8);
}
`;
// Add styles to head
const styleSheet = document.createElement('style');
styleSheet.textContent = cursorStyles;
document.head.appendChild(styleSheet);
// Initialize
new MouseFollower();
🎯 13. Best Practices
Do’s and Don’ts
/* ✅ DO: Use transform and opacity */
.good-animation {
transform: translateX(100px) scale(1.1);
opacity: 0.8;
transition: transform 0.3s ease, opacity 0.3s ease;
}
/* ❌ DON'T: Animate layout properties */
.bad-animation {
width: 200px; /* Causes layout recalculation */
margin-left: 100px; /* Avoid animating margin */
padding: 20px; /* Avoid animating padding */
}
/* ✅ DO: Group animations */
.efficient-animation {
animation: fadeInSlideUp 0.5s ease forwards;
}
@keyframes fadeInSlideUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* ✅ DO: Use CSS Variables for dynamic animations */
:root {
--animation-speed: 0.3s;
--animation-easing: cubic-bezier(0.4, 0, 0.2, 1);
}
.dynamic-animation {
transition: all var(--animation-speed) var(--animation-easing);
}
Performance Tips
- Batching Changes
// ❌ Bad: Multiple style changes
element.style.transform = 'translateX(100px)';
element.style.opacity = '0.8';
element.style.backgroundColor = 'blue';
// ✅ Good: Use CSS classes
element.classList.add('animated-state');
- RequestAnimationFrame
function smoothScroll(target, duration) {
const start = window.pageYOffset;
const distance = target - start;
let startTime = null;
function animation(currentTime) {
if (startTime === null) startTime = currentTime;
const timeElapsed = currentTime - startTime;
const progress = Math.min(timeElapsed / duration, 1);
window.scrollTo(0, start + distance * easeInOutCubic(progress));
if (timeElapsed < duration) {
requestAnimationFrame(animation);
}
}
requestAnimationFrame(animation);
}
- Debouncing Animations
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
const debouncedAnimation = debounce(() => {
element.classList.add('animated');
}, 150);
🎯 Kesimpulan
Animasi CSS yang baik bukan hanya tentang membuat sesuatu bergerak, tapi juga tentang:
-
✨ User Experience
- Animasi harus memiliki tujuan
- Tidak mengganggu interaksi user
- Memberikan feedback visual yang jelas
-
🚀 Performance
- Gunakan properties yang optimal (transform & opacity)
- Hindari animasi yang memicu layout recalculation
- Manfaatkan hardware acceleration
-
🎨 Design
- Konsisten dengan brand identity
- Smooth dan natural
- Tidak berlebihan
-
♿ Accessibility
- Sediakan opsi reduce motion
- Pastikan kontras yang cukup
- Tidak memicu vestibular disorders
🔗 Resources & Tools
-
Tools
- Animista - CSS Animation Generator
- Cubic Bezier - Custom Easing Function
- Keyframes.app - Visual Animation Creator
-
Libraries
- GSAP - Professional Animation Library
- Motion One - Web Animations API Wrapper
- Framer Motion - React Animation Library
-
Learning Resources
🎯 Next Steps
Setelah menguasai dasar-dasar animasi CSS, kamu bisa explore:
-
Advanced Animation Techniques
- 3D Transforms
- SVG Animations
- Web Animation API
-
Animation Libraries
- GSAP
- Anime.js
- Lottie
-
Performance Optimization
- Animation Profiling
- Frame Rate Optimization
- Memory Management
-
Cross-browser Compatibility
- Vendor Prefixes
- Fallback Animations
- Browser Support Testing
🔗 Artikel Terkait
- Membuat Dark Mode dengan CSS Variables dan JavaScript
- Tips Optimasi Website Loading Cepat
- Deploy Website Gratis: Vercel vs Netlify vs GitHub Pages
Ditulis dengan ❤️ oleh Hilal Technologic