توسعه فرانت‌اند

CSS Container Queries: واکنش‌گرایی واقعی

تفاوت میزبان و مؤلفه، inline-size و نام کانتینر، پایه خوانا و شرط اندازه با دو کارت کامل در فضاهای متفاوت بدون وابستگی.

1404/12/04 3 دقیقه مطالعه 1,437 بازدید

یک کارت در ستون اصلی صفحه جا دارد، اما همان کارت در sidebar باریک دیده می‌شود. اگر تغییر چیدمان فقط با عرض viewport انجام شود، هر دو ممکن است ظاهر پهن بگیرند چون پنجره بزرگ است. Container Query امکان می‌دهد شرط به فضای کانتینر مربوط باشد. این قابلیت برای مؤلفه‌های قابل استفاده در جایگاه‌های متفاوت مفید است، ولی استقلال کامل محتوا و رفتار را به‌تنهایی تضمین نمی‌کند.

ابتدا مشخص کنید کارت در فضای کم چه چیزی را تغییر می‌دهد. اگر فقط عرض آیتم‌ها سیال است، شاید Grid یا Flexbox ذاتی کافی باشد. اگر رابطه بخش‌ها عوض می‌شود، مثلاً توضیح و جزئیات از کنار هم به زیر هم می‌روند، شرط مبتنی بر کانتینر معنی روشن‌تری دارد. ابزار را از رفتار لازم انتخاب کنید؛ جدید بودن یک قابلیت دلیل استفاده در همه بخش‌های صفحه نیست.

کانتینر پرسش با عنصر تغییرکننده فرق دارد

راهنمای Container Queries در MDN مفهوم query container و قواعد داخل آن را توضیح می‌دهد. در size query، یک ancestor مناسب اطلاعات اندازه را فراهم می‌کند و قواعد می‌توانند descendantها را تغییر دهند. عبارت «والد» اگر به معنی parent مستقیم گرفته شود همیشه دقیق نیست. انتخاب کانتینر به نوع و نام و رابطه عناصر بستگی دارد.

در طراحی نمونه، wrapper مسئول ارائه اندازه است و کارت فرزند آن ظاهر تازه می‌گیرد. شرط نباید به این انتظار وابسته باشد که همان عنصر اندازه خودش را query و با تغییر ظاهر، اندازه خود را دوباره تعیین کند. جدا کردن میزبان و مؤلفه این رابطه را روشن‌تر می‌کند. نام کلاس‌ها هم باید همین مسئولیت‌ها را بیان کنند تا container-type به اشتباه روی عنصر نامناسب گذاشته نشود.

inline-size دامنه اندازه را مشخص می‌کند

مرجع container-type تفاوت نوع‌ها و اثر containment را توضیح می‌دهد. inline-size برای query اندازه در محور inline کاربرد دارد. این محور در حالت نوشتار معمول با عرض مرتبط است، اما بیان منطقی آن با جهت و writing mode سازگارتر است. انتخاب size برای هر دو محور مسئولیت بیشتری دارد و نباید بدون توجه به تعیین ارتفاع انجام شود.

Containment می‌تواند رابطه اندازه محتوا و میزبان را تغییر دهد. اگر والد برای اندازه گرفتن کاملاً به فرزند وابسته است، افزودن نوع container ممکن است نتیجه‌ای متفاوت بسازد. اندازه میزبان باید از قرارداد چیدمان معلوم شود؛ مثل ستون Grid یا عرض محدود wrapper. Container Query مسئله تعیین فضای خود والد را به‌طور خودکار حل نمی‌کند. این بخش باید در ساختار صفحه طراحی شود.

نمونه کامل در دو میزبان

فایل زیر را با نام container-card.html و UTF-8 ذخیره و به صورت HTML باز کنید. همه CSS داخل style است و تصویر، JavaScript یا بسته خارجی وجود ندارد. دو میزبان با حداکثر عرض‌های متفاوت همان ساختار کارت را دارند. هر میزبان container با نام course است. کارت در فضای دست‌کم ۳۲rem به دو ستون تبدیل می‌شود و در فضای کمتر، بخش‌ها زیر هم می‌مانند.

