ירושה

The CSS Podcast – 005: Inheritance

נניח שכתבתם קוד CSS כדי לגרום לאלמנטים להיראות כמו לחצן.

<a href="http://example.com" class="my-button">I am a button link</a>
.my-button {
  display: inline-block;
  padding: 1rem 2rem;
  text-decoration: none;
  background: pink;
  font: inherit;
  text-align: center;
}

לאחר מכן מוסיפים רכיב קישור לכתבה עם ערך class של .my-button. עם זאת, יש בעיה: הטקסט לא בצבע שציפיתם לו. איך זה קרה?

חלק ממאפייני ה-CSS עוברים בירושה אם לא מציינים להם ערך. במקרה של הלחצן הזה, הוא ירש את color מ-CSS הזה:

article a {
  color: maroon;
}

בשיעור הזה נסביר למה זה קורה ואיך ירושה היא תכונה חזקה שתעזור לכם לכתוב פחות CSS.

תהליך הירושה

נראה איך ירושה פועלת באמצעות קטע הקוד הבא ב-HTML:

<html>
  <body>
    <article>
      <p>Lorem ipsum dolor sit amet.</p>
    </article>
  </body>
</html>

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

html {
  color: lightslategray;
}

המאפיין color עובר בירושה כברירת מחדל על ידי אלמנטים אחרים. לאלמנט html יש color: lightslategray, לכן לכל האלמנטים שיכולים לרשת צבע יהיה עכשיו צבע של lightslategray.

body {
  font-size: 1.2em;
}
p {
  font-style: italic;
}

רק הרכיב <p> יכלול טקסט נטוי כי הוא הרכיב העמוק ביותר בתוך העץ. הירושה מתבצעת רק כלפי מטה, ולא בחזרה לרכיבי הורה.

אילו מאפיינים עוברים בירושה כברירת מחדל?

לא כל מאפייני ה-CSS עוברים בירושה כברירת מחדל, אבל יש הרבה כאלה. לידיעתכם, זוהי הרשימה המלאה של המאפיינים שעוברים בירושה כברירת מחדל, שנלקחה מהחומר העזר של W3 לגבי כל מאפייני ה-CSS:

איך פועלת ירושה

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

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

איך לקבל בירושה באופן מפורש ולשלוט בירושה

בירושה יכולה להשפיע על רכיבים בדרכים בלתי צפויות, ולכן ב-CSS יש כלים שיכולים לעזור בכך.

מילת המפתח inherit

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

strong {
  font-weight: 900;
}

קטע הקוד הזה ב-CSS מגדיר לכל האלמנטים מסוג <strong> את הערך font-weight של 900, במקום ערך ברירת המחדל bold, שהוא המקביל ל-font-weight: 700.

.my-component {
  font-weight: 500;
}

במקום זאת, הכיתה .my-component מגדירה את font-weight כ-500. כדי שהאלמנטים <strong> בתוך .my-component יהיו גם font-weight: 500, מוסיפים:

.my-component strong {
  font-weight: inherit;
}

עכשיו, לרכיבי <strong> בתוך .my-component יהיה font-weight של 500.

אפשר להגדיר את הערך הזה באופן מפורש, אבל אם משתמשים ב-inherit וה-CSS של .my-component ישתנה בעתיד, אפשר להבטיח שה-<strong> יישאר מעודכן באופן אוטומטי.

מילת המפתח initial

ירושה עלולה לגרום לבעיות ברכיבים, ו-initial מספק אפשרות איפוס חזקה.

למדתם קודם לכן שלכל מאפיין יש ערך ברירת מחדל ב-CSS. מילת המפתח initial מחזירה את הערך של המאפיין לערך ברירת המחדל המקורי.

aside strong {
  font-weight: initial;
}

קטע הקוד הזה יסיר את העיצוב מודגש מכל הרכיבים מסוג <strong> בתוך רכיב <aside>, ובמקום זאת יעשה להם עיצוב רגיל, שהוא הערך הראשוני.

מילת המפתח unset

התנהגות המאפיין unset משתנה בהתאם לכך שהנכס עובר בירושה כברירת מחדל או לא. אם מאפיין עובר בירושה כברירת מחדל, מילת המפתח unset תהיה זהה למילת המפתח inherit. אם המאפיין לא עובר בירושה כברירת מחדל, מילת המפתח unset שווה ל-initial.

קשה לזכור אילו מאפייני CSS עוברים בירושה כברירת מחדל, ולכן unset יכול להיות שימושי בהקשר הזה. לדוגמה, המאפיין color עובר בירושה כברירת מחדל, אבל המאפיין margin לא, כך שאפשר לכתוב את זה:

/* Global color styles for paragraph in authored CSS */
p {
  margin-top: 2em;
  color: goldenrod;
}

/* The p needs to be reset in asides, so you can use unset */
aside p {
  margin: unset;
  color: unset;
}

עכשיו, הערך margin יוסר ו-color יחזור להיות הערך המחושב שהוענק בירושה.

אפשר להשתמש בערך unset גם עם הנכס all. נחזור לדוגמה שלמעלה: מה קורה אם לסגנונות הגלובליים של p מתווספים עוד כמה מאפיינים? רק הכלל שהוגדר עבור margin ו-color יחול.

/* Global color styles for paragraph in authored CSS */
p {
    margin-top: 2em;
    color: goldenrod;
    padding: 2em;
    border: 1px solid;
}

/* Not all properties are accounted for anymore */
aside p {
    margin: unset;
    color: unset;
}

אם משנים את הכלל aside p ל-all: unset, לא משנה אילו סגנונות גלובליים יחולו על p בעתיד, הם תמיד לא יוגדרו.

aside p {
    margin: unset;
    color: unset;
    all: unset;
}

בדיקת ההבנה

בדיקת הידע שלכם בנושא ירושה

אילו מהמאפיינים הבאים עוברים בירושה כברירת מחדל?

animation
אנימציות לא מועברות לצאצאים.
font-size
🎉
color
🎉
text-align
🎉
line-height
🎉

איזה ערך מתנהג כמו inherit, אלא אם אין מה לרשת, ואז מתנהג כמו initial?

reset
לא ערך חוקי, צריך לנסות שוב!
unset
🎉
superset
לא ערך חוקי, צריך לנסות שוב!

משאבים