@container و :has(): دو API پاسخگو جدید قدرتمند در Chromium 105 فرود می‌شوند

پرس و جوهای کانتینر و :has() یک تطبیق هستند که در بهشت ​​پاسخگو ساخته شده اند. خوشبختانه، هر دوی این ویژگی‌ها با هم در Chromium 105 قرار می‌گیرند. این نسخه بزرگ با دو ویژگی بسیار درخواستی برای رابط‌های واکنش‌گرا است!

پرس و جوهای ظرف: خلاصه ای سریع

جستجوهای Container به توسعه دهندگان این امکان را می دهد که از یک انتخابگر والد برای اندازه و اطلاعات سبک آن سؤال کنند، و این امکان را برای عنصر فرزند ایجاد می کند که منطق استایل پاسخگو خود را بدون توجه به جایی که در یک صفحه وب زندگی می کند، داشته باشد.

توسعه‌دهندگان به‌جای تکیه بر Viewport برای طراحی ورودی مانند فضای موجود، اکنون این توانایی را دارند که اندازه عناصر درون صفحه را نیز جستجو کنند. این قابلیت به این معنی است که یک کامپوننت دارای منطق استایل پاسخگوی خود است. این کامپوننت را بسیار انعطاف‌پذیرتر می‌کند، زیرا منطق استایل به آن متصل است، مهم نیست در کجای صفحه ظاهر می‌شود.

استفاده از پرس و جوهای کانتینر

برای ساخت با کوئری های کانتینر، ابتدا باید Containment را روی یک عنصر والد تنظیم کنید. این کار را با تنظیم یک container-type در کانتینر اصلی انجام دهید. ممکن است کارتی با یک تصویر و محتوای متنی داشته باشید که شبیه این است:

کارت تک دو ستونی.

برای ایجاد یک جستجوی کانتینر، container-type روی ظرف کارت تنظیم کنید:

.card-container {
  container-type: inline-size;
}

تنظیم container-type به inline-size اندازه جهت درونی والد را جستجو می کند. در زبان‌های لاتین مانند انگلیسی، این عرض کارت است، زیرا متن از چپ به راست به صورت خطی جریان دارد.

اکنون، می‌توانیم از آن ظرف برای اعمال استایل‌ها به هر یک از فرزندانش با استفاده از @container استفاده کنیم:

.card {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

@container (max-width: 400px) {
  .card {
    grid-template-columns: 1fr;
  }
}

انتخابگر :has()

شبه کلاس CSS :has() به توسعه دهندگان این امکان را می دهد تا بررسی کنند که آیا عنصر والد دارای فرزندانی با پارامترهای خاص است یا خیر.

به عنوان مثال، p:has(span) یک انتخابگر پاراگراف ( p ) را نشان می دهد که دارای یک span در داخل آن است. می توانید از این برای استایل دادن به خود پاراگراف والد یا استایل دادن به هر چیزی در آن استفاده کنید. یک مثال مفید figure:has(figcaption) برای استایل دادن به عنصر figure که حاوی عنوان است. شما می توانید در این مقاله توسط جی تامپکینز اطلاعات بیشتری در مورد :has() مشاهده کنید.

پرس و جوهای کانتینر و :has()

می‌توانید قدرت‌های انتخاب والد :has() را با قدرت‌های پرس‌وجو والد کوئری‌های کانتینر ترکیب کنید تا سبک‌های درونی واقعاً پویا ایجاد کنید.

اجازه دهید مثال اول را با کارت موشک گسترش دهیم. اگر کارتی بدون تصویر داشتید چه؟ شاید بخواهید اندازه عنوان را افزایش دهید و طرح‌بندی شبکه‌ای را به یک ستون تنظیم کنید تا بدون تصویر عمدی‌تر به نظر برسد.

متن بزرگ‌تر روی کارت بدون تصویر، و در یک ستون نشان داده می‌شود.

در این مثال، کارت با تصویر دارای یک الگوی شبکه دو ستونی است، در حالی که کارت بدون تصویر دارای طرح تک ستونی است. علاوه بر این، کارت بدون تصویر دارای عنوان بزرگتری است. برای نوشتن این با استفاده از :has() از CSS زیر استفاده کنید.

.card:has(.visual) {
  grid-template-columns: 1fr 1fr;
}

شما به دنبال عنصری با کلاس visual برای اعمال سبک دو ستونی بالا هستید. یکی دیگر از تابع های CSS منظم :not() است. این بخشی از همان مشخصات :has() است، اما مدت طولانی تری وجود داشته است و از مرورگر بهتری پشتیبانی می کند. حتی می توانید :has() و :not() را با هم ترکیب کنید، مانند:

.card:not(:has(.visual)) h1 {
  font-size: 4rem;
}

در کد بالا، شما در حال نوشتن یک انتخابگر هستید که یک h1 را در کارتی که فاقد کلاس visual است، استایل می کند. به این ترتیب می توانید به وضوح اندازه فونت را تنظیم کنید.

همه را کنار هم گذاشتن

نسخه ی نمایشی بالا ترکیبی از :has() ، :not() و @container را نشان می دهد، اما پرس و جوهای کانتینر واقعاً زمانی می درخشند که می توانید یک عنصر مشابه را در مکان های مختلف مشاهده کنید. بیایید کمی سبک اضافه کنیم و این کارت ها را در یک شبکه در کنار یکدیگر به نمایش بگذاریم.

اکنون واقعاً می توانید قدرت CSS مدرن را ببینید. ما می‌توانیم با استفاده از سبک‌های هدفمند، استایل‌های واضح بنویسیم که منطق را در بالای منطق ایجاد می‌کنند و مؤلفه‌های واقعاً قوی ایجاد می‌کنند. با وجود این دو ویژگی قدرتمند در Chromium 105 و افزایش سرعت پشتیبانی بین مرورگرها، زمان هیجان انگیزی برای توسعه دهنده رابط کاربری است!