برای سالها، توسعهدهندگان CSS برای مدیریت پیچیدگی به پیشپردازندههایی مانند SASS و LESS متکی بودند. ما سبکهای خود را به صورت دستی تو در تو میکردیم، از میکسینها برای تکرار استفاده میکردیم و ساختارهای کلاس پیچیدهای میساختیم تا از جنگهای مشخصگی (Specificity) دوری کنیم. با این حال، منظره CSS در حال تجربه یک تحول رادیکال است. CSS بومی از یک زبان سبکدهی ساده به یک سیستم قدرتمند و دارای قابلیتهای منطقی تکامل یافته است که تواناییهای آن با پیشپردازندهها رقابت میکند.
این مقاله به بررسی تأثیرگذارترین ویژگیهای مدرن CSS میپردازد که از پشتیبانی گسترده مرورگرها برخوردار شدهاند و به شما امکان میدهند بدون بار اضافی ابزارهای ساخت (Build tools)، سبکنامههای تمیزتر، قابلنگهداریتر و قدرتمندتری بنویسید. ما به بررسی تو در تو کردن CSS، پرسوجوهای ظرف، انتخابگر :has() و لایههای CSS خواهیم پرداخت.
عصر تو در تو کردن CSS بومی
روزگاری گذشته است که برای لذت بردن از تو در تو کردن (Nesting)، نیاز به کامپایل سبکهای خود داشتید. مرورگرهای مدرن اکنون از تو در تو کردن CSS بومی پشتیبانی میکنند که مزایای خوانایی و سازماندهی SASS را مستقیماً به CSS استاندارد میآورد. این ویژگی به شما امکان میدهد انتخابگرها را درون یکدیگر تو در تو کنید که سبکنامههای شما را شهودیتر کرده و تکرار کد را کاهش میدهد.
تو در تو کردن به ویژه برای معماریهای مبتنی بر کامپوننت مفید است. به جای نوشتن انتخابگرهای تکراری، میتوانید CSS خود را به گونهای ساختار دهید که با ساختار HTML همخوانی داشته باشد که این امر نگهداری را بهبود میبخشد.
نمونه کد: تو در تو کردن بومی
/* قبل: انتخابگرهای تکراری */
.card {
background: #fff;
border-radius: 8px;
}
.card:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.card h2 {
font-size: 1.5rem;
color: #333;
}
.card p {
font-size: 1rem;
color: #666;
}
/* بعد: تو در تو کردن مدرن */
.card {
background: #fff;
border-radius: 8px;
&:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
h2 {
font-size: 1.5rem;
color: #333;
}
p {
font-size: 1rem;
color: #666;
}
}
به استفاده از نماد & توجه کنید که نشاندهنده انتخابگر فعلی است. این موضوع به وضوح نشان میدهد که حالت hover به طور خاص برای عنصر .card اعمال میشود.
فراتر از اندازه صفحه نمایش: پرسوجوهای ظرف
طراحی واکنشگرا (Responsive) مدتهاست که با استفاده از پرسوجوهای @media به اندازه صفحه نمایش (Viewport) گره خورده است. با این حال، این رویکرد هنگامی که کامپوننتها نیاز دارند بر اساس اندازه خودشان به جای اندازه صفحه نمایش سازگار شوند، محدودیتهایی دارد. تصور کنید یک کامپوننت کارت نیاز دارد چیدمان خود را زمانی که در یک نوار کناری (Sidebar) در مقابل یک ناحیه محتوای اصلی قرار میگیرد، تغییر دهد، صرفنظر از عرض کلی صفحه.
پرسوجوهای ظرف با اجازه دادن به شما برای سبکدهی به عناصر بر اساس اندازه ظرف والد خود، این مشکل را حل میکنند. این امر جداسازی واقعی و قابلیت استفاده مجدد کامپوننتها را ترویج میدهد.
نمونه کد: پرسوجوهای ظرف
/* تعریف ظرف */
.sidebar-widget {
container-type: inline-size;
container-name: sidebar;
}
/* سبکدهی بر اساس عرض ظرف */
@container sidebar (min-width: 400px) {
.widget-card {
display: flex;
flex-direction: row;
}
}
@container sidebar (max-width: 399px) {
.widget-card {
display: block;
flex-direction: column;
}
}
با تعریف یک container-type، شما به مرورگر میگویید که این عنصر باید به عنوان زمینه پرسوجو عمل کند. سپس عناصر فرزند میتوانند به تغییرات ابعاد آن ظرف پاسخ دهند که چیدمانهایی را امکانپذیر میسازد که واقعاً ماژولار هستند.
قدرت منطقی :has()
شاید :has() که اغلب به عنوان "انتخابگر والد" شناخته میشود، درخواستشدهترین ویژگی در تاریخ CSS باشد. اگرچه این انتخابگر مستقیماً عنصر والد را انتخاب نمیکند، اما به شما امکان میدهد بر اساس وجود یک عنصر فرزند، به عنصر والد سبکدهی کنید. این قابلیت الگوهای جدیدی برای حالتهای رابط کاربری (UI) را باز میکند، مانند سبکدهی به یک بستهبندی فرم فقط زمانی که یک فیلد ورودی نامعتبر است.
این انتخابگر برای ایجاد چیدمانهای مبتنی بر حالت بدون نیاز به جاوااسکریپت برای تغییر کلاسها روی عناصر والد، ایدهآل است.
نمونه کد: استفاده از :has()
/* سبکدهی به فرم والد زمانی که شامل یک ورودی متمرکز است */
form:has(:focus) {
border-color: blue;
box-shadow: 0 0 5px rgba(0,0,255,0.5);
}
/* انتخاب یک پاراگراف فقط اگر شامل یک تصویر باشد */
p:has(img) {
font-size: 1.2em;
}
مدیریت مشخصگی با لایههای CSS
همانطور که پروژهها بزرگتر میشوند، مدیریت مشخصگی (Specificity) به یک کابوس تبدیل میشود. کتابخانههای جاوااسکریپت، چارچوبهای رابط کاربری و سبکهای سفارشی اغلب با هم تعارض دارند که منجر به استفاده از ترفند ناخوشایند !important میشود. لایههای CSS که با استفاده از @layer تعریف میشوند، راهی برای سازماندهی و اولویتدهی صریح سبکها فراهم میکنند.
لایهها به شما امکان میدهند یک ترتیب سلسلهمراتب (Cascade) برای سبکهای خود تعریف کنید، اطمینان حاصل کنید که توکنهای سیستم طراحی یا کلاسهای کاربردی در صورت نیاز بر سبکهای کامپوننت اولویت دارند.
نمونه کد: لایههای CSS
@layer utilities, components, reset;
@layer reset {
/* اولویت کم */
* { margin: 0; padding: 0; }
}
@layer components {
/* اولویت متوسط */
.button { background: red; }
}
@layer utilities {
/* اولویت بالا */
.bg-blue { background: blue; }
}
با تعریف ترتیب لایهها، یک سلسلهمراتب قابل پیشبینی ایجاد میکنید. هر سبک درون utilities سبکهای موجود در components را لغو میکند که در نوبت خود سبکهای reset را لغو میکند.
نتیجهگیری
CSS مدرن دیگر فقط درباره زیبا کردن چیزها نیست؛ بلکه درباره ایجاد چیدمانهای ساختاریافته، منطقی و واکنشگرا با کد کمتر است. ویژگیهایی مانند تو در تو کردن، پرسوجوهای ظرف، :has() و لایهها به توسعهدهندگان قدرت میبخشند تا رابطهای کاربری قابلنگهداریتری بسازند. با پذیرش این قابلیتهای بومی، میتوانید وابستگی خود به ابزارهای خارجی را کاهش دهید و CSS بنویسید که به همان اندازه قدرتمند و ابرازگر است که جاوااسکریپت محرک برنامههای شما. آینده CSS اینجاست و زمان آن رسیده است که با آن کدنویسی را آغاز کنید.