היכולת לשאול לגבי הגודל של רכיב מוטבע של רכיב אב, וערכי יחידות של שאילתות לגבי רכיבי container, הגיעה לאחרונה לתמיכה יציבה בכל מנועי הדפדפנים המודרניים.
עם זאת, מפרט ההכלה כולל יותר משאילתות לגבי גודל. הוא גם מאפשר לשלוח שאילתות לגבי ערכי סגנון של רכיב אב. החל מ-Chromium 111, תוכלו להחיל הכלה של סגנון על ערכים של מאפיינים מותאמים אישית ולשלוח שאילתה לגבי ערך של מאפיין מותאם אישית לרכיב אב.
Browser Support
המשמעות היא שיש לנו שליטה לוגית רבה יותר בסגנונות ב-CSS, והיא מאפשרת הפרדה טובה יותר בין הלוגיקה של האפליקציה ושכבת הנתונים שלה לבין הסגנונות שלה.
מפרט CSS Containment Module Level 3, שכולל שאילתות של גודל וסגנון, מאפשר לשאול על כל הסגנונות מאלמנט אב, כולל זוגות של מאפיינים וערכים כמו font-weight: 800. עם זאת, בשלב ההשקה של התכונה הזו, שאילתות סגנון פועלות כרגע רק עם ערכים של מאפיינים מותאמים אישית של CSS. השיטה הזו עדיין שימושית מאוד לשילוב סגנונות ולהפרדה בין נתונים לעיצוב. בואו נראה איך משתמשים בשאילתות סגנון עם מאפייני CSS מותאמים אישית:
איך מתחילים לעבוד עם שאילתות סגנון
נניח שיש לנו את קוד ה-HTML הבא:
<ul class="card-list">
<li class="card-container">
<div class="card">
...
</div>
</li>
</ul>
כדי להשתמש בשאילתות סגנון, קודם צריך להגדיר רכיב מאגר. הגישה שונה במקצת בהתאם לשאילתה שמופנית להורה ישיר או להורה עקיף.
שאילתות לגבי הורים ישירים

בניגוד לשאילתות סגנון, לא צריך להחיל את המאפיין container-type או container על .card-container כדי ש-.card יוכל לשאול על הסגנונות של רכיב האב הישיר שלו. עם זאת, צריך להחיל את הסגנונות (ערכי מאפיינים מותאמים אישית במקרה הזה) על מאגר (.card-container במקרה הזה) או על כל רכיב שמכיל את הרכיב שאנחנו מעצבים ב-DOM. אי אפשר להחיל סגנונות שאנחנו שואלים עליהם על הרכיב הישיר שאנחנו מעצבים באמצעות השאילתה הזו, כי זה עלול לגרום ללולאות אינסופיות.
כדי לשאול שאלה ישירות את ההורה, אפשר לכתוב:
/* styling .card based on the value of --theme on .card-container */
@container style(--theme: warm) {
.card {
background-color: wheat;
border-color: brown;
...
}
}
יכול להיות ששמתם לב ששאילתת הסגנון עוטפת את השאילתה ב-style(). כך אפשר להבחין בין ערכי מידות לבין סגנונות. לדוגמה, אפשר לכתוב שאילתה לגבי הרוחב של מאגר התגים כך: @container (min-width: 200px) { … }. הסגנונות יחולו אם רוחב מאגר האב יהיה לפחות 200 פיקסלים. עם זאת, min-width יכול להיות גם מאפיין CSS, ואפשר לשלוח שאילתה לגבי ערך ה-CSS של min-width באמצעות שאילתות סגנון. לכן כדאי להשתמש בתג style() wrapper כדי להבהיר את ההבדל: @container style(min-width: 200px) { … }.
עיצוב של תבניות הורה לא ישירות
אם רוצים לשאול שאילתות לגבי סגנונות של רכיב כלשהו שהוא לא רכיב אב ישיר, צריך לתת לרכיב הזה container-name. לדוגמה, אפשר להחיל סגנונות על .card על סמך הסגנונות של .card-list על ידי מתן container-name ל-.card-list והפניה אליו בשאילתת הסגנון.
/* styling .card based on the value of --moreGlobalVar on .card-list */
@container cards style(--moreGlobalVar: value) {
.card {
...
}
}
בדרך כלל מומלץ לתת שמות למאגרי התגים כדי להבין בקלות מה אתם מחפשים, וכדי שתוכלו לגשת למאגרים האלה בקלות רבה יותר. דוגמה למצב שבו זה שימושי: אם רוצים להגדיר סגנון לרכיבים בתוך .card באופן ישיר. בלי מאגר תגים עם שם ב-.card-container, אי אפשר לבצע שאילתה ישירות.
אבל כל זה יהיה ברור יותר כשנראה דוגמאות:
שאילתות סגנון בפעולה

