הצעה חלופית לבנייה של שירות CSS

צוות Chrome רוצה לראות הטמעה של פריסות מסוג 'לבנים' באינטרנט. עם זאת, לדעתנו יהיה טעות ליישם אותו כחלק מפרט CSS Grid, כפי שהוצעה בפוסט האחרון בנושא WebKit. בנוסף, לדעתנו המאמר ב-WebKit התנגד לגרסה של masonry שאף אחד לא הציע.

לכן, המטרה של הפוסט הזה היא להסביר למה יש לנו ב-Chrome חששות לגבי הטמעת פריסת 'לבנים' כחלק מהמפרט של CSS Grid Layout, ולהבהיר בדיוק מה מאפשרת ההצעה החלופית. בקצרה:

  • צוות Chrome רוצה מאוד לבטל את החסימה של פריסת האריחים, אנחנו יודעים שזה משהו שמפתחים רוצים.
  • הוספת פריסת שורות למפרט של רשת היא בעייתית מסיבות אחרות, ולא רק בגלל שפריסת שורות היא רשת או לא.
  • הגדרת פריסת שורות 'תמונות ברצף' מחוץ למפרט של התצוגה לא מונעת שימוש במספר גדלים של טראקים בפריסת שורות 'תמונות ברצף', או שימוש במאפיינים כמו התאמה או רווחים, או כל תכונה אחרת שמשמשת בתצוגת התמונות ברצף.

האם הפריטים צריכים להיות מסודרים בתצוגת שורות?

צוות Chrome סבור שפריסת 'לבנים' צריכה להיות שיטת פריסה נפרדת, שמוגדרת באמצעות display: masonry (או מילת מפתח אחרת, אם יוחלט על שם טוב יותר). בהמשך הפוסט מוצגות כמה דוגמאות לאופן שבו הקוד יכול להיראות.

יש שתי סיבות קשורות לכך שלדעתנו עדיף להגדיר את פריסת האריחים מחוץ לפריסת הרשת – האפשרות לבעיות בביצועי הפריסה והעובדה שלפריסת האריחים ולפריסת הרשת יש תכונות שמתאימות לשיטת פריסה אחת אבל לא לשיטה השנייה.

ביצועים

יש הבדל בין פריסת רשת לפריסת שורות מבחינת האופן שבו הדפדפן מטפל בגודל ובמיקום. כשמגדירים את הפריסה של רשת, כל הפריטים ממוקמים לפני הפריסה והדפדפן יודע בדיוק מה נמצא בכל טראק. כך אפשר להגדיר את הגודל הפנימי המורכב, ששימושי מאוד בתצוגת רשת. כשמשתמשים בפריסת 'לבנים', הפריטים ממוקמים לפי אופן הפריסה שלהם, והדפדפן לא יודע כמה פריטים יש בכל טראק. הבעיה הזו לא מתרחשת בכל הטראקים בגודל מובנה או בכל הטראקים בגודל קבוע, אלא רק אם משלבים בין טראקים בגודל קבוע לטראקים בגודל מובנה. כדי לעקוף את הבעיה, הדפדפן צריך לבצע שלב טרום-פריסה של פריסה של כל פריט בכל דרך אפשרית כדי לקבל מדידות. כשהמרזב גדול, זה גורם לבעיות בביצועים של הפריסה.

לכן, אם יש לכם פריסה של 'לבנים' עם הגדרת טראק של grid-template-columns: 200px auto 200px – דבר נפוץ מאוד בגבישים – אתם עלולים להיתקל בבעיות. הבעיות האלה הולכות ומתעצמות כשמוסיפים רשתות משנה.

יש הטוענים שרוב האנשים לא ייתקלו בבעיה הזו, אבל אנחנו כבר יודעים שיש לאנשים רשתות גדולות מאוד. אנחנו לא רוצים לשלוח משהו שיש מגבלות על האופן שבו אפשר להשתמש בו, אם יש גישה חלופית.

מה עושים עם הדברים שלא הגיוניים בכל שיטת פריסה?

כש-flexbox ו-grid הפכו לחלק מ-CSS, מפתחים רבים הרגישו שהם פועלים בצורה לא עקבית. חוסר העקביות שהם חווים נובע מהנחות שהיו להם במשך שנים לגבי אופן הפעולה של הפריסה, על סמך פריסה של בלוקים. עם הזמן, המפתחים התחילו להבין את ההקשרים של הפורמטים. כשעוברים להקשר של עיצוב בפריסת רשת או בפורמט גמיש, יש דברים שמתנהגים באופן שונה. לדוגמה, אתם יודעים שכאשר משתמשים ב-Flexbox, לא כל שיטות היישור זמינות כי Flexbox הוא מימד אחד.

הקיפול של פריסת האריחים לתוך רשת מפר את הקישור הברור הזה בין הקשר העיצוב לבין הזמינות של דברים כמו מאפייני היישור, שמוגדרים במפרט של Box Alignment לפי הקשר העיצוב.

