נתיבים, צורות, חיתוך ומסכות

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

נתיבים וצורות

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

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

צורות בסיסיות

circle() וגם ellipse()

הפונקציות circle() ו-ellipse() מגדירות צורות עגולות ואליפטיות עם רדיוסים יחסיים לרכיב. הפונקציה circle() מקבלת כארגומנט גודל או אחוז יחיד. כברירת מחדל, שתי הפונקציות ממקמות את הצורה ביחס למרכז הרכיב. שניהם מקבלים מיקום אופציונלי אחרי מילת המפתח at, שאפשר לציין אותו כאורכים, כאחוזים או כמילות מפתח למיקום.

.my-element {
  width: 60px;
  height: 60px;
  background: blue;
  clip-path: circle(50%);
}

כשמזינים את הארגומנט 50% בפונקציה circle(), נוצר עיגול מושלם.

בדוגמה הקודמת מוצג נתיב חיתוך מעגלי באמצעות הפונקציה circle(). שימו לב: רדיוס של 50% יוצר מעגל ברוחב המלא של הרכיב. הפונקציה ellipse() מקבלת שני ארגומנטים שמייצגים את הרדיוס האופקי והאנכי של הצורה.

.my-element {
  width: 60px;
  height: 60px;
  background: blue;
  clip-path: ellipse(50% 25%);
}

הפונקציה ellipse()‎ יוצרת אליפסה באמצעות ארגומנטים של אחוזים. אם משתמשים בערכים של 50% ו-25%, נוצרת אליפסה שמתרחבת פי שניים ברדיוס בציר X מאשר בציר Y.

בדוגמה הקודמת רואים נתיב חיתוך אליפטי באמצעות הפונקציה ellipse(). שימו לב: רדיוס של 50% יוצר אליפסה ברוחב המלא של הרכיב. בדוגמה הבאה מוצג אליפסה זהה שמוצבת כך שהמרכז שלה נמצא בחלק העליון של האלמנט.

.my-element {
  width: 60px;
  height: 60px;
  background: blue;
  clip-path: ellipse(50% 25% at center top);
}

rect() וגם inset()

הפונקציות rect() ו-inset() מספקות דרכים שונות להגדיר מלבן על ידי הגדרת המיקום של הצדדים שלו ביחס לצדדים של רכיב. כך אפשר ליצור מלבנים ששונים מבחינה ויזואלית מהתיבה שמוגדרת כברירת מחדל של הרכיב. אפשר להשתמש במילת המפתח round כדי ליצור מלבן עם פינות מעוגלות, באמצעות אותה תחביר כמו מאפיין הקיצור border-radius.

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

.my-element {
  width: 80px;
  height: 60px;
  background: blue;
  clip-path: rect(15px 75px 45px 10px);
}

הפונקציה rect() מקבלת ארבעה ארגומנטים להגדרת הגודל של מלבן. במקרה הזה, הארגומנטים הם 15px,‏ 75px,‏ 45px ו-10px.

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

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

.my-element {
  width: 80px;
  height: 60px;
  background: blue;
  clip-path: inset(15px 5px 15px 10px);
}

הפונקציה inset() יכולה להפחית מהגודל המובנה של הרכיב. הארגומנטים של הפונקציה הזו בתרשים הזה הם 15px,‏ 5px,‏ 15px ו-10px.

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

הפונקציות rect() ו-inset() מקבלות באופן אופציונלי את מילת המפתח round כדי ליצור מלבן עם פינות מעוגלות, באמצעות אותה תחביר כמו מאפיין הקיצור border-radius. בדוגמה הבאה מוצגות גרסאות מעוגלות של המלבנים שמוצגים למעלה.

.rounded-rect {
  width: 80px;
  height: 60px;
  background: blue;
  clip-path: inset(15px 5px 15px 10px round 5px);
}

