موقعیت آیتمهای گرید رو فقط با CSS دربیار
خلاصهٔ کاملتر
نویسنده تو مقالهٔ قبلیش نشون داده بود که تو یه گرید ساده با auto-fill، تعداد ستونها و ردیفها و مختصات هر آیتم با چندتا خط ریاضی درمیاد: چون هر آیتم خودکار جا میگیره و فقط یه خونه رو اشغال میکنه، با sibling-count() و sibling-index() کار تمومه. سؤال این مقاله اینه که اگه آیتمها تصادفی جا گرفته باشن و هرکدوم چند ستون و چند ردیف رو بگیرن چی؟ اونوقت دیگه نمیشه از مختصات حرف زد و باید خط شروع و پایان هر آیتم رو پیدا کرد.
جواب مثبته، ولی نه به سادگی چهار خط قبلی. دو تا شرط داره: ستونها همعرض باشن و ردیفها ارتفاع مشخص و برابر داشته باشن (با grid-auto-rows). به گفتهٔ نویسنده شرط دوم محدودیت واقعیه، ولی خبر خوب اینه که اطلاعات ردیف و ستون به هم گره نخوردن؛ یعنی اگه ارتفاع ردیفها نامشخص یا متغیر باشه، بازم موقعیت ستون رو میشه گرفت. یه متغیر --h هم برای ارتفاع کانتینر لازمه که خودش بخش دردسرساز ماجراست.
ایدهٔ اصلی اینه: بهجز تعداد ستونها، بقیهٔ مقدارها با Scroll-Driven Animations (یعنی انیمیشنی که بهجای زمان، با موقعیت یه باکس داخل یه اسکرولکانتینر پیش میره) حساب میشن. برای هر آیتم یه view-timeline تعریف میشه و با animation-range مشخص میکنیم کدوم لبهٔ آیتم پیشرفت انیمیشن رو کنترل کنه.
.container > * {
view-timeline: --x x;
timeline-scope: --x;
animation: --x-s linear both;
animation-timeline: --x;
animation-range: entry-crossing var(--c) exit-crossing 0%;
}دو تا نکته که نویسنده تأکید میکنه هیچوقت فراموششون نکنی: overflow: hidden روی کانتینر گرید اجباریه، چون همونه که اسکرولکانتینر رو میسازه و موقعیت آیتم باید نسبت به یه مرجع سنجیده بشه. دوم timeline-scope، چون همهٔ آیتمها تایملاین همنام تعریف میکنن و باید مطمئن شی هر آیتم فقط به تایملاین خودش دسترسی داره.
تو دموی اول این تایملاین فقط رنگ پسزمینه رو عوض میکرد؛ حالا بهجای رنگ، یه متغیر از 1 به 0 انیمیت میشه. چون ستونها همعرضن، پلهٔ انیمیشن 1/(N-1) ـه؛ پس کافیه مقدار رو در N-1 ضرب کنی تا عدد صحیح ستون دربیاد. اون +1 و +2 هم دلیل داره: تو یه گرید ۴ ستونه خطهای گرید از ۱ تا ۵ ان، ولی شروع ستون فقط میتونه ۱ تا ۴ باشه و پایانش ۲ تا ۵، چون بیرون این بازه آیتم سرریز میکنه.
--col-s: round(var(--x-s)*(var(--n) - 1) + 1);
--col-e: round(var(--x-e)*(var(--n) - 1) + 2);ردیفها هم دقیقاً همینه، فقط روی محور y: بهجای --c (عرض ستون) از --r (ارتفاع ردیف) و بهجای --n از --m (تعداد ردیفها) استفاده میشه. آخرش چهار تا انیمیشن داری که هرکدوم یه متغیر رو از 1 به 0 میبرن و چهار عدد نهایی رو میسازن. تا الان فقط Chrome و Edge این قابلیتها رو کامل پشتیبانی میکنن.
نکات کلیدی:
- روش قدیمی با sibling-count() وقتی آیتمها چند ستون یا ردیف رو بگیرن غلط جواب میده؛ مثلاً یه آیتم که ۵ ستون و ۳ ردیف رو پر کرده، --m رو ۱ حساب میکنه.
- تعداد ردیفها بهجای تعداد آیتمها از ارتفاع کانتینر (--h) و همون فرمول ستونها درمیاد.
- entry-crossing و exit-crossing تو animation-range همونیان که لبهٔ چپ یا راست آیتم رو به پیشرفت انیمیشن وصل میکنن.
- overflow: hidden روی کانتینر اجباریه و بدون timeline-scope تایملاینهای همنام آیتمها قاطی میشن.
- موقعیت ستون به همارتفاع بودن ردیفها وابسته نیست، پس تو گریدهایی با ارتفاع متغیر هم میشه لااقل بخش ستون این روش رو به کار برد.




