משתני CSS – למה זה חשוב לכם?

משתני CSS, שנקראים בצורה מדויקת יותר מאפיינים מותאמים אישית של CSS, נוחתות ב-Chrome 49. הם יכולים להיות שימושיים לצמצום חזרות ב-CSS, גם כדי לקבל אפקטים עוצמתיים בזמן הריצה, כמו מעבר בין עיצובים, הרחבה/מילוי פוליגוני של תכונות CSS עתידיות.

עומס בשירות ה-CSS

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

לאחרונה, מפתחים רבים הנעזרים במעבדי עיבוד מראש לשירותי CSS, כמו SASS או פחות משתמשים בפתרון הבעיה הזו באמצעות שימוש במשתנים של מעבד מידע מראש. בזמן הכלים האלה שיפרו משמעותית את הפרודוקטיביות של המפתחים, יש להם מחסרון משמעותי: שהם סטטיים ואי אפשר השתנה בזמן הריצה. הוספת היכולת לשנות משתנים בזמן ריצה לא רק פותחת את הדלת לדברים כמו עיצוב דינמי של אפליקציות, אבל יש לה גם השלכות לעיצוב רספונסיבי והפוטנציאל למילוי פוליגונים ל-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 אטקינס.

תחביר של מאפיינים מותאמים אישית

התחביר של נכס מותאם אישית הוא פשוט.

--header-color: #06c;

חשוב לשים לב שמאפיינים מותאמים אישית הם תלויי אותיות רישיות, לכן --header-color וגם --Header-Color הם מאפיינים מותאמים אישית שונים. אומנם הן נראות פשוטות בערך המקורי, התחביר שמותר לנכסים מותאמים אישית הוא למעשה די מתירניות. לדוגמה, המאפיין הבא הוא מאפיין חוקי בהתאמה אישית:

--foo: if(x > 5) this.width = 10;

אמנם זה לא יועיל בתור משתנה, אבל הוא לא יהיה חוקי בכל נכס רגיל, ניתן לקרוא אותו ולפעול על פיו עם JavaScript ב בסביבת זמן ריצה. המשמעות היא שלנכסים מותאמים אישית יש פוטנציאל לאפשר גישה לכל הסוגים של שיטות מעניינות שאי אפשר להשתמש בהן כרגע בעזרת המעבדים המקדימים של שירותי CSS. ככה. אם אתם חושבים "פיהוק יש לי 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

כדי לקבל את הערך של מאפיין מותאם אישית בזמן ריצה, צריך להשתמש בפונקציה 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'

באופן דומה, כדי להגדיר את הערך של מאפיין מותאם אישית בזמן ריצה, צריך להשתמש בפונקציה השיטה 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.