בניית רכיב של לחצן פעולה צף (FAB)

סקירה כללית בסיסית על יצירת רכיבי FAB עם התאמה לצבע, עם תגובה מהירה ונגישים.

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

אם אתם מעדיפים סרטון, הנה גרסה של הפוסט הזה ב-YouTube:

סקירה כללית

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

רכיבים וסגנונות

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

מאגר של כפתור FAB

האלמנט הזה יכול להיות <div> רגיל, אבל כדאי לעשות טובה למשתמשים שלא רואים ולתייג אותו במאפיינים מועילים כדי להסביר את המטרה ואת התוכן של המאגר.

Markup של לחצני FAB

מתחילים עם סוג .fabs ש-CSS יכול להתחבר אליו כדי להוסיף סגנון, ואז מוסיפים את role="group" ו-aria-label כדי שהמאגר לא יהיה רק מאגר כללי, אלא מאגר בעל שם ומטרה.

<div class="fabs" role="group" aria-label="Floating action buttons">
  <!-- buttons will go here -->
</div>

הסגנון של לחצני ה-FAB

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

.fabs {
  --_viewport-margin: 2.5vmin;

  position: fixed;
  z-index: var(--layer-1);

  inset-block: auto var(--_viewport-margin);
  inset-inline: auto var(--_viewport-margin);
}

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

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

.fabs {
  

  display: flex;
  flex-direction: column-reverse;
  place-items: center;
  gap: var(--_viewport-margin);
}

כדי למרכז את הרכיבים, משתמשים ב-place-items, ו-gap מוסיף רווח בין לחצני FAB שממוקמים בקונטיינר.

לחצני FAB

עכשיו נגדיר סגנון לכמה כפתורים כך שייראו כאילו הם צפים מעל כל השאר.

לחצן FAB שמוגדר כברירת מחדל

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

תגי עיצוב ללחצן FAB

הרכיב <button> הוא הבחירה הנכונה. נתחיל ב-HTML5 כי הוא מספק חוויית משתמש מעולה עם עכבר, מגע ומקלדת. ההיבט החשוב ביותר של הרכיב הזה הוא להסתיר את הסמל ממשתמשים בקורא מסך באמצעות aria-hidden="true" ולהוסיף את טקסט התווית הנדרש לרכיב <button> עצמו. במקרים כאלה, כשמוסיפים תוויות, אני אוהב להוסיף גם title כדי שמשתמשי עכבר יוכלו לקבל מידע על מה שהסמל רוצה להעביר.

<button data-icon="plus" class="fab" title="Add new action" aria-label="Add new action">
  <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>

סגנון FAB

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

.fab {
  --_size: 2rem;

  padding: calc(var(--_size) / 2);
  border-radius: var(--radius-round);
  aspect-ratio: 1;
  box-shadow: var(--shadow-4);
}

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

.fab {
  

  /* light button and button hover */
  --_light-bg: var(--pink-6);
  --_light-bg-hover: var(--pink-7);

  /* dark button and button hover */
  --_dark-bg: var(--pink-4);
  --_dark-bg-hover: var(--pink-3);

  /* adaptive variables set to light by default */
  --_bg: var(--_light-bg);

  /* static icon colors set to the adaptive foreground variable */
  --_light-fg: white;
  --_dark-fg: black;
  --_fg: var(--_light-fg);

  /* use the adaptive properties on some styles */
  background: var(--_bg);
  color: var(--_fg);

  &:is(:active, :hover, :focus-visible) {
    --_bg: var(--_light-bg-hover);

    @media (prefers-color-scheme: dark) {
      --_bg: var(--_dark-bg-hover);
    }
  }

  /* if users prefers dark, set adaptive props to dark */
  @media (prefers-color-scheme: dark) {
    --_bg: var(--_dark-bg);
    --_fg: var(--_dark-fg);
  }
}

בשלב הבא מוסיפים כמה סגנונות כדי לעזור לסמלי ה-SVG להתאים למרחב.

.fab {
  

  & > svg {
    inline-size: var(--_size);
    block-size: var(--_size);
    stroke-width: 3px;
  }
}

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

.fab {
  -webkit-tap-highlight-color: transparent;
}

Mini FAB

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

Markup של לחצן FAB מיני

