קינון CSS

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

אדם ארגייל
אדם ארגייל

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

לפני
.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

.nesting > .is > .awesome {
  color: deeppink;
}

אחרי הסידור בתוך הסלקטורים, אפשר להמשיך ולקבץ את כללי הסגנון שקשורים אליהם.

אחרי
.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

כדאי לנסות את זה בדפדפן.

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

בעזרת Nesting אפשר: - ארגון - הקטנת גודל הקובץ - ארגון מחדש של הקוד

תכונת Nesting זמינה ב-Chrome 112 ואפשר לנסות אותה בגרסה 162 של Safari Technical Preview 162.

תחילת העבודה עם Nest Nesting

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

רשת צבעונית של עיגולים קטנים וגדולים, משולשים וריבועים.

בתוך ארגז החול יש מעגלים, משולשים ומרובעים. חלקם קטנים, בינוניים או גדולים. סוגים אחרים הם כחול, ורוד או סגול. כולם נמצאים בתוך הרכיב שמכיל .demo. זוהי תצוגה מקדימה של רכיבי ה-HTML שאליהם תמקד.

<div class="demo">
  <div class="sm triangle pink"></div>
  <div class="sm triangle blue"></div>
  <div class="square blue"></div>
  <div class="sm square pink"></div>
  <div class="sm square blue"></div>
  <div class="circle pink"></div>
  …
</div>

דוגמאות לקינון

קינון CSS מאפשר להגדיר סגנונות לרכיב בהקשר של בורר אחר.

.parent {
  color: blue;

  .child {
    color: red;
  }
}

בדוגמה הזו, הבורר של המחלקה .child מוצב בתוך הבורר של המחלקה .parent. המשמעות היא שהסלקטור .child המקונן יחול רק על רכיבים שהם צאצאים של רכיבים עם המחלקה .parent.

לחלופין, אפשר לכתוב את הדוגמה הזו באמצעות הסמל &, כדי לציין במפורש את המיקום של מחלקת ההורה.

.parent {
  color: blue;

  & .child {
    color: red;
  }
}

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

בחירת המעגלים

בדוגמה הראשונה הזו, המשימה היא להוסיף סגנונות כדי להפוך לשקוף בהדרגה ולטשטש רק את המעגלים שבתוך ההדגמה.

ללא קינון, שירותי CSS כיום:

.demo .circle {
  opacity: .25;
  filter: blur(25px);
}

באמצעות קינון יש שתי דרכים תקפות:

/* & is explicitly placed in front of .circle */
.demo {
  & .circle {
    opacity: .25;
    filter: blur(25px);
  }
}

או

/* & + " " space is added for you */
.demo {
  .circle {
    opacity: .25;
    filter: blur(25px);
  }
}

התוצאה, כל הרכיבים בתוך .demo שיש בהם סיווג .circle מטושטשים וכמעט בלתי נראים:

ברשת הצבעונית של הצורות אין יותר עיגולים, הן עמעמות מאוד ברקע.
לניסיון להדגמה

בחירת משולשים וריבועים

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

כיום, ללא קינון, יש שתי דרכים:

.demo .triangle,
.demo .square {
  opacity: .25;
  filter: blur(25px);
}

או באמצעות :is()

/* grouped with :is() */
.demo :is(.triangle, .square) {
  opacity: .25;
  filter: blur(25px);
}

יש שתי דרכים חוקיות לביצוע סידור פנימי:

.demo {
  & .triangle,
  & .square {
    opacity: .25;
    filter: blur(25px);
  }
}

או

.demo {
  .triangle, .square {
    opacity: .25;
    filter: blur(25px);
  }
}

התוצאה, רק .circle רכיבים נשארו בתוך .demo:

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

בחירת משולשים ומעגלים גדולים

למשימה הזו יש צורך בסלקטור מורכב, שבו רכיבים חייבים לכלול את שתי המחלקות כדי שניתן יהיה לבחור בהם.

ללא קינון, שירותי CSS כיום:

.demo .lg.triangle,
.demo .lg.square {
  opacity: .25;
  filter: blur(25px);
}

או

.demo .lg:is(.triangle, .circle) {
  opacity: .25;
  filter: blur(25px);
}

יש שתי דרכים חוקיות לביצוע סידור פנימי:

.demo {
  .lg.triangle,
  .lg.circle {
    opacity: .25;
    filter: blur(25px);
  }
}

או

