שימוש ב-shape() לחיתוך רספונסיבי

תאריך פרסום: 8 באפריל 2025

בעזרת המאפיין clip-path אפשר לשנות את הצורה של אלמנט על ידי חיתוך לעיגול, לפוליגון או אפילו לנתיב SVG. עם זאת, לפני הגרסאות Chrome 135 ו-Safari 18.4, צריך היה לבחור בין פוליגונים עם תגובה דינמית לבין צורות מורכבות יותר שלא מגיבות לשינויים במסך באמצעות נתיבים של SVG. בעזרת הפונקציה החדשה shape(), אפשר להשתמש ב-clip-path כדי לחתוך את האלמנט לצורה שאינה פוליגון, וגם רספונסיבית.

Browser Support

  • Chrome: 135.
  • Edge: 135.
  • Firefox Technology Preview: supported.
  • Safari: 18.4.

Source

יצירת צורה של דגל

לדוגמה, אפשר להשוות בין יצירת צורה של דגל באמצעות clip-path: path() לבין יצירת צורה של דגל באמצעות clip-path: shape().

צורה של דגל ירוק עם קווים מעוגלים בחלק העליון ובחלק התחתון.

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

יצירת הדגל באמצעות clip-path: path()

אפשר לייצג צורה כמו הדגל הזה באמצעות נתיב SVG:

.flag {
  clip-path: path(
    "M 0 20 \
     C 25 0 75 40 100 20 \
     V 80 \
     C 75 100 25 60 0 80 \
     z");
}

כדי להבין את הנושא, נתאר את הנתיב ב-SVG כסדרה של פקודות נתיב:

  1. עוברים אל 0, 20.
  2. עקומה ל-100, 20 באמצעות נקודות בקרה (25,0 ו-75, 40).
  3. קו אנכי עד 80.
  4. עקומה ל-0,‏ 80 באמצעות נקודות בקרה (75,‏ 100 ו-25,‏ 50).
  5. סוגרים את הנתיב (קו ל-0,20).

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

לדוגמה, אם רוצים לשנות את הגודל של כל המלבן, אבל לשמור על הגובה והרוחב של העקומות ב-20px, קובץ ה-SVG לא יעמוד במשימה.

יצירת הדגל באמצעות shape()

השוואה של אותה תוצאה באמצעות shape(). פונקציית הצורה מקבלת סדרה של פקודות, בדומה לפקודות הנתיב ב-SVG. עם זאת, הפקודות האלה מקבלות אורך ושיעור אחוזים ב-CSS, בכל יחידת CSS.

הקוד הבא ב-CSS ממיר את הדגל a shape() ליחידות אחוז:

.flag {
  clip-path: shape(from 0% 20%,
     curve to 100% 20% with 25% 0% / 75% 40%,
     vline to 80%,
     curve to 0% 80% with 75% 100% / 25% 60%,
     close
  );
}

עיצוב רספונסיבי

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

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

.flag {
  clip-path: shape(from 0% 20px,
     curve to 100% 20px with 25% 0% / 75% 40px,
     vline to calc(100% - 20px),
     curve to 0% calc(100% - 20px) 
           with 75% 100% / 25% calc(100% - 40px),
     close
  );
}

הוספת מאפיינים ואנימציות מותאמים אישית

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

.flag {
  --wave-height: 40px;
  clip-path: shape(
    from 0px var(--wave-height),
    curve to 100% var(--wave-height) 
          with 25% 0px / 75% calc(var(--wave-height) * 2),
    vline to calc(100% - var(--wave-height)),
    curve to 0 calc(100% - var(--wave-height))
          with 75% 100% / 25% calc(100% - var(--wave-height) * 2),
    close
  )
}

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

@property --animated-wave-height {
  syntax: "<length>";
  inherits: false;
  initial-value: 40px;
}

@keyframes curve {
  from { --animated-wave-height: 0px; }
  to { --animated-wave-height: 180px; }
}

.flag {
  width: 600px;
  height: 400px;
  background: green;
  animation: curve 1s infinite alternate;
  --wave-height: calc(min(var(--animated-wave-height, 40px), 40%));
  clip-path: shape(
    from 0px var(--wave-height),
    curve to 100% var(--wave-height)
          with 25% 0px / 75% calc(var(--wave-height) * 2),
    vline to calc(100% - var(--wave-height)),
    curve to 0 calc(100% - var(--wave-height)) 
          with 75% 100% / 25% calc(100% - var(--wave-height) * 2),
    close
  )
}

נסה את ההדגמה

ב-Chrome 135 או ב-Safari 18.4, אפשר לראות את צורת הדגל האנימציוני שנוצר באמצעות clip-path: shape() בדמו הזה ב-CodePen.

סיכום

clip-path: shape() מאפשרת לחתוך את הרכיב באמצעות צורות שרירותיות ותגובה, שקודם אפשר היה ליצור רק באמצעות שיטות כמו מעברים conic או קובצי SVG שנוצרו באמצעות JavaScript.

במפרט מפורט התחביר המלא.

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