اخبار وب

Container Queries و طراحی واکنش‌گرای واقعی

تفاوت Container Query و Media Query، انتخاب query container و نمونه مستقل HTML و CSS برای کارت در ستون اصلی و Sidebar.

1405/01/08 3 دقیقه مطالعه 621 بازدید
Container Queries و طراحی واکنش‌گرای واقعی

Container Queries اجازه می‌دهند style بخشی از رابط با فضای container مناسب آن هماهنگ شود. یک کارت مقاله ممکن است در ستون اصلی جای فراوان و در sidebar جای کمی داشته باشد، در حالی که viewport در هر دو حالت یک اندازه است. Media Query عرض صفحه را می‌بیند؛ Size Container Query به اندازه container تعیین‌شده نگاه می‌کند. این تفاوت برای componentی که در چند چیدمان استفاده می‌شود کاربردی است.

Container Query به معنی تصمیم خودکار هر component بر اساس هر والد نیست. باید یک ancestor مناسب را به عنوان query container تعریف کنید و قواعد فرزند را با آن هماهنگ کنید. درصد پوشش مرورگر بدون منبع و تاریخ که در نسخه قبلی مطلب آمده بود حذف شده است. راهنمای Container Queries و جدول compatibility همان ویژگی، مرجع بررسی پشتیبانی‌اند.

عرض viewport مسئله همه componentها نیست

در یک صفحه دسکتاپ، کارت در sidebar می‌تواند از کارت همان صفحه در بخش اصلی کوچک‌تر باشد. اگر فقط در عرض بزرگ viewport چیدمان افقی را فعال کنید، هر دو کارت همان قاعده را می‌گیرند و نمونه باریک ممکن است فشرده شود. Size Query کمک می‌کند تغییر بر اساس فضایی باشد که واقعاً به کارت داده شده است. محل استفاده دیگر لازم نیست فقط برای عرض، prop تازه‌ای به component بدهد.

Media Query همچنان نقش دارد. ساختار کل صفحه، ترجیح reduced motion یا color scheme به ویژگی‌هایی متفاوت از عرض container مربوط‌اند. انتخاب این دو ابزار رقابت برای حذف دیگری نیست. می‌توان صفحه را با Media Query به دو ستون تبدیل کرد و کارت داخل هر ستون را با Container Query تنظیم کرد. هر قاعده باید سؤال مربوط به خودش را پاسخ دهد.

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

Container را روی wrapper مناسب تعریف کنید

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

قاعده query برای style عنصرهای زیرمجموعه container به کار می‌رود. عنصر نمی‌تواند صرفاً با query اندازه خودش، همان اندازه را به شکل چرخه‌ای تعیین کند. wrapper و کارت را در نمونه جدا نگه داشته‌ایم تا این رابطه دیده شود. container-name هم انتخاب container مناسب را در ساختارهای تو در تو روشن می‌کند. مرجع container-name قرارداد نام‌گذاری را شرح می‌دهد.

اگر component در wrapper جدیدی قرار می‌گیرد، بررسی کنید container واقعی کدام ancestor است. نزدیک‌ترین container با شرایط مناسب ممکن است با انتظارتان فرق داشته باشد. نام روشن کمک می‌کند query به ظرف مورد نظر مربوط بماند، ولی نام باید در CSS تعریف شده باشد. استفاده از یک اسم دلخواه در @container بدون تعریف متناظر، نمونه را فعال نمی‌کند.

نمونه کامل دو کارت در فضای متفاوت

نمونه زیر یک فایل مستقل است. آن را با نام index.html ذخیره کنید و در مرورگر دارای پشتیبانی Size Container Queries باز کنید. HTML و CSS در همان فایل هستند و به تصویر، فونت خارجی یا JavaScript نیاز ندارند. کارت اصلی و کارت sidebar محتوای آموزشی مشابه دارند، ولی wrapperهای آن‌ها عرض متفاوتی می‌گیرند.

