ساخت افکت سایه متحرک با CSS
افکتهای سایه متحرک یکی از راههای ساده و چشمگیر برای افزایش جذابیت رابط کاربری هستند. در این مقاله به صورت عملی و فنی روشهای مختلف ساخت سایههای متحرک با CSS را بررسی میکنیم، مزایا و معایب هر روش را میگوییم و نمونههای قابل استفاده در پروژههای واقعی را نشان میدهیم.
چرا سایه متحرک مهم است؟
سایههای متحرک میتوانند عمق، جهت نور و حس تعامل با المانها را منتقل کنند. از آنها در دکمهها، کارتها، منوها و المانهای شناور استفاده میشود تا تجربه کاربری روانتر و مدرنتری ایجاد شود.
روشها و دستورالعمل کلی
- استفاده از box-shadow برای سایههای ساده.
- استفاده از filter: drop-shadow() در مواردی که میخواهیم سایه بر اساس شکل شفاف تصویر باشد.
- استفاده از یک pseudo-element (::before یا ::after) برای سایههایی با محو شدگی پیشرفته یا افکتهای چندلایه.
- استفاده از @keyframes یا transition برای انیمیشن.
- رعایت دسترسپذیری با media query مثل
prefers-reduced-motion.
مثال 1 — سایه ساده با transition
/* HTML:
<div class="card">Card</div>
*/ /* CSS */ .card { width: 200px; height: 120px; background: #fff; border-radius: 12px; box-shadow: 0 6px 18px rgba(0,0,0,0.12); transition: box-shadow 250ms ease, transform 250ms ease; } .card:hover { transform: translateY(-6px); box-shadow: 0 20px 40px rgba(0,0,0,0.18); }
در این کد یک card ساده تعریف شده که هنگام هاور سایه بزرگتر و کارت کمی بالا میآید. از transition برای هموار کردن تغییرات استفاده شده است. این روش مناسب دکمهها و کارتهای ساده است و سبک است، اما برای افکتهای پیچیدهتر باید از keyframes یا pseudo-element استفاده کنیم.
مثال 2 — سایه متحرک طبیعی با keyframes
/* HTML:
<div class="float">Hover me</div>
*/ /* CSS */ .float { display: inline-block; padding: 20px 30px; background: linear-gradient(180deg,#fff,#f7f7f7); border-radius: 14px; box-shadow: 0 10px 30px rgba(0,0,0,0.12); animation: float 3s ease-in-out infinite; } @keyframes float { 0% { transform: translateY(0); box-shadow: 0 10px 30px rgba(0,0,0,0.12); } 50% { transform: translateY(-12px); box-shadow: 0 26px 60px rgba(0,0,0,0.16); } 100% { transform: translateY(0); box-shadow: 0 10px 30px rgba(0,0,0,0.12); } }
در این مثال از @keyframes استفاده شده تا یک حرکت نوسانی همراه با تغییر سایه شبیه به شناور شدن ایجاد شود. دقت کنید تغییر همزمان transform و box-shadow کمک میکند حرکت طبیعیتر دیده شود.
مثال 3 — سایه نرم و گسترده با pseudo-element
/* HTML:
<div class="soft-card">Content</div>
*/ /* CSS */ .soft-card { position: relative; padding: 24px; background: #fff; border-radius: 12px; z-index: 1; } .soft-card::before { content: ""; position: absolute; inset: 8px; /* فاصله از لبهها */ background: rgba(0,0,0,0.08); filter: blur(18px); border-radius: 14px; z-index: -1; transition: transform 300ms ease, opacity 300ms ease; } .soft-card:hover::before { transform: translateY(8px) scale(1.02); opacity: 0.95; }
ایجاد سایه با pseudo-element امکان کنترل بهتر محو شدگی (با filter: blur()) و لایهبندی را میدهد. این روش پردازشِ بهتری برای سایههای بسیار نرم و چندلایه فراهم میکند و میتوان به آسانی با transition آن را متحرک کرد.
حرکت نور با CSS variables (ترکیب با حداقل JS)
برای ساخت سایهای که با حرکت ماوس جهت نور را شبیهسازی میکند، معمولاً باید متغیرهای CSS را با JS بهروز کنید. این کار کاربر را در تعامل زندهتری قرار میدهد.
/* HTML:
<div class="spot">Light</div>
*/ /* CSS */ :root { --x: 0; --y: 0; } .spot { width: 180px; height: 100px; background: #fff; border-radius: 12px; transition: box-shadow 120ms linear; box-shadow: calc(var(--x) * 1px) calc(var(--y) * 1px) 30px rgba(0,0,0,0.2); } /* JS (example to update variables) document.addEventListener('mousemove', e => { const el = document.querySelector('.spot'); const rect = el.getBoundingClientRect(); const x = (e.clientX - (rect.left + rect.width/2)) / 10; const y = (e.clientY - (rect.top + rect.height/2)) / 10; el.style.setProperty('--x', x); el.style.setProperty('--y', y); });
در این مثال با جاوااسکریپت مختصات ماوس نسبت به مرکز المان محاسبه و در متغیرهای CSS ذخیره میشود، سپس مقدار سایه به صورت داینامیک تغییر میکند. نکته مهم: برای حفظ عملکرد، این بهروزرسانیها باید با استفاده از requestAnimationFrame بهینه شوند تا فشار روی رندر کاهش یابد.
ملاحظات عملکرد و دسترسپذیری
- box-shadow میتواند در برخی مرورگرها سنگین باشد؛ اگر عملکرد مهم است، از
transformوopacityبرای انیمیشنهای اصلی استفاده کنید و سایه را کمدرجه نگه دارید. - برای کاربران با حساسیت به حرکت، حتماً
@media (prefers-reduced-motion: reduce)را پشتیبانی کنید و انیمیشنها را کاهش دهید یا غیرفعال کنید. - از
will-change: transformیاwill-change: box-shadowفقط زمانی استفاده کنید که لازم است و به اندازهٔ کوتاهی اعمال کنید؛ استفادهٔ نادرست میتواند حافظه را افزایش دهد.
جدول مقایسه روشها
| روش | مزایا | معایب |
|---|---|---|
| box-shadow | ساده، قابل ترکیب با transition | ممکن است در رندر سنگین باشد، شکل ساده |
| filter: drop-shadow() | برای تصاویر و SVG مناسب، سایه وفقپذیر با شکل | کنترل کمتر روی لایهها نسبت به pseudo-element |
| pseudo-element + blur | سایههای نرم و چندلایه، کنترل کامل | کمی پیچیدهتر در ساخت |
نکات پیشرفته و بهترین تمرینها
- ترکیب transform و box-shadow حرکت طبیعیتری ایجاد میکند.
- برای افکتهای طولانی یا چرخهای،
cubic-bezierمناسب انتخاب کنید تا حالت طبیعیتر شود. - حتماً روی موبایل تست کنید؛ اندازه و شدت سایه باید با صفحههای کوچک هم سازگار باشد.
- در پروژههای تولیدی، انیمیشنها را با تست عملکرد (Performance Profiler) بررسی کنید تا افت فریم نداشته باشید.
نتیجهگیری
ساخت افکت سایه متحرک با CSS ترکیبی از هنر و علم است: انتخاب روش مناسب بر اساس نیازهای طراحی، توجه به عملکرد و رعایت دسترسپذیری باعث میشود افکتها هم زیبا و هم قابل استفاده باشند. با روشهای بالا میتوانید از سادهترین تا واقعگرایانهترین سایهها را بسازید و آنها را با انیمیشنها ترکیب کنید تا رابطی حرفهایتر ایجاد شود.
آیا این مطلب برای شما مفید بود ؟




