ایجاد افکت موج آب با CSS
افکت موج آب یکی از جلوههای بصری محبوب در طراحی وب است که هم برای هدرها و بنرها مناسب است و هم برای پسزمینه بخشهای تعاملی. در این مقاله به چند روش عملی — از CSS خالص تا ترکیب SVG و CSS — میپردازیم، نکات عملکردی و دسترسی را بررسی میکنیم و نمونهکدهای قابل استفاده ارائه میدهیم.
مفاهیم کلیدی و تکنیکها
- ایجاد حرکت با keyframes و تراکنشهای CSS (transform, translateX/translateY).
- استفاده از SVG برای مسیر موج دقیق و قابل اسکیل.
- لایهبندی چند موج با سرعتهای مختلف برای ایجاد پارالاکس.
- بهینهسازی با will-change، transform (GPU-accelerated) و respects prefers-reduced-motion.
نمونه 1 — موج ساده با پسزمینه گرادیان و انیمیشن
/* Simple CSS wave using repeating-linear-gradient and animation */.wave {
position: relative;
height: 160px;
background: linear-gradient(180deg, #4fc3f7 50%, #0288d1 50%);
overflow: hidden;
}
.wave::before {
content: '';
position: absolute;
left: -50%;
top: -20%;
width: 200%;
height: 200%;
background: repeating-linear-gradient(
135deg,
rgba(255,255,255,0.08) 0 10px,
rgba(255,255,255,0.00) 10px 20px
);
transform: rotate(0deg);
animation: waveMove 8s linear infinite;
opacity: 0.8;
}
@keyframes waveMove {
from { transform: translateX(0) translateY(0) rotate(0deg); }
to { transform: translateX(-50%) translateY(0) rotate(0deg); }
}این کد از یک لایهٔ ::before با repeating-linear-gradient استفاده میکند تا خطوط شبیه موج ایجاد شود و با انیمیشن translateX حرکت دهد. این روش ساده است و برای جلوههای سبک مناسب است اما موج حاصل دقیقاً شبیه آب رفتار سینوسی نیست؛ بیشتر حس حرکت سطح را منتقل میکند.
نمونه 2 — موج واقعیتر با SVG و انیمیشن CSS
<div class="ocean">
<svg viewBox="0 0 1440 200" preserveAspectRatio="none">
<path id="wavePath" d="M0,60 C 360,120 1080,0 1440,60 L1440,200 L0,200 Z" fill="#0288d1"></path>
<use href="#wavePath" x="0" y="10" fill="#03a9f4" opacity="0.6"></use>
<use href="#wavePath" x="0" y="20" fill="#4fc3f7" opacity="0.4"></use>
</svg>
</div>
/* CSS */.ocean svg { width:100%; height:160px; display:block; }
.ocean path { transform-origin: 50% 50%; animation: float 6s linear infinite; }
.ocean path:nth-child(2) { animation-duration: 8s; }
.ocean path:nth-child(3) { animation-duration: 10s; }
@keyframes float {
0% { transform: translateX(0); }
50% { transform: translateX(-25%); }
100% { transform: translateX(0); }
}در این مثال از یک مسیر SVG تعریفشده و چند بار استفاده شده تا لایههای مختلف موج ایجاد شوند. هر لایه با سرعت متفاوت حرکت میکند (پارالاکس) تا حس عمق بیشتر شود. استفاده از SVG مزیت کیفیت و مقیاسپذیری بالا را دارد و میتوان مسیر موج را دقیقاً مطابق نیاز تغییر داد.
نمونه 3 — ماسک (mask) برای بخشهای متن یا پسزمینه
.hero {
position: relative;
height: 320px;
background: linear-gradient(180deg,#0288d1,#4fc3f7);
-webkit-mask-image: url('wave-mask.svg');
mask-image: url('wave-mask.svg');
mask-repeat: repeat-x;
animation: waveShift 12s linear infinite;
}
@keyframes waveShift {
from { background-position: 0 0; }
to { background-position: 100% 0; }
}با ماسک میتوان قسمتهایی از یک بلاک را شفاف یا موجدار کرد؛ این روش برای هدرهایی که متن یا لوگو روی موج قرار میگیرد مناسب است. توجه کنید که پشتیبانی مرورگر از mask-image بهتدرج بهتر شده اما برای سازگاری باید جایگزینهای سادهتر فراهم کنید.
بهینهسازی، عملکرد و دسترسی
- از transform (translate) استفاده کنید نه left/top برای کاهش repaint.
- برای المانهای متحرک از will-change: transform استفاده کنید اما بدون زیادهروی.
- برای کاربران با حرکت محدود (prefers-reduced-motion) انیمیشن را غیرفعال یا ملایم کنید.
- حداقل تعداد فریمها و طول انیمیشن مناسب (مثلاً 6–12s) باعث حس طبیعیتر میشود.
@media (prefers-reduced-motion: reduce) {
.wave::before, .ocean path { animation: none; }
}این قطعه کد باعث میشود دستگاههایی که ترجیح به کاهش حرکت دارند، انیمیشنها را نادیده بگیرند — یک بهترین عمل برای دسترسی است.
مقایسهٔ خلاصهٔ روشها
| روش | واقعگرایی | عملکرد | پیچیدگی |
|---|---|---|---|
| CSS گرادیان | متوسط | خوب | کم |
| SVG path | بالا | عالی (با transform) | متوسط |
| Mask/Image | بالا | متوسط | متوسط |
نمونههای کاربردی و نکات حرفهای
- برای صفحات لندینگ، ترکیب 3 لایه موج با رنگهای شفاف و سرعتهای مختلف جلوهٔ بسیار جذابی ایجاد میکند.
- اگر موج پشت عناصر تعاملی است، به z-index و pointer-events توجه کنید.
- در موبایل از فشردهسازی SVG و کاهش پیچیدگی path برای کارایی بهتر استفاده کنید.
- برای انیمیشنهای بسیار نرم، از cubic-bezier و مدتزمان بلندتر استفاده کنید تا حرکت طبیعیتر باشد.
خلاصه و بهترین روشها
انتخاب روش مناسب بستگی به نیاز شما دارد: اگر میخواهید موجی سبک و سریع بسازید از CSS گرادیان استفاده کنید؛ اگر نیاز به ظاهر دقیق و قابل اسکیل دارید از SVG بهره ببرید؛ و اگر میخواهید متن یا تصویر را با قالب موج برش دهید از ماسک استفاده کنید. همواره به عملکرد و دسترسی توجه کنید و برای انیمیشنها media query مربوط به prefers-reduced-motion را لحاظ نمایید.
آیا این مطلب برای شما مفید بود ؟




