برای سالها، توسعهدهندگان CSS با محدودیتی همیشگی روبرو بودند: ناتوانی در انتخاب یک عنصر والد بر اساس فرزندان آن. ما به شدت به جاوااسکریپت برای افزودن کلاسهای کمکی متکی بودیم یا از میکسینهای SASS دشوار استفاده میکردیم تا این خلأ را پر کنیم. با این حال، معرفی شبهکلاسهای :has() و :is() نحوه نوشتن استایلها را متحول کرده است. این ابزارهای قدرتمند امکان نوشتن کدی بیانگرتر، قابلنگهداریتر و کارآمدتر را فراهم میکنند. در این پست، بررسی خواهیم کرد که چگونه میتوان از این انتخابگرها برای غلبه بر چالشهای پیچیده رابط کاربری بهره برد.
درک انتخابگر :is()
شبهکلاس :is() در اصل یک انتخابگر گروهبندی است. به شما امکان میدهد عناصری را که با هر یک از انتخابگرهای موجود در لیست آرگومان آن مطابقت دارند، شناسایی کنید. پیش از :is()، توسعهدهندگان اغلب برای اعمال استایلهای مشترک، انتخابگرها را تکرار میکردند که منجر به کدی طولانی و تکراری میشد.
فرض کنید میخواهید تمام عناوین داخل یک کانتینر خاص را به صورت متفاوتی استایلدهی کنید. بدون :is()، ممکن است کدی مانند زیر بنویسید:
.container h1 {
color: blue;
}
.container h2 {
color: blue;
}
.container h3 {
color: blue;
}
با استفاده از :is()، میتوانید این موارد را در یک قانون واحد و تمیز خلاصه کنید:
.container :is(h1, h2, h3) {
color: blue;
}
این کار نه تنها حجم فایل را کاهش میدهد، بلکه خوانایی را نیز بهبود میبخشد. علاوه بر این، :is() خاصیت Specificity (اولویت) خاصترین آرگومان خود را به ارث میبرد. این نکته برای درک نحوه تعامل آن با سایر انتخابگرها حیاتی است و تضمین میکند که استایلهای شما دقیقاً همانطور که قصد دارید سرازیر شوند، بدون درگیریهای غیرمنتظره بر سر اولویتها.
تغییردهنده بازی: انتخابگر :has()
اگر :is() درباره گروهبندی است، :has() درباره زمینه (Context) است. اغلب به عنوان «انتخابگر والد» شناخته میشود، :has() عنصری را انتخاب میکند اگر حداقل یک عنصر که با انتخابگر ارائهشده در آرگومان آن مطابقت دارد را در خود نگه دارد. این قابلیت دریچهای به سوی راهحلهای کاملاً مبتنی بر CSS برای حالتهایی میگشاید که پیشتر نیاز به جاوااسکریپت داشتند.
بیایید یک مثال عملی را بررسی کنیم: استایلدهی به یک گروه فرم بر اساس این که آیا فیلد ورودی آن معتبر است یا خیر. به طور سنتی، شما نیاز به یک شنونده رویداد (Event Listener) روی ورودی داشتید تا کلاسی را به والد فرم اضافه کند. با :has()، این کار به صورت خودکار انجام میشود:
/* استایلدهی به لیبل اگر ورودی داخل فرم-گروپ معتبر باشد */
.form-group:has(input:valid) .label {
color: green;
}
/* استایلدهی به حاشیه فرم-گروپ اگر ورودی آن دارای خطا باشد */
.form-group:has(input:invalid) {
border-color: red;
}
این انتخابگر برای ساخت کامپوننتهای قابل دسترس (Accessible) به شدت قدرتمند است. برای مثال، میتوانید یک کارت را به صورت بصری برجسته کنید وقتی کاربر با هر لینکی در داخل آن تعامل دارد:
.card:has(:focus-visible) {
box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5);
}
تودرتو کردن و ترکیبگرها
:has() از تمام ترکیبگرهای استاندارد پشتیبانی میکند، مانند + (خواهر بعدی) و ~ (خواهر عمومی). این امکان را برای عبارات منطقی پیچیده فراهم میآورد. برای مثال، میتوانید یک آیتم ناوبری را استایلدهی کنید اگر دارای یک منوی کشویی باشد که در حال حاضر باز است:
nav li:has(~ .dropdown-menu.open) {
background-color: #f0f0f0;
}
پشتیبانی مرورگر و بهترین شیوهها
تا سال ۲۰۲۴، هر دو :has() و :is() از پشتیبانی گستردهای در مرورگرهای مدرن از جمله Chrome، Firefox، Safari و Edge برخوردار هستند. با این حال، اگر باید از مرورگرهای قدیمی مانند Internet Explorer پشتیبانی کنید، استفاده از پلاگینهای PostCSS مانند postcss-nesting یا بازگشت به راهحلهای جاوااسکریپت را در نظر بگیرید.
هنگام استفاده از این انتخابگرها، نکات زیر را در نظر داشته باشید:
- از تودرتو کردن بیش از حد پرهیز کنید: اگرچه
:has()قدرتمند است، اما انتخابگرهای به شدت تودرتو میتوانند عیبیابی آنها را دشوار کنند. - دسترسپذیری را آزمایش کنید: اطمینان حاصل کنید که نشانههای بصری اضافهشده از طریق
:has()تنها به رنگ متکی نیستند، زیرا این امر میتواند بر کاربران دارای نقص بینایی تأثیر بگذارد. - عملکرد: پرسوجوهای پیچیده
:has()میتوانند از نظر محاسباتی پرهزینه باشند. اگر در حال ساخت برنامههای مقیاسپذیر بزرگ هستید، استایلهای خود را بنچمارک (Benchmark) کنید.
نتیجهگیری
انتخابگرهای :is() و :has() نشاندهنده تکامل قابل توجهی در قابلیتهای CSS هستند. با امکانپذیر کردن گروهبندی بهتر و استایلدهی زمینهمحور، به توسعهدهندگان این قدرت را میدهند که استایلشیتهای تمیزتر، معناییتر و قابلنگهداریتر بنویسند. با استاندارد شدن این ویژگیها در تمام پلتفرمها، تسلط بر آنها دیگر اختیاری نیست—بلکه برای هر توسعهدهنده فرانتاند که میخواهد پیشرو بماند، ضروری است. این ابزارها را بپذیرید تا وابستگی خود به جاوااسکریپت را کاهش داده و رابطهای کاربری مقاومتری ایجاد کنید.