היום למדתי: scope ב CSS

22/03/2024

אני אוהב איך ש CSS מתפתח ומצליח לפתור את הבעיות תמיד שלוש שנים אחרי הזמן. הסיפור היום הוא על פיצ'ר מ CSS Selectors 4 שנקרא scope שממש הייתי צריך כל החיים אבל בכל מקרה אנחנו לא פה בשביל להתלונן וטוב מאוחר מלעולם לא.

מה ש scope עושה זה נותן לנו להגדיר כללי CSS שמשפיעים רק על אזור מסוים. כלומר אם יש לנו את ה HTML הזה (מתוך הדוגמה ב MDN):

<div class="light-scheme">
  <p>
    MDN contains lots of information about
    <a href="/en-US/docs/Web/HTML">HTML</a>,
    <a href="/en-US/docs/Web/CSS">CSS</a>, and
    <a href="/en-US/docs/Web/JavaScript">JavaScript</a>.
  </p>
</div>

<div class="dark-scheme">
  <p>
    MDN contains lots of information about
    <a href="/en-US/docs/Web/HTML">HTML</a>,
    <a href="/en-US/docs/Web/CSS">CSS</a>, and
    <a href="/en-US/docs/Web/JavaScript">JavaScript</a>.
  </p>
</div>

ואני רוצה לצבוע כל אחד מהדיבים והלינקים שאיתו בצבעים שונים תמיד יכלתי לכתוב CSS בסגנון הזה:

.light-scheme {
  background-color: plum;
}

.light-scheme a {
  color: darkmagenta;
}

.dark-scheme {
    background-color: darkmagenta;
    color: antiquewhite;
}

.dark-scheme a {
  color: plum;
}

די הרבה זמן אני כבר יכול להשתמש ב CSS כזה:

.light-scheme {
  background-color: plum;
  a {
    color: darkmagenta;
  }
}


.dark-scheme {
  background-color: darkmagenta;
  color: antiquewhite;

  a {
    color: plum;
  }
}

ולאחרונה אני יכול להשתמש גם בכתיב הזה כדי להגיע לאותה תוצאה:

@scope (.light-scheme) {
  :scope {
    background-color: plum;
  }

  a {
    color: darkmagenta;
  }
}

@scope (.dark-scheme) {
  :scope {
    background-color: darkmagenta;
    color: antiquewhite;
  }

  a {
    color: plum;
  }
}

ההבדל בין שני האחרונים קשור למשמעות הסמנטית שלהם. האמצעי בעל אותה משמעות כמו הראשון וה Specificity של ההורה נלקח בחשבון כשמחשבים את הערך (צבע במקרה שלנו). ב scope ההורה הוא לא חלק משורת ה Selector ולכן לא נלקח בחשבון בפיתרון קונפליקטים. דוגמה? בטח. ה CSS הזה:

.light-scheme a {
  color: yellow;
}

@scope (.light-scheme) {
  :scope {
    background-color: plum;
  }

  a {
    color: darkmagenta;
  }
}

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

div {
  padding: 10px;
}

.light-scheme a {
  color: yellow;
}

.light-scheme {
  background-color: plum;

  a {
    color: darkmagenta;
  }
}

ייתן ללינקים שבתוך ה light-scheme את הצבע darkmagenta בגלל שהסלקטור שלו יותר ספציפי.