Tailwind CSS نسخه ۴: کوئریهای کانتینر و مرگ کوئریهای مدیا

کدبیس خود را برای یافتن کامپوننتهایی که در چندین زمینه طرحبندی (سایدبارها، ماژولها، گریدها) ظاهر میشوند ، بررسی کنید .
ابزار @container را به عنصر والد طرحبندی مستقیم هر کامپوننت اضافه کنید .
پیشوندهای viewport را با پیشوندهای container عوض کنید — md: تبدیل میشود به @md: و lg: تبدیل میشود به @lg:
اندازه نقاط شکست را تنظیم کنید ، زیرا نقاط شکست کانتینر ( @md = 448px) کوچکتر از نقاط شکست ویوپورت ( md = 768px) هستند.
کانتینرها را با سینتکس @container/card نامگذاری کنید ، زمانی که تودرتونویسی نیاز به هدف قرار دادن یک جد خاص دارد.
هر کامپوننت را در سه عرض والد (~250px، ~450px، تمام عرض) با استفاده از اشکالزدایی کوئری کانتینر DevTools آزمایش کنید .
کوئریهای رسانهای viewport را برای تصمیمات مربوط به طرحبندی سطح صفحه مانند ستونهای شبکهای و قابلیت مشاهده ناوبری نگه دارید .
شما یک کامپوننت کارت واکنشگرا با md:flex-row و lg:gap-6 میسازید، آن را در یک شبکه با عرض کامل آزمایش میکنید و همه چیز عالی به نظر میرسد. سپس یک طراح همان کارت را در یک نوار کناری ۳۰۰ پیکسلی قرار میدهد و طرحبندی به هم میریزد. این نقص اساسی است که کوئریهای کانتینر Tailwind CSS نسخه ۴ آن را برطرف میکنند: کوئریهای رسانهای به viewport پاسخ میدهند، نه به فضایی که یک کامپوننت واقعاً اشغال میکند.
Tailwind CSS نسخه ۴ ابزارهای بومی پرسوجوی کانتینر را ارائه میدهد که به کامپوننتها اجازه میدهد به جای پنجره مرورگر، ابعاد کانتینر والد خود را پرسوجو کنند. در این آموزش پرسوجوهای کانتینر CSS ، من سینتکس جدید را بررسی میکنم، یک کامپوننت واقعی را از نقاط شکست viewport به نقاط شکست کانتینر منتقل میکنم و دستورالعملهای عملی را برای زمانی که هر رویکرد هنوز منطقی است، ارائه میدهم. پشتیبانی مرورگر؟ پرسوجوهای کانتینر به خط پایه ۲۰۲۳ میرسند. کروم ۱۰۵+، فایرفاکس ۱۱۰+، سافاری ۱۶+. میتوانید این را امروز ارسال کنید.
فهرست مطالب
چرا نقاط شکست Viewport کامپوننتها را میشکنند؟
کوئریهای رسانهای عرض viewport را ارزیابی میکنند. همین. آنها هیچ چیزی در مورد <div> کامپوننت شما که درون آن قرار دارد، ستون grid که آن را محدود میکند، یا modal که آن را در بر میگیرد، نمیدانند. برای صفحات یکپارچه خوب است. برای توسعه رابط کاربری مبتنی بر کامپوننت افتضاح است.
یک <ProductCard> میتواند در یک جدول محصولات سه ستونه، یک سایدبار تک ستونه، یک پنجره مقایسه و یک پنل داشبورد، همه در یک صفحه و با عرض یکسان نمایش داده شود.
وقتی md:flex-row به آن کارت اضافه میکنید، در واقع میگویید «وقتی پنجره مرورگر به ۷۶۸ پیکسل رسید، به طرحبندی افقی تغییر دهید.» اما اگر کارت در یک نوار کناری ۲۸۰ پیکسلی روی یک مانیتور ۱۴۴۰ پیکسلی قرار گیرد، پنجره نمایش عریض، والد کارت باریک و طرحبندی افقی زمانی که جایی برای آن وجود ندارد، فعال میشود.
توسعهدهندگان سالهاست که با ترفندهای زشتی این مشکل را حل کردهاند: کلاسهای override مخصوص wrapper مانند sidebar-card ، شنوندههای ResizeObserver مبتنی بر جاوااسکریپت که کلاسها را به صورت اجباری تغییر وضعیت میدهند، یا انواع کامپوننتهای کاملاً تکراری. هر یک از این رویکردها شکننده، دشوار برای نگهداری و مقیاسپذیری ضعیفی دارند.
الگویی که باعث درد میشود به شرح زیر است:
مثال کد ۱: یک کارت محصول مبتنی بر ویوپورت که در والدهای باریک میشکند
<!-- This card uses viewport breakpoints --> <div class="max-w-sm rounded-lg border bg-white shadow"> <img src="/product.jpg" alt="Product" class="w-full rounded-t-lg md:w-48 md:rounded-l-lg md:rounded-t-none" /> <div class="p-4"> <h3 class="text-lg font-semibold md:text-xl">Wireless Headphones</h3> <p class="mt-1 text-sm text-gray-600">Premium noise-canceling audio</p> <span class="mt-2 inline-block text-lg font-bold text-indigo-600">$249</span> </div> </div>
<!-- Problem: At viewport >= 768px, md: utilities activate. If this card is placed inside a 280px sidebar, the image gets md:w-48 (192px), leaving only ~88px for text. The layout is broken, but the viewport is "wide." --> این را در یک کانتینر با عرض کامل قرار دهید و عالی به نظر میرسد. آن را در یک نوار کناری قرار دهید و md: utilities بر اساس پنجره مرورگر فعال میشود، نه فضای موجود. تصویر ۱۹۲ پیکسل از یک والد ۲۸۰ پیکسلی را نشان میدهد و ستون متن جمع میشود.
کوئریهای رسانهای عرض viewport را ارزیابی میکنند. همین. آنها هیچ چیزی در مورد <div> کامپوننت شما که درون آن قرار دارد، ستون grid که آن را محدود میکند، یا modal که آن را در بر میگیرد، نمیدانند. برای صفحات یکپارچه خوب است. برای توسعه رابط کاربری مبتنی بر کامپوننت افتضاح است.
نحوه کار کوئریهای کانتینر (مقدمه 30 ثانیهای)
زمینهی مهار و @container
دو بخش از مدل ذهنی:
یک عنصر والد با استفاده از container-type خود را به عنوان یک زمینهی مهار تعریف میکند. این به مرورگر میگوید: "ممکن است فرزندان من بخواهند بدانند که عرض من چقدر است."
یک عنصر فرزند از قانون @container برای اعمال مشروط استایلها بر اساس ابعاد عنصر والد استفاده میکند.
رایجترین تعریف، container-type: inline-size است که امکان پرسوجوها را در برابر محور درونخطی (عرض در حالتهای نوشتاری افقی) کانتینر فراهم میکند. تقریباً همیشه به جای size inline-size میخواهید. چرا؟ size همچنین نیاز به مهار محور بلوکی دارد که میتواند محاسبات ارتفاع را به هم بریزد و باعث رفتار غیرمنتظره طرحبندی، به ویژه با محتوای auto-height شود.
این یک CSS بومی از مشخصات سطح ۳ ماژول مهار CSS است. Tailwind آن را اختراع نکرده است. Tailwind نسخه ۴ این عناصر اولیه را در کلاسهای کاربردی قرار میدهد که در کنار پیشوندهای واکنشگرای sm: md: lg: که از قبل میشناسید، طبیعی به نظر میرسند.
کانتینرهای نامگذاری شده در مقابل کانتینرهای بدون نام
کانتینرها میتوانند به صورت اختیاری نامگذاری شوند. وقتی یک فرزند از @container (min-width: 400px) استفاده میکند، نزدیکترین کانتینر والد را جستجو میکند. اما اگر کانتینرهای تو در تو دارید و نیاز دارید که یک کانتینر خاص را هدف قرار دهید، کانتینرهای نامگذاری شده این مشکل را حل میکنند. والد container-name: card تعریف میکند و فرزند آن را به طور صریح با @container card (min-width: 400px) جستجو میکند.
Tailwind نسخه ۴ از هر دو الگو با سینتکس تمیز پشتیبانی میکند.
سینتکس کوئری کانتینر Tailwind CSS نسخه ۴
تعریف یک کانتینر با @container
برای ایجاد یک زمینهی مهار در Tailwind نسخه ۴، ابزار @container را به عنصر والد اضافه کنید. این container-type: inline-size روی آن عنصر تنظیم میکند و آن را توسط فرزندانش قابل پرسوجو میکند.
برای کانتینرهای نامگذاری شده، از سینتکس اسلش استفاده کنید: @container/card . این کار هم container-type: inline-size و هم container-name: card روی عنصر تنظیم میکند.
مثال کد ۲: اعلانهای کانتینر
<!-- Unnamed container (queries from any descendant hit this) --> <div class="@container"> <!-- children can use @sm:, @md:, etc. --> </div>
<!-- Named container (descendants can target it specifically) --> <div class="@container/card"> <!-- children can use @sm/card:, @md/card:, etc. --> </div>این کل تنظیمات سمت والد بود. هیچ CSS سفارشی، هیچ تغییری در فایل پیکربندی برای حالت پایه وجود ندارد.
پرس و جو از کانتینر با اندازههای مختلف
زمانی که یک عنصر والد، یک عنصر کانتینر باشد، عناصر فرزند از پیشوندهای نقطه توقف کانتینر-کوئری استفاده میکنند: @sm: @md: @lg: @xl: و غیره. این پیشوندها به مقیاس تم کانتینر کوئری Tailwind نگاشت میشوند که از مقادیر مبتنی بر rem استفاده میکند. مقادیر پیشفرض موجود در مستندات Tailwind عبارتند از:
| پیشوند | حداقل عرض |
|---|---|
@3xs | ۱۶ رم (۲۵۶ پیکسل) |
@2xs | ۱۸ رم (۲۸۸ پیکسل) |
@xs | ۲۰ رم (۳۲۰ پیکسل) |
@sm | ۲۴ رم (۳۸۴ پیکسل) |
@md | ۲۸ رم (۴۴۸ پیکسل) |
@lg | ۳۲ رم (۵۱۲ پیکسل) |
@xl | ۳۶ رم (۵۷۶ پیکسل) |
@2xl | ۴۲ رم (۶۷۲ پیکسل) |
@3xl | ۴۸ رم (۷۶۸ پیکسل) |
@4xl | ۵۶ رم (۸۹۶ پیکسل) |
@5xl | ۶۴ رم (۱۰۲۴ پیکسل) |
@6xl | ۷۲ رم (۱۱۵۲ پیکسل) |
@7xl | ۸۰ رم (۱۲۸۰ پیکسل) |
توجه داشته باشید که این نقاط شکست عمداً با نقاط شکست viewport متفاوت هستند ( sm = 640px، md = 768px). نقاط شکست container کوچکتر هستند زیرا اجزا معمولاً در فضاهای باریکتری نسبت به viewportهای کامل قرار میگیرند.
برای هدف قرار دادن یک کانتینر نامگذاری شده، نام را اضافه کنید: @md/card:flex-row به این معنی است که "وقتی کانتینری به نام card حداقل 28rem عرض دارد، flex-row اعمال شود."
حالا نتیجهاش این است. آن کارت محصول خرابِ قبلی را یادتان هست؟ این هم نسخهی container-query:
مثال کد ۳ (دارایی ویروسی): کوئریهای مدیا در مقابل کوئریهای کانتینر در کنار هم
قبل: مبتنی بر Viewport (شکستگی در والدهای باریک)
<div class="max-w-sm rounded-lg border bg-white shadow"> <img src="/product.jpg" alt="Product" class="w-full rounded-t-lg md:w-48 md:rounded-l-lg md:rounded-t-none" /> <div class="p-4"> <h3 class="text-lg font-semibold md:text-xl">Wireless Headphones</h3> <p class="mt-1 text-sm text-gray-600">Premium noise-canceling audio</p> <span class="mt-2 inline-block text-lg font-bold text-indigo-600">$249</span> </div> </div>بعد: مبتنی بر کانتینر (با هر عرض والد سازگار میشود)
<!-- Parent declares itself as a container --> <div class="@container"> <div class="rounded-lg border bg-white shadow @md:flex"> <img src="/product.jpg" alt="Product" class="w-full rounded-t-lg @md:w-48 @md:rounded-l-lg @md:rounded-t-none" /> <div class="p-4"> <h3 class="text-lg font-semibold @md:text-xl">Wireless Headphones</h3> <p class="mt-1 text-sm text-gray-600">Premium noise-canceling audio</p> <span class="mt-2 inline-block text-lg font-bold text-indigo-600">$249</span> </div> </div> </div> نسخه media-query در یک نوار کناری باریک قرار میگیرد. نسخه container-query به طور خودکار سازگار میشود. وقتی والد @container به اندازه کافی پهن باشد (28rem+)، کارت به طرح افقی تغییر میکند. وقتی والد باریک باشد، صرف نظر از عرض viewport، کارت به صورت انباشته باقی میماند. این کامپوننت سرانجام رفتار واکنشگرای خود را به دست میآورد.
نقاط شکست کوئری کانتینر سفارشی
اگر مقیاس کانتینر پیشفرض Tailwind با نیازهای کامپوننت شما مطابقت ندارد، با استفاده از دستور @theme در فایل CSS خود، نقاط شکست سفارشی تعریف کنید (رویکرد پیکربندی CSS-first در Tailwind نسخه ۴):
مثال کد ۴: نقطه توقف سفارشی کانتینر
@import "tailwindcss";
@theme { --container-compact: 12rem; /* 192px - for very compact widgets */ --container-sidebar: 16rem; /* 256px - for sidebar cards */ } <div class="@container"> <!-- Switches to horizontal at just 16rem (256px) parent width --> <div class="flex flex-col @sidebar:flex-row"> <img src="/avatar.jpg" class="size-12 rounded-full" /> <p class="mt-2 @sidebar:ml-3 @sidebar:mt-0">Jane Smith</p> </div> </div> شایان ذکر است: @3xs و @2xs از قبل در مقیاس پیشفرض کانتینر Tailwind نسخه ۴ (به ترتیب ۱۶rem و ۱۸rem) وجود دارند. مثال بالا از نامهای سفارشی ( compact ، sidebar ) برای جلوگیری از نادیده گرفتن نقاط توقف داخلی استفاده میکند و مقیاس پیشفرض را در حین اضافه کردن آستانههای خاص پروژه دست نخورده نگه میدارد. این به شما امکان میدهد نقاط توقف را با آستانههای خاصی که طرحبندی کامپوننت شما نیاز به تغییر دارد، تنظیم کنید، نه اینکه با مقیاس سراسری مطابقت داشته باشد.
مرحله ۱: اجزا را شناسایی کنید، نه صفحات را
سعی نکنید کل کدبیس خود را به یکباره منتقل کنید. با بررسی اجزایی که در چندین زمینه طرحبندی ظاهر میشوند، شروع کنید. وقتی یک پروژه داشبورد را بررسی کردم، متوجه شدم که سه جزء (یک کارت آمار، یک ردیف آواتار کاربر و یک پنل اعلان) 80٪ از هکهای لغو واکنشگرای ما را تشکیل میدهند. اینها کاندیداهای مهاجرت بودند.
یک روش اکتشافی سریع: اگر یک کامپوننت تا به حال به یک کلاس مخصوص wrapper مانند sidebar-stats-card یا یک کلاس شرطی که توسط والد تغییر وضعیت داده شده است نیاز داشته باشد، به لیست مهاجرت کوئری کانتینر شما تعلق دارد.
مرحله ۲: والدها را با @container پوشش دهید
کانتینر باید والد مستقیم طرحبندی باشد که عرض موجود را کنترل میکند: یک سلول شبکه، یک پوشش نوار کناری، یک بدنه مدال، یک پنل داشبورد. @container را آنجا قرار دهید.
یک نکتهی احتیاطی: در هر <div> در نشانهگذاری خود، @container را قرار ندهید. Containment یک زمینهی قالببندی جدید روی عنصر ایجاد میکند و اگرچه تأثیر عملی آن معمولاً نامرئی است، اما میتواند بر فرزندان کاملاً موقعیتیابی شده و فروریختن حاشیه تأثیر بگذارد. مهمتر از آن، باید مطمئن شوید که عنصر کانتینر در واقع دارای اندازهی درونخطی محدود است. اگر عرض یک کانتینر محدود نباشد (مثلاً یک بلوک با عرض کامل بدون محدودیتهای max-width یا grid/flex باشد)، نقاط شکست کانتینر شما صرف نظر از زمینه، در همان آستانهها فعال میشوند. این کار کل هدف را نقض میکند.
مرحله 3: پیشوندهای Viewport را با پیشوندهای Container عوض کنید
تغییر مکانیکی ساده است: md: به @md: تبدیل میشود، lg: به @lg: تبدیل میشود و به همین ترتیب ادامه مییابد. اما مقادیر پیکسل ۱:۱ نیستند. Viewport md برابر با ۷۶۸px است. Container @md برابر با ۲۸rem (۴۴۸px) است. شما باید نقاط شکست container متفاوتی نسبت به viewport مورد استفاده خود انتخاب کنید. من متوجه شدهام که @sm (384px) و @md (448px) برای اکثر اجزای سبک کارت به نقطه مطلوب میرسند، در حالی که @lg (512px) برای بلوکهای محتوای عریضتر به خوبی کار میکند.
در اینجا یک انتقال کامل از یک کارت آمار داشبورد آورده شده است:
مثال کد ۵: مهاجرت کامل قبل/بعد
قبل: کارت آمار مبتنی بر Viewport
<!-- Stats card using viewport breakpoints --> <div class="rounded-xl border bg-white p-4 shadow-sm"> <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between"> <!-- Icon --> <div class="mb-3 flex size-10 items-center justify-center rounded-lg bg-blue-100 sm:mb-0"> <svg class="size-5 text-blue-600"><!-- chart icon --></svg> </div> <!-- Content --> <div class="sm:ml-4 sm:flex-1"> <p class="text-sm text-gray-500">Monthly Revenue</p> <p class="text-2xl font-bold text-gray-900 lg:text-3xl">$48,290</p> </div> <!-- Trend badge --> <span class="mt-2 inline-flex items-center rounded-full bg-green-100 px-2 py-1 text-xs font-medium text-green-700 sm:mt-0"> +12.5% </span> </div> </div>بعد: کارت آمار مبتنی بر کانتینر
<!-- Layout parent becomes the container --> <div class="@container"> <div class="rounded-xl border bg-white p-4 shadow-sm"> <div class="flex flex-col @sm:flex-row @sm:items-center @sm:justify-between"> <!-- Icon --> <div class="mb-3 flex size-10 items-center justify-center rounded-lg bg-blue-100 @sm:mb-0"> <svg class="size-5 text-blue-600"><!-- chart icon --></svg> </div> <!-- Content: uses @sm for layout shift, @lg for text scaling --> <div class="@sm:ml-4 @sm:flex-1"> <p class="text-sm text-gray-500">Monthly Revenue</p> <p class="text-2xl font-bold text-gray-900 @lg:text-3xl">$48,290</p> </div> <!-- Trend badge --> <span class="mt-2 inline-flex items-center rounded-full bg-green-100 px-2 py-1 text-xs font-medium text-green-700 @sm:mt-0"> +12.5% </span> </div> </div> </div> تغییرات جزئی هستند: @container در والد، sm: به @sm: lg: به @lg: تبدیل میشود. اما تفاوت رفتاری چشمگیر است. این کارت اکنون به صورت یک طرح عمودی انباشته در یک نوار کناری باریک رندر میشود و در یک پنل پهنتر به حالت افقی تغییر میکند، همه اینها بدون اینکه چیزی در مورد نمای دید (viewport) بدانید.
مرحله ۴: تست در چندین زمینه
پس از مهاجرت، کامپوننت را حداقل در سه عرض والد مختلف قرار دهید. من معمولاً در تقریباً ۲۵۰ پیکسل (نوار کناری باریک)، ۴۵۰ پیکسل (پنل متوسط) و تمام عرض آزمایش میکنم. Chrome DevTools اشکالزدایی کوئری کانتینر بسیار خوبی دارد: وقتی عنصری را با سبکهای کوئری کانتینر بررسی میکنید، DevTools مرز کانتینر را برجسته میکند و نشان میدهد که کدام نقاط شکست کانتینر فعال هستند. فایرفاکس ابزار مشابهی را در پنل طرحبندی خود ارائه میدهد.
یک نکتهی مهم که باید مراقب آن باشید: کانتینرهای تودرتو. اگر کانتینری درون یک کانتینر دیگر دارید، یک کوئری @md: روی یک فرزندِ عمیقاً تودرتو، نزدیکترین کانتینرِ جد را هدف قرار میدهد، نه لزوماً کانتینری که انتظار دارید. اینجاست که کانتینرهای نامگذاریشده ( @container/card و @md/card: ) ضروری میشوند. اگر مهاجرت شما رفتار غیرمنتظرهای ایجاد کرد، بررسی کنید که آیا یک والد میانی سهواً به یک کانتینر تبدیل شده است یا خیر.
تصمیمات مربوط به طرحبندی در سطح Viewport
کوئریهای کانتینر جایگزین کوئریهای مدیا برای همه چیز نمیشوند. کوئریهای مدیا هنوز ساختار صفحه سطح بالا را در اختیار دارند: تغییر از طرحبندی چند ستونی به پشته موبایل تک ستونی، نمایش یا پنهان کردن کشوی ناوبری، تنظیم اندازه فونتهای سراسری یا تغییر ریتم کلی فاصلهگذاری صفحه. اینها تصمیماتی در سطح viewport هستند که هیچ ارتباطی با والد یک کامپوننت خاص ندارند.
قانونی که من استفاده میکنم: طرحبندی صفحه = کوئریهای رسانهای؛ طرحبندی کامپوننت = کوئریهای کانتینر. اگر میخواهید نحوه چیدمان بخشهای اصلی صفحه را کنترل کنید، از md: و lg: استفاده کنید. اگر میخواهید نحوه تطبیق یک کامپوننت قابل استفاده مجدد با فضای موجودش را کنترل کنید، از @md: و @lg: استفاده کنید.
قانونی که من استفاده میکنم: طرحبندی صفحه = کوئریهای رسانهای؛ طرحبندی کامپوننت = کوئریهای کانتینر. اگر میخواهید نحوه چیدمان بخشهای اصلی صفحه را کنترل کنید، از md: و lg: استفاده کنید. اگر میخواهید نحوه تطبیق یک کامپوننت قابل استفاده مجدد با فضای موجودش را کنترل کنید، از @md: و @lg: استفاده کنید.
ترکیب هر دو رویکرد
Tailwind نسخه ۴ به شما امکان میدهد انواع viewport و container را در یک صفحه بدون تداخل ترکیب کنید. آنها با قوانین شرطی CSS متفاوتی کامپایل میشوند ( @media در مقابل @container ) و به طور واضح در کنار هم قرار میگیرند.
مثال کد ۶: ابزارهای Viewport + Container با هم
<!-- Page grid uses VIEWPORT breakpoints for overall layout --> <div class="grid grid-cols-1 gap-6 md:grid-cols-3">
<!-- Each grid cell is a CONTAINER for its child component --> <div class="@container"> <div class="flex flex-col @md:flex-row @md:items-center rounded-lg border p-4"> <img src="/item.jpg" class="size-16 rounded-lg @md:mr-4" /> <div> <h3 class="font-semibold">Product Title</h3> <p class="text-sm text-gray-500">$99.00</p> </div> </div> </div>
<!-- Repeat for other grid cells --> </div> در اینجا، md:grid-cols-3 یک کوئری viewport است: وقتی عرض پنجره مرورگر حداقل ۷۶۸ پیکسل باشد، شبکه سه ستون را نشان میدهد. درون هر ستون، @md:flex-row یک کوئری container است: وقتی آن سلول شبکه خاص حداقل ۴۴۸ پیکسل عرض داشته باشد، طرحبندی کارت افقی میشود. طرحبندی صفحه و طرحبندی کامپوننت به محرکهای جداگانه و مناسب پاسخ میدهند.
نکاتی در مورد عملکرد و پشتیبانی مرورگر
سازگاری مرورگرها
کوئریهای کانتینر در کروم ۱۰۵+، فایرفاکس ۱۱۰+ و سافاری ۱۶+ کار میکنند. طبق گفته Can I Use، پشتیبانی جهانی تقریباً ۹۳٪ از کاربران ردیابی شده را شامل میشود. برای اکثریت قریب به اتفاق برنامههای تولیدی که مرورگرهای همیشه سبز را هدف قرار میدهند، نیازی به polyfill نیست.
اگر مجبور به پشتیبانی از مرورگرهای قدیمیتر هستید، آزمایشگاههای گوگل کروم یک container-query-polyfill در گیتهاب نگهداری میکنند. توجه داشته باشید که polyfillها برای کوئریهای کانتینر محدودیتهای واقعی دارند: آنها ResizeObserver در پشت صحنه استفاده میکنند، که به معنای هزینه عملکرد و احتمال سوسو زدن طرحبندی در صفحات پیچیده است. برای اکثر تیمها، پاسخ عملی این است که اجازه دهند سبکهای کوئریشده توسط کانتینر به طرز دلپذیری در مرورگرهای پشتیبانینشده به طرحبندی موبایل/پیشفرض تنزل پیدا کنند.
عملکرد رندرینگ
مهار CSS در واقع برای کمک به عملکرد رندر طراحی شده است. وقتی container-type: inline-size را تنظیم میکنید، به مرورگر میگویید که اندازه درونخطی این عنصر به محتوای فرزندان آن بستگی ندارد. مرورگر میتواند محاسبات مجدد طرحبندی را به آن زیردرخت محدود کند تا اینکه کل سند را دوباره محاسبه کند.
با این اوصاف، این یک برد کامل در عملکرد نیست. تودرتو کردن دهها زمینهی مهاربندی، پیچیدگی را به درخت طرحبندی مرورگر اضافه میکند. من هرگز ندیدهام که این موضوع باعث ایجاد مشکلات قابل اندازهگیری در برنامههای دنیای واقعی با سلسله مراتب منطقی اجزا شود. اما اگر در حال ساخت چیزی مانند یک نمای درختی عمیقاً بازگشتی هستید که در آن هر گره یک ظرف است، قبل از فرض آزاد بودن مهاربندی، پروفایل را بررسی کنید. برای معماریهای CSS مبتنی بر مؤلفهی معمولی با چند لایهی تودرتو، تأثیر عملکرد از ناچیز تا کمی مثبت متغیر است.
مهار CSS در واقع برای کمک به عملکرد رندر طراحی شده است. وقتی container-type: inline-size را تنظیم میکنید، به مرورگر میگویید که اندازه درونخطی این عنصر به محتوای فرزندان آن بستگی ندارد. مرورگر میتواند محاسبات مجدد طرحبندی را به آن زیردرخت محدود کند تا اینکه کل سند را دوباره محاسبه کند.
نکات کلیدی و مراحل بعدی
سه ایده برای به خاطر سپردن این موضوع:
کوئریهای کانتینر به کامپوننتها اجازه میدهند صرف نظر از محل قرارگیریشان در طرحبندی، رفتار واکنشگرای خود را داشته باشند . این کامپوننت، عرض والد خود را پرسوجو میکند، نه عرض نمایشگر (viewport)، و این عدم تطابقی را که بیش از یک دهه طراحی واکنشگرا را آزار داده بود، از بین میبرد.
Tailwind CSS نسخه ۴، پذیرش را ساده میکند. @container را به یک والد اضافه کنید، md: را در فرزندان با @md: جایگزین کنید، تمام. کانتینرهای نامگذاری شده ( @container/name و @md/name: ) سناریوهای تو در تو را به طور تمیز مدیریت میکنند. نقاط توقف سفارشی چند خط در یک بلوک @theme را اشغال میکنند.
پرسوجوهای رسانهای هنوز از بین نرفتهاند. آنها به طرحبندی سطح صفحه، جایی که هنوز به آن تعلق دارند، محدود شدهاند. الگوی برنده، پرسوجوهای viewport برای ساختار صفحه و پرسوجوهای container برای اجزای داخلی کامپوننت است.
حرکت بعدی شما این است: یک کامپوننت پرکاربرد در پروژه فعلی خود انتخاب کنید، چیزی که حداقل در دو زمینه طرحبندی مختلف نمایش داده شود. آن را با استفاده از چهار مرحله بالا منتقل کنید. آن را در یک نوار کناری قرار دهید. ببینید چطور سازگار میشود. همین یک آزمایش، نحوه تفکر شما در مورد طراحی واکنشگرا را تغییر خواهد داد.
برای مطالعه بیشتر، مستندات Tailwind CSS container queries مرجع قطعی برای سینتکس و پیشفرضهای utility است. مشخصات CSS Containment Module Level 3، ویژگی اساسی پلتفرم را با جزئیات فنی کامل پوشش میدهد. و Can I Use جایی است که میتوانید قبل از ارسال به مرحله تولید، تعداد پشتیبانی مرورگرهای فعلی را بررسی کنید.





ارسال نظر