.rounded-inset {
  width: 80px;
  height: 60px;
  background: blue;
  clip-path: inset(15px 5px 15px 10px round 5px);
}

polygon()

בצורות אחרות, כמו משולשים, מחומשים, כוכבים וכו', הפונקציה polygon() מאפשרת ליצור צורות על ידי חיבור של כמה נקודות באמצעות קווים ישרים. הפונקציה polygon() מקבלת רשימה של זוגות שמורכבים משתי יחידות אורך או אחוזים. כל זוג מתאר נקודה במצולע: הערך הראשון הוא המרחק מהקצה השמאלי של הרכיב, והערך השני הוא המרחק מהקצה העליון של הרכיב. לא צריך לסגור את הפוליגון, כי הוא יושלם על ידי חיבור הנקודה האחרונה עם הנקודה הראשונה.

.my-element {
  width: 60px;
  height: 60px;
  background: blue;
  clip-path: polygon(
    50% 0,
    0 100%,
    100% 100%
  );
}

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

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

כברירת מחדל, הפונקציה polygon() מעבדת אזורים חופפים כמלאים. אפשר לשנות את ההתנהגות הזו באמצעות ארגומנט ראשון אופציונלי שנקרא כלל המילוי. כדי לעבור בין אזורים מלאים לאזורים לא מלאים, מגדירים את כלל המילוי ל-evenodd. כדי להשתמש בכלל המילוי שמוגדר כברירת מחדל, מגדירים את הערך nonzero.

בדוגמה הקודמת מוצגת הפונקציה polygon() עם פונקציות טריגונומטריות ליצירת מצולעים רגילים וצורות של כוכבים. הפעולה הזו לא יוצרת את המצולע המשוכלל הגדול ביותר שאפשר להכניס לרכיב או למרכז אותו – אתם יכולים לנסות לעשות זאת בעצמכם. צורות הכוכבים בדוגמה הזו ממחישות גם את כללי המילוי nonzero ו-evenodd.

צורות מורכבות

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

path()

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

הפונקציה path() לא משתמשת ביחידות גודל של CSS, וכל הערכים מתפרשים כפיקסלים. כלומר, צורות שנוצרו באמצעות פונקציית הנתיב לא מגיבות לגודל של האלמנט או של הגורם המכיל. מומלץ להשתמש ב-path() רק לצורות עם מידות קבועות.

shape()

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

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

חיתוך

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

כמו שראיתם בדוגמאות בקטע הקודם, אפשר להשתמש בכל אחת מהפונקציות של צורה בסיסית או נתיב כ-clip-path. המאפיין clip-path תומך גם בנתיבים שמוגדרים ברכיב clipPath של SVG, שיכול להיות מוטמע או בקובץ נפרד.

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

בתרשים שלמעלה אפשר לראות איך הוספה של clip-path לרכיב תמונה משנה את האזור הגלוי של התמונה. נתיב הגזירה העליון משתמש בפונקציה circle(), בעוד שהתחתון משתמש ב-SVG clipPath. הערה: כברירת מחדל, העיגול שנוצר באמצעות הפונקציה circle() ממוקם במרכז של הרכיב.

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

חיתוך באמצעות צורות

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

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

תיבת ההפניה של נתיב חיתוך

כברירת מחדל, נתיב החיתוך של רכיב כולל את הגבול של הרכיב. כשמשתמשים באחת מפונקציות הצורה הבסיסיות, אפשר להגדיר את תיבת ההפניה של נתיב הגזירה כך שתכלול רק את האזור של הרכיב בתוך הגבול. הערכים התקפים לתיבת ההפניה הם stroke-box (ברירת המחדל) ו-fill-box (לכלול רק את האזור בתוך הגבול).

בדוגמה הקודמת מוצגים רכיבים עם גבול גדול (20px), שכל אחד מהם משתמש בפונקציה inset() כדי להגדיר את clip-path. הרכיב שמוגדר לחיתוך ביחס לגבול של הרכיב עדיין מציג חלק מהגבול. האלמנטים שנחתכים ביחס לאזור בתוך הגבול לא מציגים גבול והם קטנים יותר, גם אם ערך השוליים הפנימיים זהה.

