یک پیشنهاد جایگزین برای سنگ تراشی CSS

منتشر شده: ۳۰ آوریل ۲۰۲۴، آخرین به‌روزرسانی: ۱۳ فوریه ۲۰۲۶

تیم کروم مشتاق است که شاهد پیاده‌سازی طرح‌بندی‌های نوع بنایی (masonry) در وب باشد. با این حال، ما احساس می‌کنیم که پیاده‌سازی آن به عنوان بخشی از مشخصات CSS Grid همانطور که در پست اخیر WebKit پیشنهاد شده است، یک اشتباه خواهد بود. ما همچنین احساس می‌کنیم که پست WebKit علیه نسخه‌ای از بنایی (masonry) که هیچ کس آن را پیشنهاد نکرده بود، استدلال کرد.

بنابراین، هدف این پست توضیح این موضوع است که چرا ما در کروم نگرانی‌هایی در مورد پیاده‌سازی چیدمان بنایی به عنوان بخشی از مشخصات طرح‌بندی شبکه‌ای CSS داریم و دقیقاً مشخص می‌کنیم که پیشنهاد جایگزین چه قابلیت‌هایی را ارائه می‌دهد. به طور خلاصه:

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

آیا مصالح بنایی باید بخشی از شبکه باشد؟

تیم کروم معتقد است که چیدمان کاشی‌ای باید یک روش طرح‌بندی جداگانه باشد که با استفاده از display: masonry (یا کلمه کلیدی دیگری که نام بهتری برای آن انتخاب شود) تعریف می‌شود. در ادامه این پست، می‌توانید چند نمونه از آنچه که می‌تواند در کد به نظر برسد را مشاهده کنید.

دو دلیل مرتبط وجود دارد که چرا احساس می‌کنیم چیدمان بنایی (masonry) خارج از طرح‌بندی شبکه‌ای (grid layout) بهتر تعریف می‌شود - احتمال بروز مشکلات عملکرد چیدمان، و این واقعیت که هم چیدمان بنایی و هم چیدمان شبکه‌ای ویژگی‌هایی دارند که در یک روش چیدمان منطقی هستند اما در روش دیگر منطقی نیستند.

عملکرد

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

بنابراین، اگر یک طرح‌بندی masonry با تعریف مسیر grid-template-columns: 200px auto 200px داشته باشید - که یک کار بسیار رایج در grid است - با مشکلاتی مواجه خواهید شد. این مشکلات با اضافه کردن subgridها به صورت تصاعدی افزایش می‌یابند .

استدلالی وجود دارد که می‌گوید اکثر مردم با این موضوع مواجه نمی‌شوند، با این حال ما می‌دانیم که مردم شبکه‌های بسیار بزرگی دارند . ما نمی‌خواهیم چیزی را ارائه دهیم که محدودیت‌هایی در نحوه استفاده از آن وجود داشته باشد، در حالی که یک رویکرد جایگزین وجود دارد.

در مورد چیزهایی که در هر روش طرح‌بندی منطقی نیستند چه کار کنیم؟

وقتی flexbox و grid بخشی از CSS شدند، توسعه‌دهندگان اغلب احساس می‌کردند که آنها به شیوه‌ای متناقض رفتار می‌کنند. ناسازگاری که آنها تجربه می‌کردند به دلیل فرضیات طولانی‌مدت در مورد نحوه عملکرد طرح‌بندی، بر اساس طرح‌بندی بلوکی بود. با گذشت زمان، توسعه‌دهندگان شروع به درک زمینه‌های قالب‌بندی کرده‌اند. وقتی به یک زمینه قالب‌بندی grid یا flex تغییر می‌دهیم، برخی چیزها متفاوت رفتار می‌کنند. به عنوان مثال، می‌دانید که وقتی در flexbox هستید، همه روش‌های ترازبندی در دسترس نیستند، زیرا flexbox یک بعدی است.

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

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

همچنین الگوهایی وجود دارند که در masonry منطقی هستند، برای مثال grid-template-columns: repeat(auto-fill, max-content) ، زیرا شما محدودیت‌های متقاطع ندارید، اما باید در grid نامعتبر باقی بمانید. در زیر لیستی از ویژگی‌هایی آمده است که انتظار داریم رفتار متفاوتی داشته باشند یا مقادیر معتبر متفاوتی داشته باشند.

  • grid-template-areas : در بنایی فقط می‌توانید ردیف اولیه را در جهت غیر بنایی مشخص کنید.
  • grid-template : این خلاصه‌نویسی باید تمام تفاوت‌ها را در نظر بگیرد.
  • مقادیر اندازه برای grid-template-columns و grid-template-rows را به دلیل تفاوت در مقادیر قانونی، پیگیری کنید.
  • grid-auto-flow برای masonry و masonry-auto-flow برای grid اعمال نمی‌شود. ادغام آنها مشکلاتی ایجاد می‌کند که به دلیل روش چیدمانی که در آن هستید، نامعتبر هستند.
  • گرید چهار ویژگی قرارگیری دارد ( grid-column-start و غیره)، ماسونری فقط دو ویژگی دارد.
  • گرید می‌تواند از هر شش ویژگی justify-* و align-* استفاده کند، اما ماسونری فقط از زیرمجموعه‌ای مانند flexbox استفاده می‌کند.

