מעברים בין מסכים לפי כיוון הניווט

תכונות באינטרנט: מעברי תצוגה מעבר תצוגה פעיל

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

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

שלבי ההטמעה

  1. זיהוי כיוון הניווט: קובעים אם המשתמש עובר "קדימה" או "אחורה" בתהליך של האפליקציה. האופן שבו מזהים את הכיוון תלוי בתרחיש לדוגמה.
  2. הפעלת מעבר עם סוגים: מעבירים את הכיוון במערך types אל document.startViewTransition() כדי לסווג את המעבר.
  3. הגדרת אנימציות כיווניות באמצעות CSS: משתמשים במחלקה המדומה :active-view-transition-type() כדי להחיל אנימציות ספציפיות על סמך סוג הניווט.

הגדרת קיפריימים

הגדרת אנימציות של החלקה לכל כיוון ומכל כיוון. כדי לקבל את הביצועים הכי טובים, כדאי להוסיף אנימציה לשינויי מיקום באמצעות המאפיין transform או מאפייני הטרנספורמציה הנפרדים, scale,‏ rotate ו-translate. גם opacity בדרך כלל פועל היטב, אבל כדאי להימנע מהנפשה של מאפייני CSS אחרים בלי לוודא קודם שהם לא מפעילים פריסה או צביעה.

/* Slide an element out to the left */
@keyframes slide-to-left {
  /* Mandatory: animate `transform` instead of inset properties for better performance. */
  to { transform: translateX(-100%); }
}

/* Slide an element in from the right */
@keyframes slide-from-right {
  from { transform: translateX(100%); }
}

/* Slide an element out to the right */
@keyframes slide-to-right {
  to { transform: translateX(100%); }
}

/* Slide an element in from the left */
@keyframes slide-from-left {
  from { transform: translateX(-100%); }
}

הגדרת אנימציות משותפות

משתמשים בבורר ::view-transition-group(root) כדי להחיל הגדרות אנימציה שמשותפות לכל המעברים.

::view-transition-group(root){
  animation: 0.4s ease-in-out both;
}

החלת אנימציות כיווניות

משתמשים במחלקה המדומה active-view-transition-type כדי לטרגט את תצוגות המעבר באופן ספציפי כשהסוג "קדימה" או "אחורה" פעיל.

/* MANDATORY: Apply forward animations when the 'forward' type is active */
html:active-view-transition-type(forward)::view-transition-old(root) {
  animation-name: slide-to-left;
}
html:active-view-transition-type(forward)::view-transition-new(root) {
  animation-name: slide-from-right;
}

/* MANDATORY: Apply backward animations when the 'backward' type is active */
html:active-view-transition-type(backward)::view-transition-old(root) {
  animation-name: slide-to-right;
}
html:active-view-transition-type(backward)::view-transition-new(root) {
  animation-name: slide-from-left;
}

הפעלת המעבר

במהלך הניווט, מעבירים את הסוג המתאים ל-method‏ startViewTransition.

const transitionType = yourTransitionTypeLogic();
const updateDOM = yourUpdateDOMLogic();

document.startViewTransition({
  update: updateDOM,
  types: [transitionType] // Matches the CSS :active-view-transition-type() selectors
});

נגישות

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

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(root) {
    animation: none !important;
  }
}

אסטרטגיות חלופיות

‫View Transitions API הוא שיפור הדרגתי (progressive enhancement). בדפדפנים לא נתמכים, document.startViewTransition יהיה undefined. כדי לוודא שעדכון ה-DOM עדיין מתרחש באופן מיידי ללא אנימציה, צריך לעטוף את לוגיקת הניווט בבדיקה לזיהוי תכונות, כמו שמוצג בפונקציית העזר הזו.

/**
 * Navigates to a new view with a directional transition.
 * @param {Function} updateDOM - Callback to update the DOM state.
 * @param {string} direction - Either 'forward' or 'backward'.
 */
function navigate(updateDOM, direction) {
  // Feature detect for browsers that do not support View Transitions
  if (!document.startViewTransition) {
    updateDOM();
    return;
  }

  // Start transition with the specific navigation type
  document.startViewTransition({
    update: updateDOM,
    types: [direction] // Matches the CSS :active-view-transition-type() selectors
  });
}