חיתוך עם גרפיקה

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

<img id="kitten" src="kitten.png">

<svg>
  <defs>
    <clipPath id="kitten-clip-shape">
      <circle cx="130" cy="175" r="100" />
    </clipPath>
  </defs>
</svg>

<style>
  #kitten {
    clip-path: url(#kitten-clip-shape);
  }
</style>

בדוגמה הקודמת, ה-clipPath עם id של kitten-clip-shape מוחל על האלמנט <img>. במקרה הזה, מסמך ה-SVG מוטמע ב-HTML. אם מסמך ה-SVG הוא קובץ חיצוני בשם kitten-clipper.svg, אז ההפניה ל-clipPath תהיה url(kitten-clipper.svg#kitten-clip-shape).

מסקינג

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

כדי להחיל מסכה, מגדירים את המאפיין mask-image. המאפיין הזה מקבל תמונה אחת או יותר, מעברי צבע או הפניות לרכיבי <mask> במסמך SVG. אפשר להוסיף כמה תמונות מסכה, ולהפריד ביניהן באמצעות פסיקים.

.my-element {
  mask-image: url(my-mask.png),
              linear-gradient(black 0%, transparent 100%);
}

בדוגמה הקודמת, .my-element מוסתר באמצעות תמונת PNG, ואחריה מעבר צבע לינארי. כברירת מחדל, כמה מסכות מתווספות זו לזו כדי ליצור את המסכה הסופית.

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

מיסוך לפי אלפא לעומת מיסוך לפי בהירות

אפשר להחיל מסכה באמצעות alpha או luminance של התמונה. כשמבצעים מיסוך על סמך alpha, השקיפות של כל פיקסל בתמונת המסכה מוחלת על הרכיב, בלי להתייחס לפרטי הצבע של הפיקסל. כשמחילים מסכה על סמך luminance, גם השקיפות וגם הערך של כל פיקסל (בהירות או כהות) מוחלים על הרכיב. הסתרת חלקים לפי בהירות מתייחסת לצבעים בהירים כאל צבעים גלויים ולצבעים כהים כאל צבעים לא גלויים.

כדי להגדיר את מצב המיסוך, משתמשים במאפיין mask-mode. כברירת מחדל, הנכס mask-mode מוגדר לערך match-source, שמגדיר מצב על סמך סוג תמונת המסכה. עבור תמונות ומעברי צבע, ברירת המחדל היא alpha. במסכות SVG, ערך ברירת המחדל יהיה הערך של המאפיין mask-type של רכיב <mask> או luminance, אם לא מוגדר mask-type.

בדוגמה הקודמת, תבנית בדיקה שמציגה ערכי צבע ואלפא שונים משמשת כמסכה. אם מעבירים את המתג mask-mode, אפשר לראות שמצב alpha מבוסס על שקיפות, ומצב luminance מבוסס על בהירות הצבע וגם על שקיפות.

מאפייני מיסוך נוספים

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

נכס תיאור
mask-clip

הגדרה של תיבת ההפניה של האלמנטים שמוחל עליהם מיסוך. ברירת המחדל היא border-box.

mask-composite

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

mask-origin

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

mask-position

מגדיר את המיקום של מסכה ביחס ל-mask-origin. אפשר להזין ערכים של מילות מפתח למיקום כמו top או center, אחוזים, יחידות מידה או ערכים יחסיים למילת מפתח למיקום. התנאי הזה מתנהג באופן דומה ל-background-position ומקבל את אותם סוגים של ארגומנטים.

mask-repeat

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

mask-size

ההגדרה הזו קובעת את גודל המסכה ביחס לגודל של האלמנט המוסתר. ברירת המחדל היא auto. התנאי הזה מתנהג באופן דומה ל-background-size ומקבל את אותם סוגים של ארגומנטים.

קיצור הדרך למסיכה

אפשר להגדיר כמה מאפייני מסכה בבת אחת באמצעות קיצור הדרך למסכה. האפשרות הזו יכולה לפשט את הגדרת כמה מסכות, כי היא מקבצת את כל המאפיינים של כל מסכה. הקיצור של המסכה שווה להגדרת המאפיינים האלה לפי הסדר: mask-image,‏ mask-mode,‏ mask-position,‏ mask-size,‏ mask-repeat,‏ mask-origin,‏ mask-clip ו-mask-composite. לא צריך לכלול את כל המאפיינים, ומאפיינים שלא נכללים יאופסו לערך הראשוני שלהם. התמיכה היא בעד שמונה מאפיינים לכל מסכה, ולכן כדאי להשתמש בהפניה המלאה.

.longhand {
  mask-image: linear-gradient(white, black),
              linear-gradient(90deg, black, transparent);
  mask-mode: luminance, alpha;
  mask-position: bottom left, top right;
  mask-size: 50% 50%, 30% 30%;
}

.shorthand {
  mask: linear-gradient(white, black) luminance bottom left / 50% 50%,
        linear-gradient(90deg, black, transparent) alpha top right / 30% 30%;
}

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

טקסט זורם סביב רכיבים צפים

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

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

המאפיין shape-outside מקבל גם תמונה או מעבר צבעים. בדומה למסכות, הגבולות של הצורה ייקבעו לפי השקיפות של התמונה או המעבר ההדרגתי. המאפיין shape-image-threshold מגדיר אילו רמות שקיפות נכללות בתוך הצורה.

צורות באנימציה

יצירת אנימציה של clip-path

אפשר להנפיש את המאפיין clip-path, ולעבור בצורה חלקה מצורה לצורה. כדי ליצור אנימציות חלקות, צריך להשתמש באותה פונקציית צורה לכל מסגרת מפתח. כשמשתמשים בפונקציות polygon() או shape(), צריך להשתמש באותו מספר נקודות בכל מסגרת מפתח.

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

יצירת אנימציה עם offset-path

אפשר גם להנפיש אלמנטים לאורך הנתיבים שנוצרו באמצעות פונקציות הצורה האלה. המאפיין offset-path מגדיר את הצורה שתשמש כנתיב, והמאפיין offset-distance מגדיר את המיקום לאורך הנתיב הזה. אפשר גם להשתמש בפונקציה ray() עם המאפיין offset-path כדי ליצור אנימציה לאורך קו ישר.

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

בדיקת ההבנה

אילו מהפונקציות הבאות הן פונקציות צורה תקינות?

circle()
תשובה נכונה!
square()
תשובה לא נכונה.
hexagon()
תשובה לא נכונה.
polygon()
תשובה נכונה!
rectangle()
תשובה לא נכונה.
inset()
תשובה נכונה!

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

True
תשובה לא נכונה.
לא נכון
תשובה נכונה!

נכון או לא נכון: הגדרת נתיב חיתוך של רכיב לא תשנה את זרימת הטקסט סביב הרכיב

True
תשובה נכונה!
לא נכון
תשובה לא נכונה.

איזו מהאפשרויות הבאות יכולה לשמש כנתיב חיתוך?

צורה בסיסית
תשובה נכונה!
רכיב clipMask של SVG
תשובה נכונה!
תמונת מפת סיביות
תשובה לא נכונה.
הדרגתי
תשובה לא נכונה.

באילו מהאפשרויות הבאות אפשר להשתמש כמסכה?

תמונת מפת סיביות
תשובה נכונה!
הדרגתי
תשובה נכונה!
רכיב מסכה בפורמט SVG
תשובה נכונה!
צורה בסיסית, כמו circle() או rect()
תשובה לא נכונה.