همچنین الزامی وجود خواهد داشت که مشخص شود در تمام موارد خطای جدید ناشی از استفاده توسعه‌دهندگان از مقداری که در grid-with-masonry یا grid-without-masonry معتبر نیست، چه اتفاقی می‌افتد. به عنوان مثال، استفاده از grid-template-columns: masonry یا grid-template-rows: masonry معتبر است اما استفاده همزمان از هر دو مجاز نیست. اگر از هر دو به طور همزمان استفاده کنید چه اتفاقی می‌افتد؟ این جزئیات باید مشخص شوند تا همه مرورگرها کار یکسانی انجام دهند.

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

یک پیشنهاد جایگزین

همانطور که قبلاً اشاره شد، تیم کروم مایل است چیدمان بنایی را خارج از مشخصات شبکه تعریف کند. این بدان معنا نیست که به یک روش طرح‌بندی بسیار ساده با اندازه ستون‌های یکسان محدود شود. تمام دموهای موجود در پست WebKit همچنان امکان‌پذیر خواهند بود.

طرح بندی کلاسیک ماسونری

وقتی بیشتر مردم به چیدمان بنایی فکر می‌کنند، یک طرح‌بندی با ستون‌های متعدد و هم‌اندازه را تصور می‌کنند. این طرح‌بندی با استفاده از CSS زیر تعریف می‌شود که به کد کمتری نسبت به نسخه شبکه‌ای معادل نیاز دارد.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 1rem;
}

آهنگ‌های هم‌اندازه.

برای عرض‌های مختلف ستون، از اندازه‌بندی مسیر از نوع شبکه‌ای استفاده کنید

گذشته از مشکل ذکر شده قبلی در مورد اندازه‌گذاری ترکیبی ذاتی و ثابت مسیر، می‌توانید از تمام اندازه‌بندی‌های مسیر مورد علاقه‌تان از گرید استفاده کنید. مانند مثالی از پست وبلاگ WebKit ، الگویی از تکرار ستون‌های باریک و پهن.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
  gap: 1rem;
}

الگویی از مسیرهای پهن و باریک.

اندازه مسیر اضافی برای سنگ تراشی

گزینه‌های دیگری برای اندازه‌گذاری مسیر وجود دارد که به دلیل اینکه گرید یک روش طرح‌بندی دوبعدی است، در گرید مجاز به استفاده از آنها نیستیم. این گزینه‌ها در بنایی مفید خواهند بود، اما اگر در گرید کار نکنند، گیج‌کننده خواهند بود.

پر کردن خودکار آهنگ‌های max-content .

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, max-content);
  gap: 1rem;
}

پر کردن خودکار آهنگ‌های با اندازه auto ، که آهنگ‌هایی با اندازه یکسان ایجاد می‌کند، که به طور خودکار اندازه آنها متناسب با بزرگترین آهنگ است.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
  gap: 1rem;
}

بنایی با ریل‌های با اندازه خودکار.

اجازه دهید محتوا روی ستون‌ها قرار گیرد و موارد را در طرح بنایی قرار دهید

هیچ دلیلی وجود ندارد که ستون‌های محتوا را در یک مشخصات جداگانه‌ی masonry نپوشانیم. این ممکن است از ویژگی masonry-track استفاده کند که مخفف masonry-track-start و masonry-track-end است، زیرا در طرح‌بندی masonry فقط یک بُعد برای پوشاندن چیزها دارید.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
}

.span-2 {
  masonry-track: span 2; /* spans two columns */
}

.placed {
  masonry-track: 2 / 5; /* covers tracks 2, 3, and 4 */
}

بنایی با اقلام قرار داده شده و پوشاننده.

زیرسازی یا زیرشبکه با استفاده از مسیرهای بنایی

این می‌تواند با یک مشخصات بنایی جداگانه پشتیبانی شود، باز هم با این شرط که مسیرهای با اندازه ثابت و ذاتی مختلط مجاز نباشند. اینکه دقیقاً چه شکلی باشد، باید تعریف شود. ما هیچ دلیلی نمی‌بینیم که این کار نکند.

نتیجه‌گیری

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

اگر نظری دارید، در بحث شماره ۹۰۴۱ شرکت کنید.

با تشکر از براموس، تب اتکینز-بیتنر، اونا کراوتس، ایان کیلپاتریک و کریس هارلسون برای بررسی این پست و بحث‌هایی که منجر به شکل‌گیری آن شد.