@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 ומקבלות תמיכה בדפדפנים שונים, כך שזו תקופה מרגשת להיות מפתחי ממשק משתמש!