אם נחליט לטפל בבעיית הביצועים שמפורטת למעלה על ידי איסור על שילוב של הגדרות טראקים מובנות וטראקים קבועים בפריסת 'אבן ריבועית', חשוב לזכור שתבנית נפוצה מאוד של פריסות רשת לא עובדת בפריסת 'אבן ריבועית'.

יש גם תבניות שיהיו הגיוניות בסידור 'לבנים', למשל grid-template-columns: repeat(auto-fill, max-content), כי אין אילוצים חוצי-עמודות, אבל צריך להישאר לא חוקיים בפריסת רשת. בהמשך מופיעה רשימה של מאפיינים שאנחנו מצפים שהם יפעלו בצורה שונה או שיש להם ערכים חוקיים שונים.

  • grid-template-areas: בפריסת שורות, אפשר לציין רק את השורה הראשונה בכיוון שאינו פריסת שורות.
  • grid-template: הקיצור צריך להביא בחשבון את כל ההבדלים.
  • לעקוב אחרי ערכי הגודל של grid-template-columns ו-grid-template-rows בגלל הבדלים בערכים החוקיים.
  • grid-auto-flow לא חל על פריסת'לבנים' ו-masonry-auto-flow לא חל על פריסת רשת. מיזוג שלהם יגרום לבעיות של פריטים לא תקינים בגלל שיטת הפריסה שבה אתם משתמשים.
  • לרשת יש ארבעה מאפייני מיקום מודעה (grid-column-start וכן הלאה), ולמיקום מודעה ב-masonry יש רק שניים.
  • אפשר להשתמש בכל ששת המאפיינים של justify-* ו-align-* ב-Grid, אבל ב-Masonry נעשה שימוש רק בקבוצת משנה כמו flexbox.

בנוסף, תהיה דרישה לציין מה קורה בכל מקרה השגיאה החדש שנגרם על ידי מפתחים שמשתמשים בערך לא חוקי ב-grid-with-masonry או ב-grid-without-masonry. לדוגמה, אפשר להשתמש ב-grid-template-columns: masonry או ב-grid-template-rows: masonry, אבל לא בשניהם בו-זמנית. מה קורה אם משתמשים בשתי התכונות בו-זמנית? צריך לציין את הפרטים האלה כדי שכל הדפדפנים יבצעו את אותה פעולה.

מבחינת המפרט, הכול הופך להיות מסובך, עכשיו ובעתיד. נצטרך לוודא שכל התמונות והסרטונים מוצגים בפורמט של 'קיר תמונות', ולבדוק אם הם עובדים בפורמט הזה או לא. הוא גם מבולבל מנקודת המבט של המפתחים. למה חשוב לזכור שלמרות השימוש ב-display: grid, יש דברים שלא עובדים בגלל השימוש ב-masonry?

הצעה חלופית

כפי שצוין קודם, צוות Chrome רוצה להגדיר את הצורה 'לבנים' מחוץ למפרט של הרשת. זה לא אומר שהיא תהיה מוגבלת לשיטת פריסה פשוטה מאוד עם גדלים זהים של עמודות. עדיין תוכלו להריץ את כל הדמואים שפורסמו בפוסט של 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-track, שהוא קיצור דרך ל-masonry-track-start ול-masonry-track-end, כי יש רק מאפיין אחד שאפשר להשתמש בו כדי למקם פריטים בפריסת 'לבנים'.

.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 */
}

פריסת 'לבנים' עם פריטים מוצבים ופריטים שחופפים על פני כמה שורות.

תת-פריסת 'לבנים' או רשת משנה שמשתמשת בטראקים של 'לבנים'

אפשר לתמוך בכך באמצעות מפרט נפרד של פריסת שורות, שוב עם ההגבלה שאסור לשלב טראקים בגודל קבוע עם טראקים בגודל מובנה. צריך להגדיר בדיוק איך זה נראה. אין לנו סיבה לחשוב שהשיטה הזו לא תפעל.

סיכום

אנחנו רוצים להגיע למצב שבו נוכל לשלוח מפרט שאפשר יהיה להשתמש בו ביעילות. עם זאת, אנחנו רוצים לעשות זאת בצורה שתעבוד טוב עכשיו ובעתיד, ושהמפתחים יוכלו לסמוך עליה. הדרך היחידה לטפל בבעיות הביצועים שמפורטות למעלה היא להחמיר את הבעיה השנייה – הבעיה של חלקים מהמרקם שאינם חוקיים בפריסת 'לבנים'. אנחנו לא חושבים שזה פתרון טוב, במיוחד כשאפשר להשתמש בכל התכונות של התצוגה ברשימה ועדיין להפריד בבירור בין הדברים השונים.

אם יש לכם משוב, תוכלו להצטרף לדיון בבעיה 9041.

תודה ל-Bramus,‏ Tab Atkins-Bittner,‏ Una Kravets,‏ Ian Kilpatrick ו-Chris Harrelson על בדיקת הפוסט הזה ועל הדיונים שהובילו ליצירתו.