הרינדור של 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%);
}
בדוגמה הקודמת מוצג נתיב חיתוך מעגלי באמצעות הפונקציה circle()
. שימו לב: רדיוס של 50%
יוצר מעגל ברוחב המלא של הרכיב. הפונקציה ellipse()
מקבלת שני ארגומנטים שמייצגים את הרדיוס האופקי והאנכי של הצורה.
.my-element {
width: 60px;
height: 60px;
background: blue;
clip-path: ellipse(50% 25%);
}
בדוגמה הקודמת רואים נתיב חיתוך אליפטי באמצעות הפונקציה 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()
. המאפיינים הם יחסי לקצוות העליון והימני של הרכיב, כפי שמוצג בתרשים.
הפונקציה inset()
מגדירה את המיקום של צלעות המלבן לפי המרחק פנימה מכל אחת מהצלעות של רכיב. הפונקציה מקבלת ארגומנט אחד עד ארבעה של יחידות גודל או אחוזים, ומאפשרת להגדיר כמה צדדים בבת אחת. אפשר לבחור בפונקציה inset()
כשרוצים מלבן שמשנה את הגודל שלו בהתאם לאלמנט, או מלבן ששומר על מרחק קבוע מקצוות האלמנט.
.my-element {
width: 80px;
height: 60px;
background: blue;
clip-path: 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()
מעבדת אזורים חופפים כמלאים. אפשר לשנות את ההתנהגות הזו באמצעות ארגומנט ראשון אופציונלי שנקרא כלל המילוי. כדי לעבור בין אזורים מלאים לאזורים לא מלאים, מגדירים את כלל המילוי ל-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 |
הגדרה של תיבת ההפניה של האלמנטים שמוחל עליהם מיסוך. ברירת המחדל היא |
mask-composite |
המאפיין קובע את האינטראקציה בין המסכות כשמחילים כמה מסכות על אותו רכיב. ברירת המחדל היא |
mask-origin |
הגדרה של תיבת ההפניה שמשמשת כמקור של מסכה. ברירת המחדל היא |
mask-position |
מגדיר את המיקום של מסכה ביחס ל- |
mask-repeat |
ההגדרה קובעת איך המסכה חוזרת על עצמה אם הרכיב המוסתר גדול יותר מהמסכה. ברירת המחדל היא |
mask-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()
באמצעות אחוזים
נכון או לא נכון: הגדרת נתיב חיתוך של רכיב לא תשנה את זרימת הטקסט סביב הרכיב
איזו מהאפשרויות הבאות יכולה לשמש כנתיב חיתוך?
clipMask
של SVGבאילו מהאפשרויות הבאות אפשר להשתמש כמסכה?
circle()
או rect()