.demo {
  .lg {
    &.triangle,
    &.circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

התוצאה, כל המשולשים והמעגלים הגדולים מוסתרים ב-.demo:

ברשת הצבעונית מוצגות רק צורות קטנות ובינוניות.
לניסיון להדגמה
טיפ למתקדמים עם בוררים מורכבים וקינון

הסמל של & מייצג את החבר/ה שלכם, מכיוון שהוא מראה במפורש איך לצרף בוררים בתצוגת עץ. לדוגמה:

.demo {
  .lg {
    .triangle,
    .circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

אמנם דרך חוקית לקינון, אך התוצאות לא יתאימו לרכיבים שציפית לקבל. הסיבה לכך היא שאם לא תכללו ב-& את התוצאה הרצויה של .lg.triangle, .lg.circle, התוצאה בפועל תהיה .lg .triangle, .lg .circle; בוררי צאצאים.

בחירת כל הצורות חוץ מההוורודות

למשימה הזו נדרש פסאודו מחלקה פונקציונלית מסוג negation, שבו לרכיבים לא יכול להיות הבורר שצוין.

ללא קינון, שירותי CSS כיום:

.demo :not(.pink) {
  opacity: .25;
  filter: blur(25px);
}

יש שתי דרכים חוקיות לביצוע סידור פנימי:

.demo {
  :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

או

.demo {
  & :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

התוצאה, כל הצורות שאינן ורודות מוסתרות בתוך .demo:

הרשת הצבעונית היא עכשיו מונוכרומטית, ומוצגות בה רק צורות ורודות.
לניסיון להדגמה
דיוק וגמישות עם &

נניח שרצית למקד אל .demo באמצעות הבורר :not(). נדרש & לשם כך:

.demo {
  &:not() {
    ...
  }
}

המערכת משלבת בין .demo ו-:not() לבין .demo:not(), ולא בדוגמה הקודמת שבה היה צורך ב-.demo :not(). התזכורת הזו חשובה מאוד כשרוצים להציב אינטראקציה של :hover.

.demo {
  &:hover {
    /* .demo:hover */
  }

  :hover {
    /* .demo :hover */
  }
}

דוגמאות נוספות לסידור פנימי

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

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

@media בתוך הכנסה

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

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

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    font-size: 1.25rem;
  }
}

שימוש בהרשאה & במפורש ניתן גם לשימוש:

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    &.large {
      font-size: 1.25rem;
    }
  }
}

בדוגמה הזו אפשר לראות את התחביר המורחב עם &, וגם לטרגט כרטיסי .large כדי להדגים תכונות קינון נוספות שממשיכים לפעול.

למידע נוסף על הגדרת @rules.

קינון בכל מקום

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

.card {
  .featured & {
    /* .featured .card */
  }
}

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

.card {
  .featured & & & {
    /* .featured .card .card .card */
  }
}

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

דוגמאות לקינון לא חוקיות

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

קינון ושרשור

מוסכמות רבות של מתן שמות למחלקות CSS מסתמכות על אפשרות הקינון של היכולת לשרשר או לצרף סלקטורים כאילו היו מחרוזות. אפשרות זו לא פועלת בקינון CSS, כי הסלקטורים הם לא מחרוזות, אלא הפניות לאובייקטים.

.card {
  &--header {
    /* is not equal to ".card--header" */
  }
}

הסבר מפורט יותר זמין במפרט.

דוגמה לקינון מסובך

בתוך רשימות הבורר ו-:is()

כדאי לשקול את בלוק ה-CSS הבא, שמוצב בתוך המסגרת:

.one, #two {
  .three {
    /* some styles */
  }
}

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

כדי שכוונת הקינון תפעל, רשימת בוררים שאינה אפשרות הקינון הפנימית ביותר תקיף ב-:is() על ידי הדפדפן. האריזה הזו שומרת על הקיבוץ של רשימת הבוררים בתוך כל ההקשרים שנוצרו. תופעת הלוואי של הקיבוץ הזה, :is(.one, #two), היא שהציון הגבוה ביותר בבוררים שבסוגריים מתבצע בה. כך :is() תמיד פועל, אבל השימוש בתחביר של עץ עשוי להפתיע כי זה לא בדיוק מה שנוצר. בוצע סיכום של הטריק: הוספה של מזהים ורשימות בוררים יכולה להוביל לבוררים ברמת דיוק גבוהה מאוד.

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

:is(.one, #two) .three {
  /* some styles */
}

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

שילוב של קינון והצהרות

כדאי לשקול את בלוק ה-CSS הבא, שמוצב בתוך המסגרת:

.card {
  color: green;
  & { color: blue; }
  color: red;
}

הצבע של רכיבי .card יהיה blue.

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

יש דרכים לעקוף את זה. החלק הבא כולל את שלושת סגנונות הצבעים ב-&, ושומר על סדר המדרגות כפי שהמחבר התכוון. הצבע של רכיבי .card יהיה אדום.

.card {
  color: green;
  & { color: blue; }
  & { color: red; }
}

למעשה, מומלץ לארוז את כל הסגנונות בהתאם לקינון של &.

.card {
  color: green;

  @media (prefers-color-scheme: dark) {
    color: lightgreen;
  }

  & {
    aspect-ratio: 4/3;
  }
}

זיהוי תכונות

יש שתי דרכים מעולות לזיהוי של קינון CSS: שימוש בקינון או שימוש ב-@supports כדי לבדוק את יכולת הניתוח של בורר הקינון.

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

שימוש בקינון:

html {
  .has-nesting {
    display: block;
  }

  .no-nesting {
    display: none;
  }
}

באמצעות @supports:

@supports (selector(&)) {
  /* nesting parsing available */
}

לקולגות שלי ברמוס יש Codepen מעולה שמדגים את האסטרטגיה הזו.

ניפוי באגים באמצעות כלי הפיתוח ל-Chrome

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

צילום מסך של תחביר של כלי פיתוח ל-Chrome.

ב-Chrome 113 תהיה תמיכה נוספת בקינון CSS. כדאי להתעדכן בהמשך.

העתיד

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

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

לסיום, הנה הדגמה שמשתמשת ב-@scope, בתצוגת עץ וב-@layer יחד. זה מאוד מרגש!

כרטיס בהיר על רקע אפור. לכרטיס יש כותרת וטקסט, כמה לחצני פעולה ותמונה בסגנון סייבר פאנק.