CSS Variables (הנקראים רשמית CSS Custom Properties) מאפשרים לאחסן ערכים במקום אחד ולהשתמש בהם לאורך כל ה-stylesheet. פחות חזרות, קוד קריא יותר וגמישות אמיתית.
בניגוד למשתנים של preprocessors כמו Sass או Less, משתני CSS הם חלק מה-DOM. הם עוברים בתורשה (cascade), יורשים ערכים, וניתן לקרוא או לשנות אותם עם JavaScript בזמן ריצה.
מדוע להשתמש ב-CSS Variables?
CSS היא שפה דקלרטיבית, לא שפת תכנות. אך בכל אתר מורכב תמצאו ערכים שחוזרים עשרות פעמים – צבע מותג, יחידת ריווח, פונטים.
אם תרצו לשנות צבע כזה, תצטרכו לבצע Search & Replace על כל קבצי ה-CSS. משתני CSS פותרים את זה על ידי אחסון ערך במקום אחד והפנייה אליו מכל מקום.
יש גם ערך סמנטי. --main-text-color הרבה יותר ברור מ-#ffe01b, במיוחד כשאותו צבע מופיע בהקשרים שונים.
שימוש בסיסי ב CSS Variables
השימוש הבסיסי ב CSS Variable מתבצע בצורה הבאה:
הכרזה על משתנה:
element {
--main-bg-color: brown;
}שימוש במשתנה:
element {
background-color: var(--main-bg-color);
}הנה דוגמה פשוטה שיצרתי ב-CodePen שמדגימה משתני CSS בפעולה:
See the Pen CSS Variables Example by Roee Yossef (@roeey) on CodePen.
הכרזה על CSS Variables
ראשית, החליטו על ה-scope. אם רוצים שהמשתנה יהיה זמין בכל מקום, הגדירו אותו על ה-:root pseudo-class (שמצביע על אלמנט ה-<html>).
מכיוון שמשתנים עוברים בתורשה, משתנה על :root יהיה זמין לכל אלמנט ב-DOM.
:root {
--main-color: #ffe01b;
}כפי שאתם רואים, אנו מכריזים על המשתנה בדיוק כפי שאנו קובעים כל תכונת CSS. עם זאת, משתנה חייב להתחיל בשני קווים מפרידים (dashes).
כדי לגשת למשתנה, משתמשים בפונקציה var() ומעבירים את שם המשתנה כפרמטר.
#title {
color: var(--main-color);
}פעולה זו תספק את הצבע #ffe01b לאלמנט עם ID בשם title.
ירושה של CSS Variables
אותם Custom Properties עוברים בירושה. המשמעות היא שאם לא נקבע ערך לתכונה מסויימת עבור אלמנט כלשהו – הערך של אלמנט האב יהיה בשימוש. תנו מבט ב HTML הבא:
<div class="one">
<div class="two">
<div class="three"></div>
<div class="four"></div>
</div>
</div>נאמר ול HTML זה קיים ה CSS הבא:
.two {
--test: 10px;
}
.three {
--test: 2em;
}במקרה זה התוצאה של var(--test) הינה:
- עבור האלמנט בעל
״class="twoהערך יהיה 10px. - עבור האלמנט בעל
״class="threeהערך יהיה 2em. - עבור האלמנט בעל
״class="fourהערך יהיה 10px (נורש מאלמנט האב). - עבור האלמנט בעל
״class="oneהערך יהיה לא תקין – מכאן שיתבצע שימוש בערך הדיפולטיבי של כל תכונה.
עלינו לזכור כי אלו Custom Properties ולא משתנים כפי שאנו מכירים משפות תכנות אחרות. הערך מחושב היכן שהוא נדרש בלבד ואינו נשמר לשימוש עבור מקומות אחרים. למשל, אינכם יכולים לקבוע תכונה עבור אלמנט ולצפות להשתמש בה עבור האלמנט הבא אחריו (sibling) ב DOM. התכונה תהיה רלוונטית אך ורק עבור הסלקטור המסויים והילדים שלו, כמו CSS סטנדרטי.
ננסה לספק דוגמה פשוטה יותר. נאמר ויש לכם אלמנט כלשהו המציג אזהרה באתר ולו צבע מיוחד שאינכם משתמשים בו במקומות אחרים באתר או באפליקציה.
.alert {
--alert-color: #ffe01b;
}ניתן להשתמש במשתנה זה עבור האלמנט ועבור כל הילדים של אלמנט זה ב DOM:
.alert p {
color: var(--alert-color);
border: 1px solid var(--alert-color);
}אם תנסו להשתמש במשתנה alert-color עבור סלקטור אחר שאינו .alert (או אחד מילדיו) הוא פשוט לא יעבוד לכם. במקרה זה הדפדפן פשוט יתעלם משורת CSS זו.
זה המקום לציין כי משתני CSS עוקבים אחר ההתנהגות הנורמלית של CSS, כך שהתכונה האחרונה שהדפדפן מקבל היא זו שתתפוס.
כיצד לגשת למשתנים באמצעות Javascript
מכיוון שמשתני CSS חיים ב-DOM, ניתן לקרוא ולעדכן אותם עם JavaScript. זה פותח את הדלת ל-theming בזמן ריצה – לאפשר למשתמשים לשנות צבעים, גדלי פונט או ריווח ללא טעינה מחדש.
קריאת משתנה דורשת שלוש שורות:
const root = document.querySelector(':root');
const rootStyles = getComputedStyle(root);
const mainColor = rootStyles.getPropertyValue('--main-color');
console.log(mainColor);
--> '#ffe01b'עדכון הוא קריאה אחת ל-setProperty:
root.style.setProperty('--main-color', '#a3316f')
ריספונסיביות פשוטה יותר עם CSS Variables
CSS Variables מציעים דרך נקייה לטפל בעיצוב רספונסיבי. דרסו ערכי משתנים בתוך media queries, וכל אלמנט שמפנה אליהם מתעדכן אוטומטית:
:root {
--main-font-size: 16px;
}
@media all and (max-width: 600px) {
:root {
--main-font-size: 12px;
}
}דוגמה לשימוש בסקאלה מודולרית ו CSS Vars
סקאלה מודולרית (Modular Scale) היא יחס מתמטי לבחירת גדלי טיפוגרפיה עקביים ולטובת היררכיה טיפוגרפית נכונה. נשתמש בסקאלה של 1.2 למסכים קטנים ו-1.33 למסכים גדולים. הגדלים מ-modularscale.com:
| 1.2 | 1.33 |
|---|---|
| 2.488rem | 4.209rem |
| 2.074rem | 3.157rem |
| 1.728rem | 2.369rem |
| 1.44rem | 1.777rem |
| 1.2rem | 1.333rem |
| 1rem | 1rem |
זהו use case מושלם למשתני CSS. מגדירים סט אחד של משתנים ומחליפים את ערכיהם בנקודות שבירה שונות:
:root {
/* scale for 1.2 */
--font-size-1: 1rem;
--font-size-2: 1.2rem;
--font-size-3: 1.44rem;
--font-size-4: 1.728rem;
--font-size-5: 2.074rem;
--font-size-6: 2.488rem;
}
@media screen and (min-width: 800px) {
:root {
/* scale for 1.33 */
--font-size-1: 1rem;
--font-size-2: 1.333rem;
--font-size-3: 1.777rem;
--font-size-4: 2.369rem;
--font-size-5: 3.157rem;
--font-size-6: 4.209rem;
}
}
הלוגיקה הרספונסיבית נמצאת במשתנים. שאר ה-CSS נשאר נקי:
h1 {
font-size: var(--font-size-6);
}
h2 {
font-size: var(--font-size-5);
}
h3 {
font-size: var(--font-size-4);
}
h4 {
font-size: var(--font-size-3);
}
h5 {
font-size: var(--font-size-2);
}
h6 {
font-size: var(--font-size-1);
}
האם CSS Variables מחליפים את הצורך ב Preprocessors?
את רוב מה שהצגנו ניתן לעשות גם עם SCSS. אך למשתני CSS יתרונות ייחודיים:
- הם Native ברמת הדפדפן ואינם דורשים קומפילציה כפי שנדרש ב Preprocessors.
- הם חיים ונמצאים ב DOM ובאפשרותכם לגשת למשתנים אלו ב Javascript – יתרון משמעותי.
- הם ניתנים לשינוי ויכולים להגיב למה שקורה בעמוד לעומת המשתנים הסטטיים של Preprocessors.
אז האם CSS Variables יכולים להחליף את השימוש ב Preprocessors? לא.
השימוש ב Preprocessors עדיין רלוונטי ולמעשה יהיה רעיון טוב לשמור על המשתנים הסטטיים ב Sass (או כל Preprocessors בו אתם משתמשים) כבדוגמה הבאה:
$breakpoint-small: 640px;
$theme-color: aliceblue;
@media screen and (min-width: $breakpoint-small) {
body {
--background: $theme-color;
}
}
זה גם מדגיש מגבלה חשובה: משתני CSS ניתנים לשימוש רק בערכי תכונות, לא בסלקטורים או ביטויי media query. לא ניתן לכתוב @media (min-width: var(--bp)).
אם תנסו לשנות את שורה מספר 5 בקוד מעלה כך שתכיל משתנה CSS, הקוד לא יעבוד כראוי.
טיפים נוספים
רגישות לאותיות גדולות/קטנות. משתני CSS הם Case Sensitive:
:root {
--color: blue;
--COLOR: red;
}
/*--color and --COLOR are two different variables*/ערכי fallback. הפונקציה var() מקבלת ארגומנט שני כ-fallback:
width: var(--custom-width, 33%);
שימוש ישירות ב-HTML. ניתן להגדיר משתני CSS ישירות ב-HTML:
<!--HTML-->
<html style="--size: 600px">
<!--CSS-->
body {
max-width: var(--size)
}הרכבת משתנים. ניתן להשתמש במשתנה בתוך משתנה אחר:
--base-red-color: #f00;
--background-gradient: linear-gradient(to top, var(--base-red-color), #222);שילוב עם calc(). משתנים עובדים יפה עם חישובים:
--text-input-width: 5000px;
max-width: calc(var(--text-input-width) / 2);Custom Properties רשומים עם @property
מיולי 2024, ה-at-rule של @property נתמך בכל הדפדפנים המודרניים. הוא מאפשר לרשום custom property עם טיפוס מסוים, ערך התחלתי ושליטה בתורשה:
@property --brand-color {
syntax: "";
inherits: true;
initial-value: #3490dc;
} למה זה חשוב? custom properties רגילים מטופלים כמחרוזות על ידי הדפדפן. הוא לא יכול לבצע אינטרפולציה בין #3490dc ל-#e3342f במעבר מעבר כי הוא לא יודע שאלו צבעים.
עם @property, הדפדפן מבין את הטיפוס ויכול להנפיש את התכונה בצורה חלקה:
@property --gradient-angle {
syntax: "";
inherits: false;
initial-value: 0deg;
}
.card {
background: linear-gradient(var(--gradient-angle), #3490dc, #6574cd);
transition: --gradient-angle 0.6s ease;
}
.card:hover {
--gradient-angle: 180deg;
} ללא
@property, מעברי gradient קופצים מידית. עם@property, הם מונפשים בצורה חלקה – משהו שהיה בלתי אפשרי ב-CSS טהור.
למדריך מקיף עם דוגמאות חיות ועוד use cases, ראו את המדריך לתכונת @property ב-CSS.
תמיכת דפדפנים
משתני CSS נתמכים בכל הדפדפנים המודרניים כבר שנים, עם כיסוי גלובלי של מעל 97%. Internet Explorer היה הדפדפן היחיד שלא תמך, ועם פרישתו ב-2022, fallbacks ל-IE כבר לא נדרשים.
ה-at-rule החדש יותר @property הגיע לתמיכה אוניברסלית ביולי 2024 (Chrome 85+, Firefox 128+, Safari 16.4+).
שאלות נפוצות
@property ומציינים תחביר כמו <color> או <angle>, הדפדפן יכול לבצע אינטרפולציה ולהנפיש מעברים בצורה חלקה.-- נבחרה כדי למנוע התנגשויות עם תכונות CSS קיימות ועתידיות. כל שם תכונה שמתחיל ב--- מובטח שלעולם לא יתנגש עם תכונת CSS מובנית.@media (min-width: var(--bp)) לא תעבוד. אבל כן ניתן לשנות ערכי משתנים בתוך בלוק media query כדי להשפיע על התכונות שמפנות אליהם.@property?
@property רושם custom property עם טיפוס מסוים (syntax), ערך התחלתי ודגל תורשה. זה נותן לדפדפן את המידע שהוא צריך כדי להנפיש את התכונה, לוולד ערכים ולספק fallback אמין כשמוקצים ערכים לא תקינים.לסיכום
אני משתמש במשתני CSS בכל פרויקט. הם החליפו את רוב משתני ה-Sass שלי לכל מה שקשור לצבעים, ריווחים וטיפוגרפיה. השילוב של scope מבוסס תורשה, גישה מ-JavaScript ורישום דרך @property הופך אותם להרבה יותר ממה שהיו כשהם הושקו לראשונה.


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