اخبار وب

CSS :has() و انتخاب‌گر والد؛ بالاخره ممکن شد!

سال‌ها انتخاب‌گر والد (Parent Selector) یکی از بزرگ‌ترین کمبودهای CSS بود. با معرفی شبه‌کلاس قدرتمند :has() این مشکل بالاخره حل شد. حالا می‌توانیم والد را بر اساس وضعیت ی...

1405/01/23 1 دقیقه مطالعه 485 بازدید
CSS :has() و انتخاب‌گر والد؛ بالاخره ممکن شد!

مقدمه

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

«چرا نمی‌توانیم والد یک عنصر را در CSS انتخاب کنیم؟»

قبل از :has()، اگر می‌خواستید بر اساس وضعیت یک فرزند، والدش را استایل دهید، مجبور بودید:

  • از JavaScript استفاده کنید
  • کلاس اضافه کنید
  • یا ساختار HTML را تغییر دهید

اما حالا با معرفی شبه‌کلاس :has()، این محدودیت تاریخی بالاخره برطرف شده است.

:has() دقیقاً چیست؟

:has() یک شبه‌کلاس رابطه‌ای (Relational Pseudo-class) است که به شما اجازه می‌دهد عنصری را انتخاب کنید اگر درون آن (یا در رابطه مشخصی با آن) المنتی خاص وجود داشته باشد.

ساختار کلی:

                                
selector:has(relative-selector) {
  /* styles */
}

به زبان ساده:

«این عنصر را انتخاب کن اگر داخلش این المنت وجود دارد.»

ساده‌ترین مثال

انتخاب تمام div هایی که شامل یک img هستند:

                                
div:has(img) {
  border: 2px solid green;
}

هر div که حداقل یک تصویر داشته باشد، حاشیه سبز می‌گیرد.

چرا این ویژگی مهم است؟

چون برای اولین بار در CSS می‌توانیم:

✅ والد را بر اساس فرزند انتخاب کنیم

✅ رفتارهای شرطی بسازیم

✅ بدون JS تعاملات پیچیده ایجاد کنیم

✅ UIهای هوشمندتر طراحی کنیم

کاربردهای عملی و حرفه‌ای

۱. فرم‌های هوشمند بدون JavaScript

استایل دادن به فیلد نامعتبر

                                
.form-group:has(input:invalid) {
  border: 2px solid red;
  background-color: #fff5f5;
}

اگر ورودی داخل .form-group نامعتبر باشد، کل گروه قرمز می‌شود.

فعال شدن دکمه هنگام تیک خوردن چک‌باکس

.form:has(input[type="checkbox"]:checked) button {
  background-color: green;
}

۲. کارت‌های پویا بر اساس محتوا

کارت دارای تصویر

.card:has(img) {
  padding-top: 0;
}

کارت دارای ویدیو

.card:has(video) {
  border: 2px dashed red;
}

۳. منوهای تعاملی

وقتی آیتمی hover شده، کل منو تغییر کند

.menu:has(li:hover) {
  background: #f5f5f5;
}

۴. گالری هوشمند

اگر فقط یک تصویر وجود دارد:

.gallery:has(.image:only-child) {
  display: flex;
  justify-content: center;
}

اگر چند تصویر وجود دارد:

 
.gallery:has(.image:nth-child(2)) {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}

۵. تم تاریک بدون JavaScript

   
body:has(.theme-toggle:checked) {
  background: #121212;
  color: white;
}

یک چک‌باکس ساده می‌تواند کل تم سایت را تغییر دهد.

ترکیب با سایر شبه‌کلاس‌ها

قدرت واقعی :has() زمانی مشخص می‌شود که با سایر selectorها ترکیب شود:

  • :not()
  • :is()
  • :where()
  • :nth-child()
  • :focus
  • :checked
  • :invalid
  • :placeholder-shown

مثال پیشرفته:

   
.card:has(input:focus):not(:has(input:invalid)) {
  box-shadow: 0 0 10px green;
}

مقایسه با روش‌های قدیمی

قبل از :has():

const input = document.querySelector("input");
input.addEventListener("input", () => {
  if (input.validity.valid) {
    input.parentElement.classList.add("valid");
  }
});

الان فقط با CSS:

    
.parent:has(input:valid) {
  border: 2px solid green;
}

✅ کد کمتر

✅ سریع‌تر

✅ تمیزتر

✅ بدون JS

عملکرد (Performance)

از آنجا که :has() یک selector پیشرفته است، ممکن است در ساختارهای بسیار بزرگ DOM هزینه محاسباتی داشته باشد.

نکات بهینه‌سازی:

  • از selectorهای بسیار عمیق داخل :has() پرهیز کنید
  • آن را به سطح خاصی محدود کنید
  • از کلاس‌های مشخص استفاده کنید

مثال بهتر:

                                
            content_copy            
            cssnote_addویرایش با Canvas
.card:has(> img)

به‌جای:

                                
            content_copy            
            cssnote_addویرایش با Canvas
body main section div.card:has(div.wrapper img)

پشتیبانی مرورگرها (۲۰۲۶)

در حال حاضر:

  • ✅ Chrome / Edge → پشتیبانی کامل
  • ✅ Safari → پشتیبانی کامل
  • ✅ Firefox → پشتیبانی کامل
  • ✅ مرورگرهای موبایل مدرن → پشتیبانی دارند

در سال ۲۰۲۶ تقریباً می‌توان با خیال راحت از :has() در پروژه‌های production استفاده کرد.

محدودیت‌ها

  • نمی‌تواند اجداد بالاتر را انتخاب کند مگر از طریق همان عنصر هدف
  • استفاده بیش از حد ممکن است پیچیدگی selector را بالا ببرد
  • در CSS قدیمی‌تر (قبل از ۲۰۲۳) پشتیبانی نمی‌شود

جمع‌بندی

:has() یکی از بزرگ‌ترین پیشرفت‌های CSS در دهه اخیر است.

این قابلیت:

  • انتخاب‌گر والد را ممکن کرد
  • وابستگی به JavaScript را کاهش داد
  • طراحی شرطی و هوشمند را ساده‌تر کرد
  • معماری CSS را مدرن‌تر کرد

اگر هنوز از آن استفاده نمی‌کنید، حالا بهترین زمان است.

CSS دیگر فقط برای استایل نیست —

بلکه حالا می‌تواند رفتارهای شرطی پیچیده را هم مدیریت کند.

واکنش به این مقاله

اشتراک‌گذاری این مقاله:
دیدگاه‌ها 0
۰ / ۲۰۰۰

هنوز دیدگاهی ثبت نشده

اولین نفری باشید که نظر می‌دهد!