@container ו-:has(): שני ממשקי API חדשים וחזקים שמגיעים אל Chromium 105

שאילתות קונטיינרים ו- :has() הן התאמה שמתבצעת בגן עדן עם יכולת תגובה. למרבה המזל, שתי התכונות האלה נוחתות יחד ב-Chromium 105. זוהי גרסה גדולה עם שתי תכונות מבוקשות מאוד לממשקי רספונסיביות.

שאילתות בקונטיינרים: סיכום קצר

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

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

שימוש בשאילתות לגבי מאגרי תגים

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

כרטיס יחיד עם שתי עמודות.

כדי ליצור שאילתה של מאגר, מגדירים את container-type במאגר הכרטיסים:

.card-container {
  container-type: inline-size;
}

הגדרת container-type כ-inline-size שולחת שאילתה לגבי הגודל בכיוון השורה של האב. בשפות לטיניות כמו אנגלית, זה יהיה רוחב הכרטיס, כי הטקסט זורם בתוך השורה משמאל לימין.

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

.card {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

@container (max-width: 400px) {
  .card {
    grid-template-columns: 1fr;
  }
}

הבורר ההורה ‎ :has()

הסיווג המזויף :has() ב-CSS מאפשר למפתחים לבדוק אם רכיב הורה מכיל צאצאים עם פרמטרים ספציפיים.

לדוגמה, p:has(span) מציין בורר של פסקה (p) שמכיל span. אפשר להשתמש באפשרות הזו כדי לעצב את פסקה ההורה עצמה, או לעצב את כל מה שנכלל בה. אחת הדוגמאות השימושיות היא figure:has(figcaption) כדי לעצב רכיב figure שמכיל כיתוב. מידע נוסף על :has() זמין במאמר הזה של Jhey Tompkins.

שאילתות קונטיינרים ו-:has()

אפשר לשלב את יכולות הבחירה של ההורה ב-:has() עם יכולות השאילתה של ההורה בשאילתות של מאגרים כדי ליצור סגנונות מהותיים דינמיים מאוד.

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

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

בדוגמה הזו, לכרטיס עם תמונה יש תבנית של רשת עם שתי עמודות, ואילו לכרטיס ללא תמונה יש פריסה עם עמודה אחת. בנוסף, בכרטיס ללא תמונה יש כותרת גדולה יותר. כדי לכתוב את זה באמצעות :has(), משתמשים בקוד ה-CSS הבא.

.card:has(.visual) {
  grid-template-columns: 1fr 1fr;
}

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

.card:not(:has(.visual)) h1 {
  font-size: 4rem;
}

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

סיכום של כל המידע

הדוגמה שלמעלה מציגה שילוב של :has(),‏ :not() ו-@container, אבל שאילתות של מאגרים הן הכי שימושיות כשאפשר לראות את אותו רכיב בשימוש במספר מקומות. נוסיף קצת עיצוב ונציג את הכרטיסים האלה בתצוגת רשת זה לצד זה.

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