שאילתות סגנון שימושיות במיוחד אם יש לכם רכיב לשימוש חוזר עם כמה וריאציות, או אם אין לכם שליטה על כל הסגנונות אבל אתם צריכים להחיל שינויים במקרים מסוימים. בדוגמה הזו מוצג אוסף של כרטיסי מוצרים שמשתמשים באותו רכיב כרטיס. בחלק מכרטיסי המוצרים יש פרטים או הערות נוספים, כמו 'חדש' או 'מלאי נמוך'. הפרטים האלה מופעלים על ידי מאפיין מותאם אישית בשם --detail. בנוסף, אם סטטוס המלאי של מוצר הוא 'מלאי נמוך', הרקע של הגבול שלו יהיה אדום כהה. סביר להניח שהמידע הזה עובר עיבוד בצד השרת, ואפשר להחיל אותו על הכרטיסים באמצעות סגנונות מוטבעים באופן הבא:
<div class="product-list">
<div class="product-card-container" style="--detail: new">
<div class="product-card">
<div class="media">
<img .../>
<div class="comment-block"></div>
</div>
</div>
<div class="meta">
...
</div>
</div>
<div class="product-card-container" style="--detail: low-stock">
...
</div>
<div class="product-card-container">
...
</div>
...
</div>
בהינתן הנתונים המובְנים האלה, אפשר להעביר ערכים אל --detail ולהשתמש במאפיין המותאם אישית הזה של CSS כדי להחיל את הסגנונות:
@container style(--detail: new) {
.comment-block {
display: block;
}
.comment-block::after {
content: 'New';
border: 1px solid currentColor;
background: white;
...
}
}
@container style(--detail: low-stock) {
.comment-block {
display: block;
}
.comment-block::after {
content: 'Low Stock';
border: 1px solid currentColor;
background: white;
...
}
.media-img {
border: 2px solid brickred;
}
}
הקוד שלמעלה מאפשר לנו להחיל צ'יפ על --detail: low-stock ועל --detail: new, אבל יכול להיות ששמתם לב שיש כפילות בבלוק הקוד. נכון לעכשיו, אין דרך לשאול רק על הנוכחות של --detail באמצעות @container style(--detail), מה שיאפשר שיתוף טוב יותר של סגנונות ופחות חזרות. היכולת הזו נמצאת כרגע בדיון בקבוצת העבודה.
כרטיסי מזג אוויר
בדוגמה הקודמת השתמשנו במאפיין מותאם אישית יחיד עם כמה ערכים אפשריים כדי להחיל סגנונות. אבל אפשר גם להשתמש בכמה נכסים מותאמים אישית ולשאול עליהם שאילתות. לדוגמה, בכרטיס מזג האוויר הזה:

כדי לשנות את הסגנון של מעברי הצבע ברקע והסמלים בכרטיסים האלה, מחפשים מאפיינים של מזג האוויר, כמו 'מעונן', 'גשום' או 'שמשי':
@container style(--sunny: true) {
.weather-card {
background: linear-gradient(-30deg, yellow, orange);
}
.weather-card:after {
content: url(<data-uri-for-demo-brevity>);
background: gold;
}
}
כך תוכלו לעצב כל כרטיס על סמך המאפיינים הייחודיים שלו. אבל אפשר גם לעצב שילובי מאפיינים (מאפיינים בהתאמה אישית) באמצעות האופרטור and, באותו אופן שבו משתמשים בשאילתות מדיה. לדוגמה, יום שבו יש גם עננים וגם שמש ייראה כך:
@container style(--sunny: true) and style(--cloudy: true) {
.weather-card {
background: linear-gradient(24deg, pink, violet);
}
.weather-card:after {
content: url(<data-uri-for-demo-brevity>);
background: violet;
}
}
הפרדת הנתונים מהעיצוב
בשני הדמויים האלה, יש יתרון מבני בהפרדה בין שכבת הנתונים (DOM שיוצג בדף) לבין הסגנונות שמוחלים. הסגנונות נכתבים כווריאציות אפשריות שקיימות בסגנון הרכיב, בעוד שנקודת קצה יכולה לשלוח את הנתונים שבהם היא תשתמש כדי לעצב את הרכיב. אפשר להשתמש בערך יחיד, כמו במקרה הראשון, ולעדכן את הערך --detail, או בכמה משתנים, כמו במקרה השני (הגדרת --rainy או --cloudy או --sunny). והכי טוב: אפשר גם לשלב בין הערכים האלה. למשל, אם תבדקו את הערכים --sunny ו---cloudy, יכול להיות שיוצג סגנון של עננים חלקיים.
אפשר לעדכן ערכים של מאפיינים מותאמים אישית באמצעות JavaScript בצורה חלקה, בזמן ההגדרה של מודל ה-DOM (כלומר, בזמן בניית הרכיב במסגרת) או בכל שלב באמצעות <parentElem>.style.setProperty('--myProperty’, <value>). I
הנה הדגמה שבה, בכמה שורות קוד, מתעדכנת התכונה --theme של לחצן, ומוחלים סגנונות באמצעות שאילתות סגנון והמאפיין המותאם אישית הזה (--theme):
כדי להגדיר את הסגנון של הכרטיס באמצעות שאילתות סגנון, משתמשים ב-JavaScript כדי לעדכן את ערכי המאפיינים המותאמים אישית:
const themePicker = document.querySelector('#theme-picker')
const btnParent = document.querySelector('.btn-section');
themePicker.addEventListener('input', (e) => {
btnParent.style.setProperty('--theme', e.target.value);
})
התכונות שמפורטות במאמר הזה הן רק ההתחלה. אפשר לצפות לעוד תכונות של שאילתות קונטיינרים שיעזרו לכם ליצור ממשקי משתמש דינמיים ורספונסיביים. בנוגע לשאילתות סגנון ספציפיות, עדיין יש כמה בעיות פתוחות. האחת היא הטמעה של שאילתות סגנון לסגנונות CSS מעבר למאפיינים מותאמים אישית. התכונה הזו כבר כלולה ברמת המפרט הנוכחית, אבל עדיין לא הוטמעה בדפדפנים. ההערכה של הקשר בוליאני צפויה להתווסף לרמת המפרט הנוכחית כשהבעיה הפתוחה תיפתר, ואילו שאילתות טווח מתוכננות לרמה הבאה של המפרט.