<!doctype html>
<html lang="fa" dir="rtl">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>کارت و Container Query</title>
<style>
body { margin: 0; font-family: sans-serif; line-height: 1.8; background: #f2f4f7; color: #18212b; }
main { max-inline-size: 72rem; margin-inline: auto; padding: 1rem; }
.page-grid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 1rem; }
.card-slot { container-type: inline-size; container-name: article-card; min-inline-size: 0; }
.card { display: grid; border: 1px solid #b7c3d0; background: white; border-radius: .6rem; overflow: hidden; }
.visual { display: grid; place-items: center; padding: 2rem; background: #dde8f5; font-weight: bold; }
.card-content { min-inline-size: 0; padding: 1rem; overflow-wrap: anywhere; }
.card h2 { margin-block-start: 0; }
a { color: #174c87; }
@container article-card (min-width: 30rem) { .card { grid-template-columns: 1fr 2fr; } }
@media (max-width: 50rem) { .page-grid { grid-template-columns: 1fr; } }
</style></head>
<body><main>
<h1>یک کارت در دو فضای متفاوت</h1>
<div class="page-grid">
  <section class="card-slot" aria-label="ستون اصلی">
    <article class="card"><div class="visual">یادداشت آموزشی</div><div class="card-content"><h2>ساخت component قابل استفاده در چند چیدمان</h2><p>این کارت بر اساس فضای ظرف خود تغییر ساختار می‌دهد.</p><a href="#details">توضیح مثال</a></div></article>
  </section>
  <aside class="card-slot" aria-label="ستون کناری">
    <article class="card"><div class="visual">یادداشت آموزشی</div><div class="card-content"><h2>ساخت component قابل استفاده در چند چیدمان</h2><p>این کارت بر اساس فضای ظرف خود تغییر ساختار می‌دهد.</p><a href="#details">توضیح مثال</a></div></article>
  </aside>
</div>
<section id="details"><h2>توضیح</h2><p>در ظرف پهن، کارت دو ستون دارد. حالت پایه آن تک‌ستونه است.</p></section>
</main></body></html>

کلاس page-grid چیدمان کلی را می‌سازد. کلاس card-slot query container با نام article-card است. خود article کلاس card دارد و مستقیم داخل wrapper قرار گرفته است. وقتی اندازه inline ظرف از 30rem بیشتر شود، قاعده query کارت را دو ستونه می‌کند. تعداد دو کارت در markup با توضیح همین مثال هماهنگ است؛ کارت یا تصویر پنهانی لازم نیست.

بلوک visual در مثال فقط یک بخش متنی با رنگ زمینه است تا ستون چیدمان دیده شود. این عنصر تصویر یا placeholder عکس محصول نیست. لینک کارت به بخش details همین سند می‌رود و لینک ساختگی بیرونی ندارد. اگر در پروژه واقعی تصویر اضافه می‌کنید، ابعاد، alt و روش بارگذاری آن باید بر اساس تصویر واقعی تعیین شود.

قاعده Media Query در 50rem صفحه را تک‌ستونه می‌کند، ولی قانون خود کارت همچنان از ظرف می‌آید. بنابراین در صفحه‌ای کوچک‌تر از breakpoint کلی، ممکن است کارت پهن‌شده رفتار متفاوتی از sidebar سابق داشته باشد. این رفتار از ترکیب دو قرارداد مستقل می‌آید. هر breakpoint را با سؤال مربوط به خودش در توضیح کد نگه دارید.

Baseline را پیش از Query طراحی کنید

style پایه کارت در نمونه تک‌ستونه و خواناست. اگر مرورگر قاعده query را نشناسد، همین حالت باقی می‌ماند. برای قابلیت‌های جدید، baseline باید وظیفه اصلی را حفظ کند. لازم نیست تمام حالت‌های پیشرفته با polyfill بازسازی شوند، مگر محصول چنین نیاز مشخصی داشته باشد. fallback مناسب از محتوای همان component شروع می‌شود.

Container Query را راه رفع تمام مشکلات overflow ندانید. کلمه طولانی، جدول یا عنصر با عرض ثابت می‌تواند همچنان بیرون بزند. min-inline-size و قواعد شکستن متن به این مسئله مربوط‌اند. اگر قاعده پایه یک مقدار ثابت نامناسب دارد، اضافه کردن query فقط مشکل را در محدوده دیگری پنهان می‌کند. ابتدا اندازه‌های intrinsic و constraints عنصر را بررسی کنید.

در محتواهای چندزبانه، طول متن و جهت متفاوت است. استفاده از logical propertyها مانند padding-inline به حفظ قرارداد RTL و LTR کمک می‌کند. مقاله CSS Logical Properties ادامه مرتبطی برای این بخش است. تغییر جهت صفحه نباید شما را مجبور کند نام margin-left را در چند فایل دستی دنبال کنید.

واحدهای وابسته به container را با حد مشخص به کار ببرید

واحدهایی مانند cqi به اندازه container مربوط می‌شوند. مرجع واحدهای Container Query تعریف آن‌ها را ارائه می‌کند. این ابزار برای اندازه‌گذاری سیال مفید است، اما نباید متن را در container باریک به اندازه غیرقابل خواندن برساند. حداقل و حداکثر با نیاز خواندن باید روشن باشد.

برای typography، یک clamp محدود می‌تواند تغییر اندازه را کنترل کند، ولی مقیاس‌پذیری متن و zoom همچنان باید لحاظ شوند. اندازه heading در رابطه با بدنه و طول عنوان معنا پیدا می‌کند. مقاله CSS clamp و Fluid Typography این تصمیم را با جزئیات بیشتری دنبال می‌کند. تغییر چند property با یک نسبت، خودبه‌خود سلسله‌مراتب بصری مناسبی نمی‌سازد.

Style Query را با Size Query یکی نگیرید

خانواده Container Queries قابلیت‌های متفاوتی دارد و پشتیبانی همه آن‌ها یکسان نیست. Size Query، Style Query و ویژگی‌های جدیدتر را جدا بررسی کنید. مثال این مقاله از اندازه inline استفاده می‌کند و درباره پشتیبانی تمام انواع query ادعایی ندارد. نام کلی قابلیت در یک خبر، جدول compatibility دقیق همان syntax را جایگزین نمی‌کند.

اگر برای theme یا context از custom property استفاده می‌کنید، مالکیت آن مقدار باید مشخص باشد. component نباید به مقدار پنهانی در یک ancestor ناشناخته وابسته شود و در محل دیگری بی‌توضیح ظاهر متفاوت بگیرد. قرارداد محیط، حتی در CSS هم نیاز به نام و معنای روشن دارد. این موضوع برای Design System با چند محصول مصرف‌کننده مهم‌تر می‌شود.

مرز component را قابل استفاده نگه دارید

استقلال component به معنی نداشتن هیچ فرض نیست. کارت هنوز به داده مناسب، ظرف دارای فضای کافی و قواعد theme نیاز دارد. هدف این است که فرض‌ها محدود و قابل توضیح باشند. اگر هر محل استفاده مجبور است wrapper خاصی بسازد، این قرارداد را در API و نمونه ثبت کنید. شرطی که فقط نویسنده CSS می‌داند، بعداً به خطای مصرف‌کننده تبدیل می‌شود.

برای مستند کردن حالت‌ها، همان کارت را در ظرف باریک، متوسط و پهن نشان دهید. داده نمونه یکسان بماند تا تفاوت چیدمان روشن باشد. اگر هم‌زمان متن را کوتاه کنید، معلوم نیست بهبود از query آمده یا داده ساده‌تر شده است. مقاله Storybook و توسعه component به ثبت این محیط‌ها مربوط است.

تعداد queryها را با حالت‌های معنادار هماهنگ کنید. چندین breakpoint نزدیک که برای تک‌تک عنوان‌های فعلی اضافه شده‌اند نگهداری را دشوار می‌کنند. رفتار انعطاف‌پذیر پایه و چند تغییر ساختاری واضح، اغلب قرارداد قابل فهم‌تری می‌سازند. استثنا واقعی را با دلیل مشخص ثبت کنید، نه با عددی که فقط یک screenshot را درست می‌کند.

قدم بعدی، انتخاب componentی است که امروز در دو فضای متفاوت مشکل دارد. HTML و wrapper واقعی را نگه دارید، رفتار پایه را خوانا کنید و فقط تغییر ساختاری لازم را به اندازه container وصل کنید. سپس محل‌های مصرف را با همان قرارداد مستند کنید. نتیجه باید کارت قابل استفاده‌تری در فضای واقعی باشد، نه صرف استفاده از syntax تازه CSS.

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

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

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

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