משתני CSS, שנקראים בצורה מדויקת יותר מאפיינים מותאמים אישית של CSS, מגיעים ל-Chrome 49. הם יכולים להיות שימושיים לצמצום חזרות ב-CSS, וגם לאפקטים עוצמתיים בזמן הריצה, כמו החלפת עיצוב, ויכולת הרחבה/מילוי של תכונות CSS עתידיות.
עומס CSS
כשמתכננים אפליקציה, מקובל להקצות קבוצה של צבעי המותג שאפשר יהיה לעשות בהם שימוש חוזר כדי לשמור על עקביות במראה של האפליקציה. לצערנו, חזרה על ערכי הצבעים האלה שוב ושוב ב-CSS היא לא רק מטלה, אלא גם שגורמת לשגיאות. אם בשלב מסוים תצטרכו לשנות אחד מהצבעים, תוכלו להשתמש ב'חיפוש והחלפה' בכל הפריטים, אבל בפרויקט גדול מספיק זה עלול להיות מסוכן.
לאחרונה, מפתחים רבים פנו למעבדים מראש של CSS כמו SASS או LESS, שמאפשרים לפתור את הבעיה הזו באמצעות משתני מעבד מראש. הכלים האלה שיפרו משמעותית את הפרודוקטיביות של המפתחים, אבל למשתנים שבהם הם משתמשים יש חיסרון משמעותי – שהם סטטיים ואי אפשר לשנות אותם בזמן הריצה. הוספת היכולת לשנות משתנים בזמן הריצה פותחת את הדלת לדברים כמו עיצוב דינמי של אפליקציות, אלא גם השלכות משמעותיות על העיצוב הרספונסיבי, והפוטנציאל לבצע פוליגונים לתכונות של CSS בעתיד. עם השקת Chrome 49, היכולות האלה זמינות עכשיו בצורת מאפיינים מותאמים אישית של CSS.
מאפיינים מותאמים אישית על קצה המזלג
נכסים מותאמים אישית מוסיפים שתי תכונות חדשות לארגז הכלים של שירותי CSS:
- היכולת של המחבר להקצות ערכים שרירותיים לנכס עם שם שנבחר על ידי המחבר.
- הפונקציה
var()
, שמאפשרת למחבר להשתמש בערכים האלה במאפיינים אחרים.
הנה דוגמה מהירה להמחשה
:root {
--main-color: #06c;
}
#foo h1 {
color: var(--main-color);
}
--main-color
הוא מאפיין מותאם אישית שהוגדר על ידי המחבר, עם הערך #06c. חשוב לזכור שכל המאפיינים המותאמים אישית מתחילים בשני מקפים.
הפונקציה var()
מאחזרת ומחליפה את עצמה בערך המאפיין המותאם אישית, והתוצאה היא color: #06c;
. כל עוד המאפיין המותאם אישית מוגדר במקום כלשהו בגיליון הסגנון הוא צריך להיות זמין לפונקציה var
.
התחביר עשוי להיראות קצת מוזר בהתחלה. מפתחים רבים שואלים, "למה לא להשתמש ב-$foo
בשמות המשתנים?" הגישה נבחרה במיוחד כגמישה ככל האפשר, ועלולה לאפשר גם שימוש בפקודות מאקרו $foo
בעתיד.
כדי לקבל רקע, אפשר לקרוא את הפוסט הזה של אחד ממחברי המפרט, Tab Atkins.
תחביר של מאפיינים מותאמים אישית
התחביר של מאפיין מותאם אישית הוא פשוט.
--header-color: #06c;
שימו לב שמאפיינים מותאמים אישית הם תלויי אותיות רישיות, לכן --header-color
ו---Header-Color
הם מאפיינים מותאמים אישית שונים. התחביר המותר למאפיינים מותאמים אישית נראה פשוט, אבל הוא למעשה די גמיש. לדוגמה, זהו מאפיין מותאם אישית תקין:
--foo: if(x > 5) this.width = 10;
זה לא יהיה שימושי כמשתנה, אבל הוא לא יהיה חוקי בכל מאפיין רגיל, אבל ייתכן שהמערכת תוכל לקרוא אותו ולבצע בו פעולות באמצעות JavaScript בזמן הריצה. כלומר, נכסים מותאמים אישית יכולים לאפשר שימוש בכל מיני שיטות מעניינות שלא ניתן להשתמש בהן כרגע במעבדי ה-CSS הקיימים. אז אם אתם חושבים "yawn יש לי SASS אז למי אכפת...", בדקו שוב! אלה לא המשתנים שאתם רגילים לעבוד איתם.
המפל
נכסים מותאמים אישית פועלים לפי כללי דירוג רגילים, כך שאפשר להגדיר את אותו נכס ברמות ספציפיות שונות
:root { --color: blue; }
div { --color: green; }
#alert { --color: red; }
* { color: var(--color); }
<p>I inherited blue from the root element!</p>
<div>I got green set directly on me!</div>
<div id="alert">
While I got red set directly on me!
<p>I’m red too, because of inheritance!</p>
</div>
כלומר, אפשר להשתמש במאפיינים מותאמים אישית בתוך שאילתות מדיה כדי לעזור בתכנון רספונסיבי. דוגמה לשימוש אפשרי היא להרחיב את השוליים סביב הרכיבים העיקריים של חלוקת המסך ככל שגודל המסך גדל:
:root {
--gutter: 4px;
}
section {
margin: var(--gutter);
}
@media (min-width: 600px) {
:root {
--gutter: 16px;
}
}
חשוב לציין שאי אפשר להשתמש בקטע הקוד שלמעלה באמצעות מעבדי CSS של היום, כי הם לא יכולים להגדיר משתנים בתוך שאילתות מדיה. היכולת הזו פותחת הרבה הזדמנויות!
אפשר גם להשתמש במאפיינים מותאמים אישית שמפיקים את הערך שלהם מנכסים מותאמים אישית אחרים. האפשרות הזו שימושית במיוחד ליצירת נושאים:
:root {
--primary-color: red;
--logo-text: var(--primary-color);
}
הפונקציה var()
כדי לאחזר את הערך של מאפיין מותאם אישית ולהשתמש בו, צריך להשתמש בפונקציה var()
. התחביר של הפונקציה var()
נראה כך:
var(<custom-property-name> [, <declaration-value> ]? )
כאשר <custom-property-name>
הוא השם של מאפיין מותאם אישית שהוגדר על ידי המחבר, כמו --foo
, ו-<declaration-value>
הוא ערך חלופי שישמש כשהמאפיין המותאם אישית שמצוין לא חוקי. ערכים חלופיים יכולים להיות רשימה מופרדת בפסיקים, שתשולב לערך יחיד. לדוגמה, var(--font-stack,
"Roboto", "Helvetica");
מגדיר חלופה ל-"Roboto", "Helvetica"
. חשוב לזכור שערכים מקוצרים, כמו אלה שמשמשים למרווחים ולרווחים פנימיים, לא מופרדים בפסיקים, ולכן חלופה מתאימה לרווח פנימי תיראה כך.
p {
padding: var(--pad, 10px 15px 20px);
}
בעזרת ערכי ברירת המחדל האלה, מחברי רכיבים יכולים לכתוב סגנונות הגנה לאלמנט שלהם:
/* In the component’s style: */
.component .header {
color: var(--header-color, blue);
}
.component .text {
color: var(--text-color, black);
}
/* In the larger application’s style: */
.component {
--text-color: #080;
/* header-color isn’t set,
and so remains blue,
the fallback value */
}
השיטה הזו שימושית במיוחד לעיצוב רכיבי אינטרנט שמשתמשים בהצללה ב-DOM, כי מאפיינים מותאמים אישית יכולים לעבור את גבולות הצללית. מחבר של רכיבי אינטרנט יכול ליצור עיצוב ראשוני באמצעות ערכי חלופות, ולחשוף 'הוקים' (hooks) לתוכן בצורת מאפיינים מותאמים אישית.
<!-- In the web component's definition: -->
<x-foo>
#shadow
<style>
p {
background-color: var(--text-background, blue);
}
</style>
<p>
This text has a yellow background because the document styled me! Otherwise it
would be blue.
</p>
</x-foo>
/* In the larger application's style: */
x-foo {
--text-background: yellow;
}
כשמשתמשים ב-var()
, יש כמה דברים שכדאי לשים לב אליהם. משתנים לא יכולים להיות שמות של נכסים. לדוגמה:
.foo {
--side: margin-top;
var(--side): 20px;
}
עם זאת, היא לא מקבילה להגדרה של margin-top: 20px;
. במקום זאת, ההצהרה השנייה לא תקינה ומוצגת כשגיאה.
באופן דומה, אי אפשר ליצור ערך (באופן תמי) כאשר חלק ממנו מסופק על ידי משתנה:
.foo {
--gap: 20;
margin-top: var(--gap)px;
}
שוב, זה לא שווה ערך להגדרה margin-top: 20px;
. כדי ליצור ערך צריך משהו אחר: הפונקציה calc()
.
יצירת ערכים באמצעות calc()
אם זו הפעם הראשונה שאתם משתמשים בה, הפונקציה calc()
היא כלי קטן מאוד שמאפשר לבצע חישובים כדי לקבוע ערכי CSS. הוא נתמך בכל הדפדפנים המתקדמים, ואפשר לשלב אותו עם מאפיינים מותאמים אישית כדי ליצור ערכים חדשים. לדוגמה:
.foo {
--gap: 20;
margin-top: calc(var(--gap) * 1px); /* niiiiice */
}
עבודה עם מאפיינים מותאמים אישית ב-JavaScript
כדי לקבל את הערך של מאפיין מותאם אישית בזמן ריצה, צריך להשתמש ב-method getPropertyValue()
של האובייקט המחושב CSSStyleDeclaration.
/* CSS */
:root {
--primary-color: red;
}
p {
color: var(--primary-color);
}
<!-- HTML -->
<p>I’m a red paragraph!</p>
/* JS */
var styles = getComputedStyle(document.documentElement);
var value = String(styles.getPropertyValue('--primary-color')).trim();
// value = 'red'
באופן דומה, כדי להגדיר את הערך של מאפיין מותאם אישית בזמן הריצה, משתמשים ב-method setProperty()
של האובייקט CSSStyleDeclaration
.
/* CSS */
:root {
--primary-color: red;
}
p {
color: var(--primary-color);
}
<!-- HTML -->
<p>Now I’m a green paragraph!</p>
/* JS */
document.documentElement.style.setProperty('--primary-color', 'green');
אפשר גם להגדיר את הערך של המאפיין המותאם אישית כך שיפנה למאפיין מותאם אישית אחר בזמן ריצה, באמצעות הפונקציה var()
בקריאה ל-setProperty()
.
/* CSS */
:root {
--primary-color: red;
--secondary-color: blue;
}
<!-- HTML -->
<p>Sweet! I’m a blue paragraph!</p>
/* JS */
document.documentElement.style.setProperty('--primary-color', 'var(--secondary-color)');
מכיוון שמאפיינים מותאמים אישית יכולים להתייחס למאפיינים מותאמים אישית אחרים בגיליון הסגנונות, אפשר לדמיין איך זה יכול להוביל לכל מיני אפקטים מעניינים בזמן הריצה.
תמיכה בדפדפנים
כרגע יש תמיכה במאפיינים מותאמים אישית ב-Chrome 49, Firefox 42, Safari 9.1 ו-iOS Safari 9.3.
הדגמה (דמו)
כדאי לנסות את הדוגמה כדי לקבל הצצה לכל השיטות המעניינות שאפשר להשתמש בהן עכשיו בזכות מאפיינים מותאמים אישית.
קריאה נוספת
אם אתם מעוניינים לקבל מידע נוסף על נכסים מותאמים אישית, פיליפ וולטון מצוות Google Analytics כתב סקירה כללית על הסיבות לכך שהוא אוהב נכסים מותאמים אישית. תוכלו גם לעקוב אחר ההתקדמות שלו בדפדפנים אחרים בכתובת chromestatus.com.