ה-HTML זהה ל-FAB, אבל אנחנו מוסיפים את הכיתה ‎ ".mini" כדי לתת ל-CSS מקום להצמיד את הווריאנט.

<button data-icon="heart" class="fab mini" title="Like action" aria-label="Like action">
  <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>
סגנון FAB קטן

בזכות השימוש במאפיינים מותאמים אישית, השינוי היחיד הנדרש הוא התאמה של המשתנה --_size.

.fab.mini {
  --_size: 1.25rem;
}

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

נגישות

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

הדגמה של אינטראקציה עם מקלדת

אחרי שהמשתמש מתמקד בקונטיינר של ה-FAB, אנחנו כבר מוסיפים את role="group" ו-aria-label="floating action buttons", שמעדכנים את המשתמשים בקורא המסך לגבי התוכן של מה שהם התמקדו בו. מבחינה אסטרטגית, הנחתי את ה-FAB שמוגדר כברירת מחדל קודם, כדי שהמשתמשים ימצאו את הפעולה הראשית קודם. לאחר מכן, משתמשים במקש flex-direction: column-reverse; כדי למקם את הלחצן הראשי בחלק התחתון, קרוב לאצבעות המשתמשים, כדי שיהיה קל לגשת אליו. זוהי תוצאה טובה, כי הלחצן שמוגדר כברירת מחדל בולט מבחינה ויזואלית והוא גם הלחצן הראשון שמופיע למשתמשים שמשתמשים במקלדת, כך שהחוויה שלהם דומה מאוד.

לבסוף, אל תשכחו להסתיר את הסמלים ממשתמשים עם קורא מסך, וודאו שאתם מספקים להם תווית ללחצן כדי שהם יוכלו להבין מה הוא עושה. כבר עשינו זאת ב-HTML באמצעות aria-hidden="true" ב-<svg> ו-aria-label="Some action" ב-<button>.

Animation

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

אסטרטגיה של תנועה מופחתת עם מאפיינים מותאמים אישית

שלושה מאפיינים מותאמים אישית נוצרים בקוד ה-CSS הבא: --_motion-reduced,‏ --_motion-ok ו---_transition. שני המשתנים הראשונים מכילים את המעברים המתאימים בהתאם להעדפות המשתמש, והמשתנה האחרון --_transition יוגדר לערך --_motion-reduced או לערך --_motion-ok בהתאמה.

.fab {
  /* box-shadow and background-color can safely be transitioned for reduced motion users */
  --_motion-reduced:
    box-shadow .2s var(--ease-3),
    background-color .3s var(--ease-3);

  /* add transform and outline-offset for users ok with motion */
  --_motion-ok:
    var(--_motion-reduced),
    transform .2s var(--ease-3),
    outline-offset 145ms var(--ease-2);

  /* default the transition styles to reduced motion */
  --_transition: var(--_motion-reduced);

  /* set the transition to our adaptive transition custom property*/
  transition: var(--_transition);

  /* if motion is ok, update the adaptive prop to the respective transition prop */
  @media (prefers-reduced-motion: no-preference) {
    --_transition: var(--_motion-ok);
  }
}

אחרי שמבצעים את הפעולות שלמעלה, אפשר לבצע שינויים ב-box-shadow, ב-background-color, ב-transform וב-outline-offset, וכך לתת למשתמש משוב נחמד בממשק המשתמש על כך שהאינטראקציה שלו התקבלה.

בשלב הבא, מוסיפים קצת יותר עניין למצב :active על ידי שינוי translateY קצת, כדי לתת ללחצן אפקט לחיצה נחמד:

.fab {
  

  &:active {
    @media (prefers-reduced-motion: no-preference) {
      transform: translateY(2%);
    }
  }
}

לבסוף, מעבירים את השינויים בסמל ה-SVG בלחצנים:

.fab {
  

  &[data-icon="plus"]:hover > svg {
    transform: rotateZ(.25turn);
  }

  & > svg {
    @media (prefers-reduced-motion: no-preference) {
      will-change: transform;
      transition: transform .5s var(--ease-squish-3);
    }
  }
}

סיכום

עכשיו, אחרי שסיפרתי לך איך עשיתי את זה, איך היית עושה את זה? 🙂

נרחיב את הגישות שלנו ונלמד את כל הדרכים לפיתוח באינטרנט.

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

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

עדיין אין מה לראות כאן.

משאבים