<!doctype html>
<html lang="fa" dir="rtl"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>کارت در دو میزبان</title><style>*{box-sizing:border-box}body{margin:0;background:#f2f4f7;color:#17243b;font-family:Tahoma,Arial,sans-serif;line-height:1.9}main{width:min(60rem,calc(100% - 2rem));margin:auto;padding-block:2rem}.host{container:course / inline-size;margin-block:1rem}.wide{width:min(100%,48rem)}.narrow{width:min(100%,22rem)}.card{display:grid;grid-template-columns:minmax(0,1fr);background:white;border:1px solid #91a1b7;border-radius:.6rem;padding:1.25rem;gap:1rem;overflow-wrap:anywhere}.card-main,.card-details{min-width:0}.card h3{margin:0;font-size:1.2rem}.card p{margin-block:.5rem}.card-details{border-block-start:1px solid #c3cddd;padding-block-start:1rem}.card a{color:#173f78}.card a:focus-visible{outline:3px solid #946000;outline-offset:3px}@container course (min-width:32rem){.card{grid-template-columns:minmax(0,1.3fr) minmax(0,1fr)}.card-details{border-block-start:0;padding-block-start:0;border-inline-start:1px solid #c3cddd;padding-inline-start:1rem}}</style></head><body><main><h1>یک ساختار در دو فضا</h1><section aria-labelledby="wide-title"><h2 id="wide-title">میزبان پهن‌تر</h2><div class="host wide"><article class="card"><div class="card-main"><h3>راهنمای ناوبری</h3><p>برچسب مقصد و مسیر فعال را روشن کنید.</p><a href="https://tarahestan.com/magazine/navigation-menu-design-principles">مطالعه راهنمای ناوبری</a></div><div class="card-details"><p>موضوع: تجربه کاربری</p><p>نوع: مقاله آموزشی</p></div></article></div></section><section aria-labelledby="narrow-title"><h2 id="narrow-title">میزبان باریک‌تر</h2><div class="host narrow"><article class="card"><div class="card-main"><h3>راهنمای ناوبری</h3><p>برچسب مقصد و مسیر فعال را روشن کنید.</p><a href="https://tarahestan.com/magazine/navigation-menu-design-principles">مطالعه راهنمای ناوبری</a></div><div class="card-details"><p>موضوع: تجربه کاربری</p><p>نوع: مقاله آموزشی</p></div></article></div></section></main></body></html>

حالت پایه یک ستون است. بنابراین در محیطی که query اندازه را اجرا نکند، محتوا همچنان قابل خواندن و لینک قابل استفاده است. شرط فقط رابطه دو بخش card-main و card-details را عوض می‌کند. تعداد محتوا در هر کارت ثابت می‌ماند و چیزی در فضای باریک حذف نشده است. فاصله و border نیز بر اساس همان چیدمان تنظیم می‌شوند تا جدا شدن بخش‌ها معنی قابل فهم داشته باشد.

نام کانتینر برای قرارداد روشن

مرجع container-name امکان نام‌گذاری کانتینر را شرح می‌دهد. نام کمک می‌کند شرط به کانتینر مناسب مربوط شود، به‌ویژه وقتی چند لایه وجود دارند. نام عمومی که در همه بخش‌ها تکرار می‌شود می‌تواند ابهام بسازد. برای سیستم طراحی، نام و دامنه باید قرارداد باشند؛ تغییر آن بخشی از API ظاهری مؤلفه محسوب می‌شود.

نام‌گذاری به معنی اتصال مستقیم به یک id ثابت نیست. هنوز رابطه ancestry و نوع query اهمیت دارد. اگر کارت به ساختار دیگری منتقل می‌شود، بررسی کنید میزبان مناسب در آن مسیر وجود دارد. مؤلفه‌ای که container لازم ندارد ممکن است فقط حالت پایه را نشان دهد. این می‌تواند fallback منطقی باشد، ولی باید در مستندات مشخص شود تا تیم نتیجه را خطای تصادفی تصور نکند.

Breakpoint از محتوا می‌آید

عدد ۳۲rem در نمونه انتخاب آموزشی برای دو بخش متنی است. آن را به قانون همه کارت‌ها تبدیل نکنید. حد تغییر را با عنوان واقعی، توضیح و کنترل‌ها تعیین کنید. اگر دو ستون پیش از جا شدن محتوا ایجاد شوند، عبارت‌ها فشرده و خواندن دشوار می‌شود. اگر تغییر دیر انجام شود، فضای اضافه ممکن است بی‌استفاده بماند. هدف، رابطه مناسب محتوا با فضای واقعی است.

مقدار rem با اندازه پایه متن مرتبط است و این رابطه در بزرگ‌نمایی می‌تواند به رفتار کمک کند، ولی استفاده از آن به‌تنهایی تضمین خوانایی نیست. متن بلند، رشته بدون فاصله و اندازه قلم تغییرکرده باید در قرارداد محتوا دیده شوند. در نمونه، min-width صفر و overflow-wrap برای موارد طولانی وجود دارد. ارتفاع ثابت هم استفاده نشده تا متن اضافی از دست نرود.

Media Query هنوز نقش خودش را دارد

Media Query می‌تواند به ویژگی‌های محیط و ترجیح مخاطب مانند کاهش حرکت مربوط باشد؛ Container Query به همه این سؤال‌ها پاسخ نمی‌دهد. حتی برای اندازه، بعضی تصمیم‌های ساختار کل صفحه می‌توانند viewportمحور بمانند. انتخاب ابزارها رقابت بر سر «واقعی» بودن واکنش‌گرایی نیست. راهنمای چیدمان ذاتی درباره کاهش breakpointهای اضافی و حفظ شرط‌های لازم توضیح دارد.

مؤلفه ممکن است از Grid سیال برای تعداد ستون و از Container Query برای تغییر جزئیات استفاده کند. این ترکیب زمانی مناسب است که هر قاعده نقش روشن داشته باشد. اگر هم Media و هم Container روی یک ویژگی اثر می‌گذارند، اولویت cascade را مشخص کنید. قاعده‌های متضاد در چند فایل می‌توانند نتیجه را به ترتیب import وابسته کنند و نگهداری را دشوار سازند.

Query اندازه با Style Query یکسان نیست

مرجع @container شکل‌های مختلف query و وضعیت پشتیبانی را شرح می‌دهد. شرط اندازه و شرط مربوط به style دامنه یکسانی ندارند. دیدن نمونه‌ای از custom property نباید باعث شود پشتیبانی همه ویژگی‌های style در همه محیط‌ها فرض شود. برای قابلیت مورد استفاده، سازگاری همان بخش را بررسی و نسخه محیط هدف را ثبت کنید.

واحدهای مبتنی بر کانتینر نیز می‌توانند در اندازه‌ها استفاده شوند، ولی مرجع آن‌ها باید معلوم باشد. اگر هیچ کانتینر مناسب وجود ندارد، رفتار fallback را از مستندات بخوانید و روی قرارداد نامشخص تکیه نکنید. ابزارهای جدید امکان‌های متفاوتی می‌دهند و بهتر است هرکدام جدا توضیح داده شوند. نمونه این مقاله فقط size query ساده دارد و Style Query یا واحد کانتینر را شبیه‌سازی نمی‌کند.

ساختار و دسترس‌پذیری

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

اطلاعات ضروری را در اندازه کم حذف نکنید فقط چون فضای محدودتر است. مخاطب موبایل هم ممکن است به همان شرط یا قیمت نیاز داشته باشد. کوتاه‌سازی باید معنی را حفظ کند و دسترسی به جزئیات معلوم باشد. راهنمای کارت درباره اطلاعات لازم برای انتخاب توضیح دارد. Container Query ابزار تنظیم ظاهر است و اولویت محتوا را باید طراح و تیم محصول تعیین کنند.

نگهداری نمونه در سیستم طراحی

حد تغییر، نام کانتینر و ساختار فرزندهای لازم را ثبت کنید. selector بدون markup متناظر راهنمای عملی کامل نیست. اگر wrapper تازه اضافه می‌شود، رابطه descendant و قواعد مربوط باید مرور شوند. در راهنمای :has نیز همین اهمیت رابطه ساختاری دیده می‌شود، ولی :has درباره وجود و وضعیت عناصر است و جای شرط اندازه را نمی‌گیرد.

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

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

واکنش به این مقاله

اشتراک‌گذاری این مقاله:
دیدگاه‌ها 0
۰ / ۲۰۰۰

هنوز دیدگاهی ثبت نشده

اولین نفری باشید که نظر می‌دهد!