- ۱ اصول
- ۲ Flexbox
- ۳ شبکه و زیرشبکه
- ۴ پُرسمان محتوی
- ۵ همپوشانیهای بومی، موقعیتیابی لنگر، و زمینههای پشتهسازی
- ۶ ردیابی سرریز و پایداری چیدمان
- ۷ مکانیک نمای دید و توزیع قطعه
- ۸ خطوط جدولی (یا همان آجرچینی)
۱ مبانی
درصورت امکان، برای عملکرد بهتر، به موتور چیدمان مرورگر تکیه کنید. پیشاز متوسل شدن به ابعاد کدنویسیشده یا پرسمانهای رسانهای پیچیده، از اندازهگذاری ذاتی، ویژگیهای منطقی، و aspect-ratio استفاده کنید.
۱.۱ از کدام حالت چیدمان استفاده شود؟
درخت تصمیمگیری را از بالا به پایین بررسی کنید و در اولین تطابق متوقف شوید. توجه داشته باشید که چیدمانها میتوانند در یکدیگر تودرتو شوند و هر تصمیم براساس مورد استفاده برای آن ظرف است.
- آیا ردیف یا ستون سادهای از موارد است؟ از flexbox استفاده کنید — یکبعدی، محتوا-محور، محتوا در امتداد یک محور توزیع میشود.
- آیا عنصر تودرتو باید با شیارهای شبکه پدربزرگش همراستا باشد؟ از subgrid استفاده کنید — دوبعدی، اولویت با رابطه، دستههای هدف والد را به ارث میبرد تا نوهها بتوانند در سراسر خواهر و برادرها تراز شوند.
- آیا ساختار صفحه یا مؤلفه پیچیده است و ردیفها و ستونها را شامل میشود؟ از شبکه استفاده کنید — دوبعدی، اولویت با چیدمان، شما اسکلت را تعریف میکنید و محتوا آن را پر میکند.
- آیا محتوا جریان طولانی نثر است که باید به ستونهای متوازن تقسیم شود؟ از چندستونی استفاده کنید — جریان یکبعدی، سبک روزنامه.
- آیا اقلام ارتفاعهای مختلفی دارند که باید محکم بستهبندی شوند؟ امروز از grid با
grid-auto-flow: denseاستفاده کنید؛ فقط زمانی به سراغ masonry بومی (یا «grid lanes») بروید که در هدف Baseline شما عرضه شده باشد (§8 را ببینید). - آیا عنصری باید بالای صفحه شناور باشد و ازنظر فضایی به یک راهانداز متصل بماند، حتی در سراسر مرزهای DOM یا زمینههای پشتهسازی؟ از موقعیتیابی لنگر استفاده کنید —
anchor-nameروی راهانداز،position-anchorروی رونهاد (§۵ را ببینید).
۱.۲ اصول کاری
- از ویژگیهای منطقی (
inline-size،block-size،margin-inline،padding-block،inset-inline-start) برای ابعاد و فاصلهگذاری چیدمان استفاده کنید — برای پوشش کامل، CSS: معماری مدرن را ببینید. - مدل ذهنی «محتوا-اول» درمقابل «چیدمان-اول» را اعمال کنید: flexbox زمانی که موارد جریان را دیکته میکنند، grid زمانی که ابتدا اسکلت را تعریف میکنید.
- از خلاصه نویسیهای
place-*(place-content،place-items،place-self) برای تراز کردن در هر دو محور در یک اعلان استفاده کنید. - قبلاز
width/heightثابت، از اندازهگذاری ذاتی (min-content،max-content،fit-content()) و قطعههای انعطافپذیر (fr،minmax()) استفاده کنید — پرسوجوهای رسانهای کمتر، چیدمانهای انعطافپذیرتر. - از
overflow: hiddenبرای پوشاندن مشکلات چیدمان استفاده نکنید — آنها را در منبع برطرف کنید. برای مثال، برخی عناصر جایگزینشده مثل<canvas>،<img>،<svg>،<video>،<iframe>بهطور پیشفرض ازdisplay: inlineاستفاده میکنند که میتواند در برخیاز چیدمانها فاصله ایجاد کند. بهجای برش دادن فاصله باoverflow، آن را با اعمال مقدار block display-outside (مثلاًdisplay: block،grid،flex، و غیره) بردارید. - از
aspect-ratioبرای رزرو فضا برای رسانه و جلوگیری از تغییر طرحبندی قبلاز بار شدن داراییها استفاده کنید.
.sidebar { inline-size: max-content; } /* Size to longest unbreakable token. */
.main-content { inline-size: fit-content; } /* Grow to available space, no further. */
.media { aspect-ratio: 16 / 9; inline-size: 100%; block-size: auto; }
body.centered { display: grid; place-content: center; min-block-size: 100dvb; }
برای
calc-size()و اندازهگذاری درونی با آگاهی از محدودیت، به محاسبه با اندازههای درونی مراجعه کنید.
۲ چارگوش انعطافپذیر
چیدمان یکبعدی — موارد در امتداد یک محور اصلی با تراز روی محور متقاطع جریان دارند. از آن برای نوارهای پیمایش، نوارهای ابزار، ردیفهای موارد، و هرگونه توزیع تکردیفی یا تکستونی استفاده کنید.
بایدها:
- بافتی با
display: flexایجاد کنید و محور اصلی را باflex-direction(rowپیشفرض) تنظیم کنید. - هرگاه احتمال سرریز وجود دارد، از
flex-wrap: wrapاستفاده کنید —nowrapبدونoverflow: auto/hiddenدر دریچههای دید باریک سرریز خواهد شد. - لایه
flex-wrap: balanceبعدازflex-wrap: wrapدر ردیفهای پیچیدهشده موارد فشرده (مانند ابرهای برچسب، قرصهای فیلتر، گروههای دکمه، یا پیوندهای پیمایش) برای توزیع یکنواخت موارد در خطوط و جلوگیری از وجود یک مورد یتیم در ردیف نهایی؛ مرورگرهای بدون پشتیبانی بهwrapبرمیگردند. - از خلاصه
flex<grow> <shrink> <basis>(مثلاًflex: 1 1 250px) در موارد استفاده کنید، بهجای اینکهflex-grow/flex-shrink/flex-basisرا بهصورت جداگانه تنظیم کنید. - برای فاصله بین موارد، بهجای حاشیههای فرزند از
gap(یاrow-gap/column-gap) استفاده کنید. - تراز موقعیتی را با
safe(مثلاًalign-items: safe center) پیشوند کنید تا وقتی محفظه باریکتر از محتوای آن است، محتوای قابلتمرکز بریده نشود. - بااستفاده از
margin-inline-start: auto(یاmargin-block-start: auto)، یک مورد را به انتهای محور اصلی فشار دهید — این دریچه فرار استاندارد است. - لغو همترازی محور متقاطع برای هر مورد با
align-self. - از
align-itemsبرای قرار دادن همه موارد در مرکز محور متقاطع استفاده کنید؛ ازmargin: autoبرای یک مورد استفاده کنید تا آن را بهطور مستقل در مرکز هر دو محور قرار دهید؛ ازalign-contentفقط زمانی استفاده کنید که محفظه پیچیده شده باشد و فضای اضافی در ردیفها داشته باشد. min-inline-size: 0(یاmin-width: 0) را روی موارد flex که حاوی محتوای طولانی نشکستنی (نشانیهای وب، کد، رشتههای طولانی) هستند تنظیم کنید — موارد flex بهطور پیشفرض به کمتر از اندازه محتوایشان کوچک نمیشوند و این باعث سرریز میشود.
این کارها را نکنید:
- Don't reach for
justify-selfon flex items — it only works on grid, block, and absolutely-positioned layouts. بهجای آن از حاشیههای خودکار استفاده کنید. - از
orderیاflex-direction: *-reverseبرای تغییر ترتیب محتوای تعاملی استفاده نکنید. آنها فقط ترتیب دیداری را تغییر میدهند؛ ترتیب DOM همچنان تمرکز متوالی را هدایت میکند، بنابراین جریان زبانه صفحهکلید با آنچه کاربر میبیند مطابقت نخواهد داشت. -
space-around(نیمفاصله در انتها) را باspace-evenly(فاصلههای مساوی قبل، بین، و بعد) اشتباه نگیرید. - چرخش محور را فراموش نکنید: وقتی
flex-direction: column،justify-contentروی محور بلاک تراز میشود وalign-itemsروی محور درونخطی تراز میشود — برعکس پیشفرض. - اندازه ظرف و فرزندان آن را طوری تنظیم نکنید که یکدیگر را پر کنند — این کار منبع رایج سرریز و نتایج غافلگیرکننده است. به یک طرف اندازه مشخصی بدهید.
flex-basisوwidth/inline-sizeرا روی یک مورد تنظیم نکنید —flex-basisدر بافت flex اولویت دارد وwidthنادیده گرفته میشود. ازflex-basis(یا خلاصهflex) بهعنوان منبع واحد حقیقت برای اندازهگذاری موارد flex استفاده کنید.
.card-grid { display: flex; flex-flow: row wrap; gap: 1rem; }
.card-item { flex: 1 1 250px; } /* grow, shrink, basis */
.card-item-action { margin-inline-start: auto; } /* Push to main-axis end. */
.toolbar { display: flex; align-items: safe center; }
.tag-list { display: flex; flex-wrap: wrap; flex-wrap: balance; gap: 0.5rem; }
۳ شبکه و زیرشبکه
چیدمان دوبعدی — ردیفها و ستونها را بهطور صریح تعریف کنید یا اجازه دهید موتور آنها را استخراج کند. Subgrid به یک شبکه تودرتو اجازه میدهد تا مسیرهای والد خود را به ارث ببرد تا نوهها در بین خواهر و برادرها همسو شوند.
انتخاب کردن عارضههای شبکه:
- آیا دقیقاً میدانید به چند ستون نیاز دارید؟
- بله — از دستههای هدف صریح (
grid-template-columns: 200px 1fr،repeat(3, 1fr)، و غیره) استفاده میکنم - آیا ستونهای مختلف به اندازههای مختلف نیاز دارند (نوار کناری + اصلی، سرایند شامل همه)؟ → از
grid-template-areasبرای مناطق نامگذاریشده و خوانا استفاده کنید - آیا همه ستونها یکسان هستند یا صرفاً براساس شماره خط قرار گرفتهاند؟ → از
repeat(N, ...)یا خطوط نامگذاریشده استفاده کنید - نه (واکنشگرا، تعداد موارد نامشخص) — از
repeat(auto-fit, minmax(min, 1fr))استفاده کنید - آیا موارد ردیف آخر باید برای پر کردن فضای باقیمانده کشیده شوند؟ →
auto-fit - آیا قطعههای ردیف آخر خالی باید حداقل اندازه خود را حفظ کنند (حفظ جایگاههای شبح ستون)؟ →
auto-fill
- بله — از دستههای هدف صریح (
- آیا باید موردی را در مکان خاصی قرار دهید؟
- بله — از
grid-column: <start> / <end>یاgrid-area: <name>استفاده کنید - نه (فقط چند قطعه را دربرمیگیرد، موقعیت جریان مهم نیست) — از
grid-column: span <n>استفاده کنید
- بله — از
- آیا عناصر فرزند باید اندازههای شیار شبکه والد را به ارث ببرند (تراز لبه ناهموار در بین عناصر همسطح)؟
- بله — از زیرشبکه در محور تحتتأثیرقرارگرفته استفاده شود
- آیا تعداد فرزندان در هر سلول متغیر است؟ → زیرشبکه فقط یک محور؛ از
grid-auto-rows/grid-auto-columnsبرای دیگری استفاده کنید - آیا تعداد فرزندان ثابت است؟ → subgrid on both axes is fine
- نه — شبکه استاندارد، بدون نیاز به زیرشبکه
بایدها:
- ایجاد زمینه با
display: grid. - از
grid-template-areasبرای چیدمانهای پیچیده در سطح صفحه استفاده کنید — نامهای ناحیه خودسندسازی هستند و اعلان را میتوان در ردیفها و ستونها تراز کرد تا خوانایی در یک نگاه فراهم شود. - از
repeat(auto-fit, minmax(200px, 1fr))برای شبکههای کارت واکنشگرا که قطعههای پرشده را برای پر کردن ردیف میکشند، یا ازauto-fillبرای حفظ قطعههای تکراری خالی در حداقل اندازه آنها استفاده کنید. - از
frبرای توزیع متناسب قطعه و ازminmax(min, max)برای قطعههای انعطافپذیر اما محدود استفاده کنید. - موقعیت موارد با
grid-column: span <n>برای اندازه در سراسر قطعهها،grid-column: <start> / <end>برای قرار دادن در خطوط خاص، یاgrid-area: <name>برای مناطق نامگذاریشده. - از زیرشبکه (
grid-template-columns: subgridیاgrid-template-rows: subgrid) برای حل مشکل «لبه ناهموار» در فهرستهای کارتی استفاده کنید — عناصر داخلی مانند عنوانها، فرادادهها، و دعوت به اقدامها در ردیفهای همسطح تراز میشوند. - یک اعلان زیرشبکه را با یک اعلان صریح قبلی
grid-template-rows/-columnsبهعنوان یک جایگزین آبشاری یکسان برای مرورگرهای قدیمیتر جفت کنید.
این کارها را نکنید:
- انتظار نداشته باشید اندازه قطعه
auto-fit/auto-fillاز محتوای مورد حاصل شود — این اندازه از آرگومان اندازهrepeat()حاصل میشود. - از
grid-auto-flow: denseدر محتوای تعاملی استفاده نکنید. این طرحبندی موارد را بهطور کارآمد بستهبندی میکند اما ترتیب آنها را بهصورت بصری تغییر میدهد و جریان زبانه صفحهکلید با ترتیب DOM را میشکند. - وقتی تعداد فرزندان متغیر است، زیرشبکه را برای هر دو محور اعمال نکنید. موارد اضافی در آخرین قطعه قرار میگیرند؛ بهجای آن از
grid-auto-rows/grid-auto-columnsبرای محور ضمنی استفاده کنید. -
justify-items/align-items(محتوای مورد را در قطعه آن تراز میکند) را باjustify-content/align-content(قطعههای شبکه را در محفظه تراز میکند) اشتباه نگیرید. استفاده از گزینه اشتباه هیچ تأثیری ندارد. - از
repeat(auto-fit/auto-fill, ...)بدونinline-sizeمشخص در محتوا استفاده نکنید — در داخلdisplay: inline-gridیا عنصر flex بدون اندازه، محتوا عرضی برای تقسیم ندارد، که باعث میشود تعداد قطعهها غیرقابلپیشبینی شود.
۳.۱ نمونه کد: شبکه و زیرشبکه
پوسته صفحه: <main class="page-layout"> حاوی <header>، <aside>، <section class="card-grid"> با <div class="card"> فرزند، و <footer> است.
/* Align grid-template-areas in rows and columns for readability. */
.page-layout {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
gap: 1.5rem;
}
header { grid-area: header; }
aside { grid-area: sidebar; }
footer { grid-area: footer; }
.card-grid {
grid-area: main;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
grid-template-rows: auto 1fr; /* title block, body block */
gap: 1rem;
}
.card {
grid-row: span 2;
display: grid;
/* Same-cascade fallback: ignored when subgrid is supported. */
grid-template-rows: auto 1fr;
grid-template-rows: subgrid;
}
۴ پُرسمان محتوا
اندازه (یا سبک محاسبهشده) محفظه والد را بهجای ناحیه نمایش جستجو کنید. Mental model: container queries = component context; media queries = global page layout and user preferences (prefers-color-scheme, prefers-reduced-motion).
بایدها:
- قبلاز اینکه بتوان از فرزندان یک پوشاننده پرسوجو کرد، بااستفاده از
container-type: inline-size(پرسوجوهای فقط عرض) یاcontainer-type: size(هر دو محور) یک بافتار مهار روی آن ایجاد کنید. - وقتی بافتهای تودرتو ممکن است باهم تداخل داشته باشند، کانتینرها را با
container-name(یا خلاصهcontainer:container: card / inline-size) نامگذاری کنید. - Include container query units in calculating fluid type and spacing:
cqi/cqb(logical inline/block),cqw/cqh(physical),cqmin/cqmax. - هرزمان از
container-type: sizeاستفاده میشود، به ظرفblock-sizeقطعی بدهید — بدون آن، فرزندان جمع میشوند زیرا محدودسازی اندازه ظرف را مجبور میکند محتوایش را نادیده بگیرد.
این کارها را نکنید:
- از
block-sizeبهعنوان مقدارcontainer-typeاستفاده نکنید — معتبر نیست. ازsizeبرای هر دو محور استفاده کنید. - پساز اعلام
container-type، انتظار نداشته باشید اندازه ذاتی فرزندان بر دربرگیرنده تأثیر بگذارد. وقتی دربرگیرنده فعال باشد، بهگونهای محاسبه میشود که گویی هیچ فرزند ندارد. - به واحدهای پرسمان محفظه در داخل فرزندان یک جد غیرواجدشرایط تکیه نکنید؛ آنها به نمای کوچک (
svw/svh) برمیگردند.
۴.۱ نمونه کد: تایپوگرافی سیال بااستفاده از واحدهای پُرسمان محتوی
.card-wrapper {
container: card / inline-size; /* shorthand for container-name / container-type */
}
@container card (inline-size > 400px) {
.content {
display: flex;
gap: 2rem;
}
}
.title {
/* Fluid type bound to the container width, not the viewport. */
font-size: clamp(1rem, 4cqi, 2rem);
}
برای الگوهای سبکبندی واکنشگرای مؤلفهمحور، به سبکبندی آگاه از اندازه و مقیاسبندی سیال مراجعه کنید.
۵ رونهاد بومی، جایگاهسازی لنگر، و زمینههای پشتهسازی
زمان استفاده از هر رونهاد اولیه:
- از
popoverبرای میانای کاربری گذرا و غیرمُدال (منوهای فرعی، پیامهای موقت، نکتهابزارها) استفاده کنید — در لایه بالایی قرار دارد، نیازی به مدیریتz-indexنیست. - از
<dialog>با.showModal()برای تعاملات مدال که نیاز به تله فوکوس و پسزمینه بیاثر دارند استفاده کنید. popoverو.showModal()را در یک عنصر ترکیب نکنید — این دو حالتهای زمان اجرای متقابلاً انحصاری هستند.
موقعیتیابی لنگر (چیدمان فضایی همپوشانیها):
- از
position-area(یاanchor()در درجها) وanchor-size()برای تعیین موقعیت و اندازه رونهاد نسبت به راهانداز آن استفاده کنید. - از
position-try-fallbacks: flip-block(یاflip-inline) استفاده کنید تا به مرورگر اجازه دهید وقتی رونهاد از ناحیه نمایش سرریز میشود، موقعیت آن را تغییر دهد. - کلیدواژههای فیزیکی و منطقی را در یک مقدار
position-areaترکیب نکنید — یکی از سیستمهای مختصات را انتخاب کنید. - با
@supports (anchor-name: --x)ویژگی را شناسایی کنید و یک جایگزین موقعیت مطلق ارائه دهید.
برای جزئیات کامل پیادهسازی، استراتژیهای شبیهساز مرورگر، و مرجع مقدار
popover، به کنترل پاپاور و کادر گفتگوی اعلانی و نکتهابزارهای آگاه از موقعیت مراجعه کنید. برای موقعیتیابی لنگر اعمالشده بر منوهای کرکرهای، منوهای فرعی، و نشانگرهای برگه، به منوهای کرکرهای آگاه از نمای دید و خط زیرین برگه موقعیتیابی لنگر مراجعه کنید.
۶ ردیابی سرریز و پایداری چیدمان
تغییرات چیدمان، نوارهای پیمایش، و برش را بهطور قابلپیشبینی مدیریت کنید.
بایدها:
- از
overflow: autoاستفاده کنید تا نوارهای پیمایش فقط زمانی ظاهر شوند که محتوا واقعاً سرریز شود. - از
overflow: clipبرای برش محتوا بدون ایجاد محفظه پیمایش استفاده کنید؛ باoverflow-clip-margin، سرریز شدن را انتخاب کنید. - از
scrollbar-gutter: stableبرای رزرو فضا برای نوارهای پیمایش و جلوگیری از تغییرات طرحبندی هنگام افزایش محتوا استفاده کنید. - از
overscroll-behavior: contain(یاnone) در مناطق پیمایش تودرتو (مانند نوارهای کناری، مدالها، و فهرستها) استفاده کنید تا از حباب شدن زنجیرههای پیمایش در صفحه جلوگیری کنید، یا ازoverscroll-behavior: chainدر بستهبندیهای پیمایش میانی (مانند تند کشیدن برای آشکار کردن قطعهها) استفاده کنید، زمانی که پیمایش اضافی باید به یک پیمایشگر اجدادی منتقل شود بدون اینکه باعث ایجاد پرش محلی نوار لاستیکی شود. از سهگانه
-webkit-line-clamp+display: -webkit-box+-webkit-box-orient: verticalبرای کوتاه کردن چندخطی استفاده کنید — با وجود پیشوند، این الگو کاملاً مشخص شده است و منسوخ نشده است.line-clampخلاصه بدون پیشوند را در کنار آن اعلام کنید؛ مرورگرهایی که هنوز از آن پشتیبانی نمیکنند، این ویژگی را بدون مشکل نادیده میگیرند. این کارها را نکنید:وقتی
autoکار را راه میاندازد، ازoverflow: scrollاستفاده نکنید —scrollحتی وقتی چیزی برای پیمایش وجود ندارد، نوار پیمایش را تحمیل میکند.وقتی فقط میخواهید برش دهید، از
overflow: hiddenاستفاده نکنید —hiddenیک محفظه پیمایش ایجاد میکند که میتوان آن را بهصورت برنامهنویسی پیمایش کرد.
.scrollable-list {
max-block-size: 400px;
overflow-y: auto;
scrollbar-gutter: stable; /* Reserve scrollbar space. */
overscroll-behavior: contain; /* No scroll chaining into the page. */
}
.snippet {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
line-clamp: 3; /* Ignored where unsupported. */
overflow: clip;
}
برای اطلاعات بیشتر درباره
overflow: clipوoverflow-clip-margin، به کنترل برش سرریز مراجعه کنید. برای انتقال پیمایش تودرتو باoverscroll-behavior: chainدر واسط کاربر «تند کشیدن برای آشکار کردن»، به تند کشیدن برای آشکار کردن مراجعه کنید. برای رنگ، اندازه، و زمینه نوار پیمایش، به سفارشیسازی رنگ یا ضخامت نوار پیمایش، حالت تیره، و تطبیق نوار پیمایش با اولویتهای کنتراست بالا مراجعه کنید.
۷ مکانیک نمای هدف و توزیع قطعه
- از
dvh/dvwبرای محفظههای چیدمان تلفن همراه که باید تغییر واسط کاربر مرورگر (جمع/باز شدن نوار نشانی وب) را درنظر بگیرند استفاده کنید. - از
100vwبرای چیدمان تمامعرض استفاده نکنید — این کار عرض نوار پیمایش را نادیده میگیرد و باعث سرریز افقی میشود. درعوض از100%،100dvw، یا100svwاستفاده کنید.
برای نقطه ورودی طراحی واکنشگرا (واحدهای نمای پویای پویا، رزرو فضا برای رسانه، تایپوگرافی سیال)، به طراحی واکنشگرا مراجعه کنید.
۸ خطوط جدولی (یا آجری)
این مشخصات با نام «grid lanes» (مثلاً display: grid-lanes) درحال توسعه است، درحالیکه نمونههای اولیه آزمایشی از grid-template-rows: masonry استفاده میکردند.
بایدها:
- امروز از شبکه با
grid-auto-flow: denseبرای بستهبندی فشرده استفاده کنید، با این فرض که ترتیب DOM ممکن است با ترتیب دیداری مطابقت نداشته باشد. - از چندستونی (
columns: 3; column-gap: 1rem) برای جریانهای محتوا-محور آجرچینیمانند استفاده کنید، زمانی که موارد بهجای کارتهای هموزن، قطعات سند هستند. - با
grid-template-rows: masonryفقط بهعنوان ارتقای پیشرو رفتار کنید — تشخیص ویژگی با@supports.
این کارها را نکنید:
- تا زمانی که هدف «مبنا» شما به آن نرسیده است،
grid-template-rows: masonryرا بهعنوان یک الزام سخت ارسال نکنید.
.gallery { columns: 3 200px; column-gap: 1rem; }
.gallery > * { break-inside: avoid; margin-block-end: 1rem; }
@supports (grid-template-rows: masonry) {
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-template-rows: masonry;
gap: 1rem;
columns: unset;
}
}