مقایسه عمیق و کاربردی: display: none در برابر visibility: hidden

در درس قبل، هر دو مفهوم display: none و visibility: hidden رو دیدیم و یه مقایسه مختصر هم انجام دادیم. چون این تفاوت یکی از پرتکرارترین سؤالات و منابع اشتباه در CSS‌ه، این درس رو کاملاً به بررسی عمیق‌تر، مثال‌های عملی بیشتر و کاربردهای واقعی هرکدوم اختصاص می‌دیم.

یادآوری سریع تفاوت اصلی

تفاوت بنیادین این دو در یک جمله: display: none عنصر رو کاملاً از جریان صفحه حذف می‌کنه (انگار وجود نداره)، در حالی که visibility: hidden فقط عنصر رو از نظر بصری نامرئی می‌کنه، ولی فضاش رو در چیدمان حفظ می‌کنه.

مثال عملی ۱: تأثیر روی چیدمان یک منوی افقی

.menu-item.removed {
  display: none;
}

.menu-item.invisible {
  visibility: hidden;
}
<nav>
  <span class="menu-item">خانه</span>
  <span class="menu-item removed">درباره ما</span>
  <span class="menu-item">تماس</span>
</nav>

در این منو، چون آیتم «درباره ما» با display: none حذف شده، آیتم «تماس» بلافاصله بعد از «خانه» قرار می‌گیره؛ انگار «درباره ما» هیچ‌وقت وجود نداشته. اگه به‌جاش از visibility: hidden استفاده می‌کردیم، یه فضای خالی به‌اندازه «درباره ما» بین «خانه» و «تماس» باقی می‌موند.

چه زمانی از display: none استفاده کنیم؟

این گزینه مناسب‌ترین انتخاب برای موقعیت‌های زیره:

  • حذف کامل و قطعی یک بخش از صفحه: مثلاً مخفی کردن یک پنل تنظیمات تا زمانی که کاربر روی دکمه‌ای کلیک کنه.
  • Responsive Design: مخفی کردن یک عنصر در اندازه‌های خاص صفحه‌نمایش (مثلاً نمایش منوی همبرگری فقط در موبایل، و مخفی کردنش در دسکتاپ).
  • تب‌ها و آکاردئون‌ها: وقتی فقط یکی از چند بخش محتوا باید در لحظه نمایش داده بشه و بقیه کاملاً از جریان خارج بشن.
@media (min-width: 768px) {
  .mobile-menu-button {
    display: none;
  }
}

در این مثال رایج، دکمه منوی موبایل فقط در صفحه‌نمایش‌های کوچک‌تر از ۷۶۸ پیکسل دیده می‌شه؛ در صفحه‌نمایش‌های بزرگ‌تر، این دکمه کاملاً از جریان صفحه حذف می‌شه و هیچ فضایی هم اشغال نمی‌کنه.

چه زمانی از visibility: hidden استفاده کنیم؟

این گزینه مناسب موقعیت‌هاییه که حفظ ثبات چیدمان صفحه اهمیت داره:

  • Tooltip یا پیام خطا: وقتی می‌خوایم یه پیام (مثلاً پیام خطای اعتبارسنجی فرم) رو نمایش یا مخفی کنیم، بدون اینکه بقیه عناصر فرم هر بار جابه‌جا بشن.
  • حفظ تقارن در یک Grid یا لیست: وقتی چند آیتم باید همیشه یک تعداد ثابت باشن (مثلاً چهار ستاره امتیازدهی)، ولی بعضی‌هاشون در شرایط خاص نباید دیده بشن.
.error-message {
  visibility: hidden;
  color: crimson;
  font-size: 14px;
}

.error-message.show {
  visibility: visible;
}
<input type="email">
<span class="error-message">لطفاً یک ایمیل معتبر وارد کنید.</span>

در این مثال، چون visibility: hidden فضای پیام خطا رو حفظ می‌کنه، وقتی این پیام نمایش داده بشه (با اضافه شدن کلاس show)، بقیه عناصر فرم پایین‌تر جابه‌جا نمی‌شن؛ چیدمان همیشه ثابت و پایدار می‌مونه. اگه از display: none استفاده می‌کردیم، ظاهر شدن ناگهانی پیام خطا باعث می‌شد کل فرم یهو به پایین «هل» داده بشه.

