ویژگی تصویر

ساخت افکت سایه داخلی با CSS — راهنمای کامل

  /  CSS   /  ساخت افکت سایه داخلی با CSS
بنر تبلیغاتی الف

سایه داخلی (inner shadow) یکی از ابزارهای مهم طراحی است که به عناصر عمق و حس برجستگی یا فرو رفتگی می‌دهد. در CSS معمولاً از خاصیت box-shadow با مقدار inset استفاده می‌شود، اما تکنیک‌های پیشرفته‌تر با pseudo-element، گرادینت‌ها و SVG هم رایج است. در این مقاله قدم‌به‌قدم، از نمونه‌های ساده تا پیاده‌سازی‌های حرفه‌ای و نکات بهینه‌سازی، همه را بررسی می‌کنیم.

مفاهیم پایه: box-shadow inset

/* ساده‌ترین سایه داخلی */.card {
  width: 300px;
  height: 180px;
  background: #fff;
  border-radius: 12px;
  box-shadow: inset 0 4px 10px rgba(0,0,0,0.15);
  padding: 16px;
}

در این مثال از box-shadow: inset استفاده شده که سایه را به داخل المان می‌کشد. مقادیر به‌ترتیب افست-x، افست-y، بلور و رنگ هستند. اگر فقط عمق کم می‌خواهیم، مقدار بلور و شفافیت را کم می‌کنیم.

چند سایهٔ هم‌زمان برای عمق بهتر

.card {
  box-shadow:
    inset 0 2px 4px rgba(0,0,0,0.08),
    inset 0 10px 20px rgba(0,0,0,0.06),
    0 4px 12px rgba(0,0,0,0.08); /* خارجی برای تاکید */}

می‌توان چندین سایهٔ داخلی را با کاما ترکیب کرد تا افکت طبیعی‌تر و چند لایه‌ای ایجاد شود. در انتها نیز می‌توانید سایهٔ خارجی اضافه کنید تا المان از پس‌زمینه جدا شود.

مشکل با border-radius و راه‌حل pseudo-element

گاهی سایهٔ داخلی در المان‌هایی با border-radius هنگام ترکیب با پس‌زمینهٔ شفاف یا مرزبندی دقیق، مطلوب دیده نمی‌شود. برای کنترل بیشتر می‌توان از یک ::before یا ::after استفاده کرد و سایه را داخل آن قرار داد.

.card {
  position: relative;
  overflow: hidden;
  border-radius: 12px;
  background: linear-gradient(#fff, #f7f7f7);
}
.card::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 6px 20px rgba(0,0,0,0.2);
  border-radius: inherit;
}

در این روش یک pseudo-element تمام فضای والد را می‌پوشاند و سایه داخل آن اعمال می‌شود. با pointer-events: none مانع تداخل با تعاملات کاربر می‌شویم و با border-radius: inherit انطباق با شعاع گوشه‌ها حفظ می‌شود.

سایهٔ داخلی با گرادینت برای ظاهری نرم‌تر

/* گرادینت شعاعی برای سایهٔ داخلی ملایم */.card::before {
  background: radial-gradient(ellipse at center, rgba(0,0,0,0.15) 0%, transparent 60%);
  mix-blend-mode: multiply;
}

گرادینت‌ها امکان ساخت سایه‌های غیر یکنواخت را می‌دهند و برای افکت‌های نرم و هنری مناسب‌ترند. ترکیب با mix-blend-mode می‌تواند نتیجهٔ جذاب‌تری تولید کند، اما باید سازگاری مرورگر را در نظر گرفت.

افکت سایهٔ داخلی برای متن

/* شبیه‌سازی متن فرو رفته */.text-inset {
  color: #222;
  text-shadow:
    0 1px 0 #fff,
    0 -1px 6px rgba(0,0,0,0.35);
}

برای متن از text-shadow استفاده می‌کنیم. با ترکیب سایه‌های مثبت و منفی می‌توان حس فرو رفتگی یا برجستگی ایجاد کرد. توجه کنید که خوانایی متن باید حفظ شود.

