יצירת רכיב של סטוריז

סקירה בסיסית שמראה איך ליצור חוויה שדומה לסטוריז של Instagram באינטרנט.

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

הדגמה

אם אתם מעדיפים הדגמה מעשית של בניית רכיב הסטוריז בעצמכם, תוכלו להיעזר ב-Codelab של רכיב הסטוריז.

אם ברצונך ליצור סרטון, הנה גרסת YouTube של הפוסט הזה:

סקירה כללית

שתי דוגמאות פופולריות לחווית המשתמש בסטוריז הן סטוריז ב-Snapchat וסטוריז ב-Instagram (וגם לא ב-Fleet). במונחים כלליים של חוויית משתמש, סטוריז הם בדרך כלל דפוס שמתמקד בניידים בלבד ומאפשר לכם לנווט לכמה מינויים. לדוגמה, ב-Instagram, משתמשים פותחים סטורי של חבר או עוברים בין התמונות שמוצגות בו. בדרך כלל הם עושים זאת כמספר החברים בו זמנית. על ידי הקשה על צד ימין של המכשיר, המשתמש מדלג קדימה לסיפור הבא של אותו חבר. בהחלקה ימינה, משתמש מדלג קדימה לחבר אחר. רכיב Story דומה למדי לקרוסלה, אבל מאפשר ניווט במערך רב-ממדי בניגוד למערך חד-ממדי. זה כאילו יש קרוסלה בתוך כל קרוסלה. 🤯

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

בחירת הכלים המתאימים למשימה

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

רשת CSS

התברר שהפריסה שלנו לא עולה בקנה אחד עם ה-CSS Grid כי היא כוללת כמה דרכים עוצמתיות לתמרן תוכן.

הפריסה 'חברים'

wrapper של רכיב .stories הראשי שלנו הוא תצוגת גלילה אופקית תחילה לנייד:

.stories {
  inline-size: 100vw;
  block-size: 100vh;

  display: grid;
  grid: 1fr / auto-flow 100%;
  gap: 1ch;

  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  touch-action: pan-x;
}

/* desktop constraint */
@media (hover: hover) and (min-width: 480px) {
  max-inline-size: 480px;
  max-block-size: 848px;
}
שימוש בכלי הפיתוח ל-Chrome מצב מכשיר להדגשת העמודות שנוצרות על ידי הרשת

נפרט את הפריסה grid:

  • אנחנו ממלאים באופן מפורש את אזור התצוגה בנייד באמצעות 100vh ו-100vw ומגבילים את הגודל במחשבים שולחניים
  • / מפריד בין תבניות של שורות ועמודות
  • auto-flow מתורגמת לgrid-auto-flow: column
  • תבנית הזרימה האוטומטית היא 100%, ובמקרה זה זהו רוחב חלון הגלילה

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

מוערם

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

בעזרת רשת CSS, אנחנו יכולים להגדיר רשת של תא יחיד (כלומר ריבוע), שבה השורות והעמודות חולקות כינוי ([story]), ולאחר מכן כל צאצא מוקצה למרחב של תא יחיד עם כינוי:

.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
.story {
  grid-area: story;
  background-size: cover;
  …
}

כך ה-HTML שלנו שולט בסדר הסידור בערימה וגם שומר על רצף כל הרכיבים. שימו לב שלא היינו צריכים לעשות שום דבר עם המיקום absolute או עם z-index, ולא היה צורך למלא את התיבה עם height: 100% או width: 100%. רשת ההורה כבר הגדירה את גודל אזור התצוגה של התמונה, כך שאף אחד מהרכיבים האלה לא צריך לבקש למלא אותה!

נקודות Snap לגלילה ב-CSS

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

גלילה אופקית בלי סגנונות scroll-snap-points ועם סגנונות כאלה. בלי האפשרות הזו, המשתמשים יכולים לגלול באופן חופשי כרגיל. באמצעותו הדפדפן שומר בעדינות על כל פריט.
parent
.stories {
  display: grid;
  grid: 1fr / auto-flow 100%;
  gap: 1ch;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  touch-action: pan-x;
}
הורה עם גלילת יתר מגדיר התנהגות Snap.
צאצא
.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
ילדים בוחרים להיות יעד קליל.

בחרתי באפשרות Scroll Snap Points מכמה סיבות:

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

תאימות לדפדפנים שונים

בדקנו את היכולות של Opera, Firefox, Safari ו-Chrome, בנוסף ל-Android ול-iOS. לפניכם סקירה קצרה של תכונות האינטרנט שבהן מצאנו הבדלים ביכולות ובתמיכה.

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

scroll-snap-stop

קרוסלות היו אחד מהתרחישים העיקריים של חוויית המשתמש שגרמו ליצירת המפרט ב-CSS Scroll Snap Points. בניגוד לסטוריז, לא תמיד צריך להפסיק את הקרוסלה בכל תמונה אחרי אינטראקציה של משתמש. אולי כדאי או לעודד אתכם לגלוש במהירות בקרוסלה. לעומת זאת, עדיף לנווט לסיפורים אחד אחרי השני, וזה בדיוק מה ש-scroll-snap-stop מספק.

.user {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

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

אם רוצים, אפשר לקרוא מידע נוסף במפרט.

overscroll-behavior

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

.stories {
  overflow-x: auto;
  overscroll-behavior: contain;
}

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

scrollIntoView({behavior: 'smooth'})

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

element.scrollIntoView({
  behavior: 'smooth'
})

Safari היה הדפדפן היחיד שלא תמך כאן ב-behavior: 'smooth'. לקבלת עדכונים, כדאי לבדוק את הקטע תאימות דפדפן.

מעשית

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

רמיקסים של הקהילה