אנימציות של גבולות CSS

כמה דרכים להוסיף אנימציה לגבול ב-CSS

הגדרת גבולות

יש כמה שיטות להגדרת גבול לרכיב: border,‏ outline ו-box-shadow. כפי שמפורט במאמר 3 השיטות ב-CSS להוספת גבולות לאלמנטים מאת סטפני אקלס (Stephanie Eckles), לכל גישה יש יתרונות וחסרונות משלה – במיוחד כשמדובר בהוספת אנימציה לגבולות. הסיבה העיקרית לכך שלא משתמשים ב-border CSS תקין היא למטרות אנימציה.

אנימציות של גבולות באמצעות outline-offset מאת Kevin J. Powell

מאמר שמשך את תשומת ליבי לאחרונה הוא אנימציה נהדרת של גבולות CSS, שבו Coco בוחנת אפשרויות נוספות. הוספת תוכן שנוצר באמצעות ::before ו-::after יוצרת גבול מלאכותי שמקבל אנימציה.

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

אנימציות של גבולות באמצעות תוכן שנוצר על ידי Coco

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

שמירה על מודל התיבה

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

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

העקרונות הבסיסיים

נתחיל ביצירת גבול מקווקו ובהוספת כמה רקעים.

/* Size of the border */
--border-size: 0.5rem;

/* Create a dotted border */
border: var(--border-size) dotted lime;

/* Create two background layers:
   1. A white semi-transparent
   2. A layer with the colored boxes
 */
background-image:
  linear-gradient(to right, rgb(255 255 255 / 0.5), rgb(255 255 255 / 0.5)),

  conic-gradient(
    from 45deg,
    #d53e33 0deg 90deg,
    #fbb300 90deg 180deg,
    #377af5 180deg 270deg,
    #399953 270deg 360deg
  )
;

שינוי הגודל של הרקעים באמצעות background-origin

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

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

תמיכה בדפדפנים

  • Chrome: ‏ 1.
  • Edge: ‏ 12.
  • Firefox: 4.
  • Safari: 3.

מקור

מה אסור לעשות
/* Manually add or offset the size of the border where needed */
background-position: calc(var(--border-size) * -1) calc(var(--border-size) * -1);
background-size: calc(var(--border-size) * 2 + 100%) calc(var(--border-size) * 2 + 100%);
מה מותר לעשות
background-origin: border-box;

הוספה אחת משפרת את המראה של הכול:

צמצום שכבת הרקע הלבן באמצעות background-clip

עכשיו, כשהרקעים תופסים את כל המרחב, צריך לצמצם שוב את השכבה השקופה למחצה. במקום להתעסק שוב ב-background-size, יש דרך קלה יותר לעשות זאת: משתמשים ב-background-clip ומגדירים אותו ל-padding-box. כך הרקע לא מצויר יותר מתחת לאזור של הגבול.

תמיכה בדפדפנים

  • Chrome: ‏ 1.
  • Edge: ‏ 12.
  • Firefox: 4.
  • Safari: 5.

מקור

background-clip:
  padding-box, /* Clip white semi-transparent to the padding-box */
  border-box /* Clip colored boxes to the border-box (default) */
;

לבסוף, מגדירים את השוליים כ-transparent כדי ליהנות מהאפקט המלא.

border: 0.3rem dotted transparent;

Animation

כדי לשחזר את האנימציה של המסגרת, אפשר לשנות את זווית ההתחלה של conic-gradient.

--angle: 0deg;
conic-gradient(
  from var(--angle),
  #d53e33 0deg 90deg,
  #fbb300 90deg 180deg,
  #377af5 180deg 270deg,
  #399953 270deg 360deg
);

בעזרת ‎@property, זה קל מאוד בדפדפנים שתומכים בכך:

תמיכה בדפדפנים

  • Chrome: ‏ 85.
  • Edge: ‏ 85.
  • Firefox: ‏ 128.
  • Safari: 16.4.

מקור

@property --angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

@keyframes rotate {
  to {
    --angle: 360deg;
  }
}

כשמשלבים את כל החלקים, הקוד נראה כך:

תוכן בונוס: border-image

גישה שסקרנו בעבר לציור גבול עם שיפוע היא שימוש ב-CSS border-image.

תמיכה בדפדפנים

  • Chrome: ‏ 16.
  • Edge: ‏ 12.
  • Firefox: ‏ 15.
  • Safari: 6.

מקור

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

/* Create a border */
border: 0.5rem solid transparent;

/* Paint an image in the border */
border-image:
  conic-gradient(
    from var(--angle),
    #d53e33 0deg 90deg,
    #fbb300 90deg 180deg,
    #377af5 180deg 270deg,
    #399953 270deg 360deg
  ) 1
;

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

  • border-image לא עוקב אחרי border-radius, והוא תמיד יישאר מלבני.
  • כשמגדירים את border-image-slice למלא, ה-border-image לא מצויר מתחת לקבוצה background אלא מעליה. זה יכול להיות בעייתי אם רוצים שהרקע יהיה שקוף למחצה.

לסיום

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