تفاوت در دسترسی‌پذیری (Accessibility)

از منظر صفحه‌خوان‌ها (Screen Readerها که برای کاربران کم‌بینا استفاده می‌شن)، هر دو مقدار معمولاً باعث می‌شن محتوا نادیده گرفته بشه؛ یعنی نه display: none و نه visibility: hidden، هیچ‌کدوم محتوا رو برای صفحه‌خوان قابل‌خوندن نگه نمی‌دارن. این نکته مهمیه، چون گاهی توسعه‌دهنده‌ها تصور می‌کنن با visibility: hidden محتوا هنوز «به‌نوعی» در دسترسه؛ در حالی که از نظر صفحه‌خوان، هر دو تقریباً یکسان نادیده گرفته می‌شن.

تفاوت در Performance

از نظر Performance مرورگر، این دو رفتار متفاوتی دارن: تغییر display باعث محاسبه مجدد کامل Layout صفحه می‌شه (چون فضای اشغال‌شده تغییر می‌کنه)، در حالی که تغییر visibility معمولاً هزینه محاسباتی کمتری داره، چون فضای عنصر ثابت می‌مونه و فقط مرحله Paint (رسم بصری) دوباره اجرا می‌شه، نه کل Layout. این تفاوت در پروژه‌های بزرگ و پرتعامل می‌تونه محسوس باشه؛ موضوعی که با جزئیات کامل در فصل CSS Performance بررسیش می‌کنیم.

یک تست ذهنی ساده برای انتخاب درست

برای تصمیم‌گیری سریع بین این دو، این سؤال رو از خودت بپرس: «آیا می‌خوام فضای این عنصر، وقتی مخفیه، همچنان در چیدمان باقی بمونه؟»

  • اگه جواب «نه» است (می‌خوام بقیه عناصر جای خالی رو پر کنن) → از display: none استفاده کن.
  • اگه جواب «بله» است (نمی‌خوام چیدمان جابه‌جا بشه) → از visibility: hidden استفاده کن.

جدول جمع‌بندی نهایی

معیار display: none visibility: hidden
فضای چیدمان حذف می‌شود حفظ می‌شود
ارث‌بری به فرزندان غیرقابل بازگرداندن روی فرزند قابل بازگرداندن با visibility: visible روی فرزند
هزینه محاسباتی هنگام تغییر بازمحاسبه کامل Layout معمولاً فقط Paint مجدد
کاربرد رایج تب‌ها، منوی موبایل، حذف کامل بخش Tooltip، پیام خطا، حفظ تقارن چیدمان

نکات مهم

  • انتخاب بین این دو باید بر اساس نیاز واقعی به حفظ یا حذف فضای چیدمان انجام شود، نه صرفاً بر اساس عادت.
  • از نظر صفحه‌خوان‌ها، هر دو روش معمولاً محتوا را غیرقابل‌دسترس می‌کنند؛ تفاوت اصلی صرفاً در رفتار چیدمان بصری است.
  • تغییر visibility معمولاً هزینه محاسباتی کمتری نسبت به تغییر display دارد.

اشتباهات رایج

  • استفاده از display: none در جایی که ثبات چیدمان مهم است (مثل پیام‌های خطای فرم)، که باعث پرش ناگهانی محتوا می‌شود.
  • استفاده از visibility: hidden برای مخفی کردن کامل یک بخش بزرگ صفحه، در حالی که فضای خالی باقی‌مانده می‌تواند ظاهر صفحه را نامرتب کند.
  • تصور اینکه visibility: hidden محتوا را برای صفحه‌خوان‌ها همچنان در دسترس نگه می‌دارد.

جمع‌بندی

انتخاب بین display: none و visibility: hidden، به این سؤال کلیدی بستگی دارد: آیا فضای عنصر مخفی‌شده باید در چیدمان باقی بماند یا نه؟ display: none برای حذف کامل و قطعی مناسب است (مثل تب‌ها یا منوی ریسپانسیو)، در حالی که visibility: hidden برای حفظ ثبات چیدمان در شرایطی مثل پیام‌های خطا یا Tooltip مناسب‌تر است. این دو همچنین از نظر هزینه محاسباتی مرورگر و رفتار ارث‌بری با یکدیگر تفاوت دارند.