ירושה

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:

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

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

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

משאבים