سال‌ها یکی از بزرگ‌ترین حسرت‌های توسعه‌دهندگان CSS این بود که نمی‌شد بر اساس «فرزندِ یک عنصر»، خودِ والد را استایل داد. انتخابگر :has() دقیقاً همین کار را می‌کند و حالا در همه مرورگرهای اصلی پشتیبانی می‌شود.

اصل کار

عبارت A:has(B) یعنی «هر عنصر A که درونش یک B وجود دارد». برای مثال کارتی که تصویر دارد با کارتی که ندارد چیدمان متفاوتی بگیرد:

.card:has(img) {
  display: grid;
  grid-template-columns: 160px 1fr;
}

.card:not(:has(img)) {
  padding: 1rem;
}

فرم‌ها بدون جاوااسکریپت

با ترکیب :has() و حالت‌های فرم می‌توان بازخورد لحظه‌ای ساخت؛ مثلاً هایلایت‌کردن گزینهٔ انتخاب‌شده یا غیرفعال‌نشان‌دادن دکمهٔ ارسال تا وقتی فرم معتبر نیست:

label:has(input:checked) {
  border-color: #2563eb;
  background: #eff6ff;
}

form:has(:invalid) .submit {
  opacity: .5;
  pointer-events: none;
}

نکته‌های کاربردی

  • می‌توانید چند انتخابگر را با ویرگول بدهید: :has(h2, h3).
  • برای هم‌نشین‌ها هم کار می‌کند: h2:has(+ p) یعنی عنوانی که بلافاصله بعدش پاراگراف آمده.
  • از انتخابگرهای بسیار عام مثل body:has(...) روی صفحه‌های سنگین با احتیاط استفاده کنید.
  • برای مرورگرهای قدیمی‌تر می‌توانید از @supports selector(:has(*)) استفاده کنید.