پیاده‌سازی برای دکمه‌های تعاملی

.btn {
  background: linear-gradient(#f6f6f6, #eaeaea);
  border: 1px solid #d0d0d0;
  border-radius: 8px;
  padding: 10px 16px;
  box-shadow: inset 0 2px 0 rgba(255,255,255,0.6), inset 0 -6px 12px rgba(0,0,0,0.12);
  transition: transform 150ms ease, box-shadow 150ms ease;
}
.btn:active {
  transform: translateY(1px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.4), inset 0 -2px 6px rgba(0,0,0,0.18);
}

سایهٔ داخلی در دکمه‌ها حس لمس‌پذیری و فشردگی اضافه می‌کند. در حالت فعال (:active) تغییر اندازه و شدت سایه باعث احساس فشرده شدن می‌شود.

نکات سازگاری و عملکرد

  • پشتیبانی مرورگر: box-shadow و text-shadow در تمام مرورگرهای مدرن پشتیبانی می‌شوند؛ اما blend modes و فیلترها ممکن است محدودیت داشته باشند.
  • عملکرد: سایه‌های سنگین با بلور بالا ممکن است رندر GPU را درگیر کنند و باعث افزایش مصرف منابع و افت فریم شوند. در صفحات با تعداد زیادی المان، از سایه‌های سبک‌تر یا تصاویر آماده استفاده کنید.
  • دسترسی: کنتراست و خوانایی را بررسی کنید تا سایه‌ها باعث کاهش خوانایی متن یا محتوای مهم نشوند.

ترفندهای پیشرفته

  • استفاده از CSS variables برای تغییر آسان رنگ و شدت در تم‌ها (روشن/تیره).
  • ترکیب با backdrop-filter برای افکت‌های محوشدگی در پس‌زمینه (مخصوصاً در پنجره‌ها و کارت‌ها) — توجه به پشتیبانی مرورگر.
  • برای افکت‌های پیچیده‌تر که نیاز به کنترل پیکسلی دارند، می‌توان از SVG با فیلترهای Gaussian blur و feComposite استفاده کرد.

نمونهٔ حرفه‌ای با متغیرها و حالت تیره

:root {
  --inset-shadow: rgba(0,0,0,0.18);
  --surface: #ffffff;
}
@media (prefers-color-scheme: dark) {
  :root {
    --inset-shadow: rgba(0,0,0,0.6);
    --surface: #111213;
  }
}
.card {
  background: var(--surface);
  box-shadow: inset 0 6px 18px var(--inset-shadow);
  border-radius: 14px;
  padding: 20px;
}

با استفاده از متغیرها و prefers-color-scheme می‌توانید بدون تغییر دستی در کد، افکت سایه را برای حالت‌های تاریک و روشن تنظیم کنید. این روش مدیریت طراحی را ساده می‌کند.

مقایسهٔ روش‌ها (خلاصه)

روشمزایامعایب
box-shadow insetساده، پشتیبانی خوبدر گوشه‌ها و با مرزبندی پیچیده محدود
pseudo-elementکنترل بیشتر، سازگار با border-radiusکمی پیچیده‌تر، تگ اضافی در DOM مجازی
SVG/Filtersافکت‌های دقیق و قابل تنظیم پیکسلیپیاده‌سازی پیچیده‌تر، حجم بیشتر

چند نکتهٔ عملی و قابل توجه

  • برای عناصر با پس‌زمینهٔ تصویری یا گرادینت، از pseudo-element برای جلوگیری از تداخل استفاده کنید.
  • اگر هدف عملکرد بالا است، از سایه‌های کمتر و تصاویر raster برای المان‌های ثابت استفاده کنید.
  • همیشه روی چند دستگاه تست کنید تا مشکلات رندر و کنتراست را ببینید.

سایهٔ داخلی ابزار ساده اما قدرتمندی است. با ترکیب اصول پایه با pseudo-elementها، گرادینت‌ها و متغیرها می‌توانید افکت‌های زیبا و عملکرد مناسبی در طراحی وب ایجاد کنید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: