חיפוש

מספר מילים על התכונה has: ב-CSS

במשך שנים, ל-CSS לא הייתה דרך לבחור אלמנט הורה לפי מה שנמצא בתוכו. אם div הכיל תמונה, לא הייתה אפשרות לעצב אותו אחרת – לא בלי JavaScript. הפסאודו-קלאס :has, שהוצג ב-CSS Selectors Level 4, משנה את זה לחלוטין.

מהו מאפיין has:?

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

תחביר – Syntax

element:has(selector) {
    /* styles */
}

כאן, element הוא האלמנט שרוצים לעצב, ו-selector מתאר מה צריך להימצא בתוכו. ניתן גם להשתמש בקומבינטורים: element:has(> selector) מגביל את הבדיקה לצאצאים ישירים בלבד.

דוגמאות מעשיות

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

דוגמה 1: הדגשת אלמנט אב בהתבסס על Child Element

עיצוב div כשהוא מכיל אלמנט מסוג img:

<div>
    <p>This div contains an image.</p>
    <img src="https://via.placeholder.com/150" alt="Placeholder Image">
</div>
<div>
    <p>This div does not contain an image.</p>
</div>
div:has(img) {
    border: 2px solid green;
    padding: 10px;
}

לחצו על הכפתור בדמו למטה כדי להוסיף או להסיר תמונה מהתיבה ולראות את הגבול משתנה בזמן אמת:

Interactive Demo

This box can contain an image.

This box never has an image. No green border.

CSS rule: .ch-box:has(img) { border-color: #2d8a4e; }

דוגמה 2: עיצוב אלמנט הורה של פריט רשימה בהתבסס על אלמנט ילד

טרגוט ul כשהוא מכיל li עם מחלקה ספציפית:

<ul>
    <li>Item 1</li>
    <li class="highlight">Item 2</li>
    <li>Item 3</li>
</ul>
<ul>
    <li>Item A</li>
    <li>Item B</li>
    <li>Item C</li>
</ul>
ul:has(li.highlight) {
    background-color: lightyellow;
    padding: 10px;
}

דוגמה 3: עיצוב אימות טפסים

עיצוב מכולה של שדה טופס לפי מצב התקינות של ה-input – ללא צורך ב-JavaScript:

<form>
    <div class="form-group">
        <label for="email">Email:</label>
        <input type="email" id="email" required>
    </div>
    <button type="submit">Submit</button>
</form>
.form-group:has(input:invalid) {
    border: 2px solid red;
    padding: 10px;
}

הקלידו בשדה למטה וצפו בגבול מגיב בזמן אמת. הסלקטורים :has(input:invalid) ו-:has(input:valid) מטפלים במשוב החזותי:

Interactive Demo
CSS rule: .ch-form-group:has(input:invalid) { border-color: #e05555; }
CSS rule: .ch-form-group:has(input:valid) { border-color: #2d8a4e; }

שימושים מעשיים בסביבת ייצור

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

Dark Mode Toggle עם has(:checked):

Checkbox בודד יכול לשלוט בסכמת הצבעים של רכיב שלם. המכולה משתמשת ב-:has(#darkmode:checked) כדי לעבור בין עיצוב בהיר לכהה. אפס שורות של JavaScript.

.card:has(#darkmode:checked) {
    background: #0e1219;
    color: #f1eeee;
}

.card:has(#darkmode:checked) .btn {
    background: #FFB42F;
    color: #0e1219;
}

הפעילו את המתג למטה כדי לראות את זה בפעולה:

Interactive Demo - Pure CSS, Zero JavaScript
Card Component
This card flips between light and dark themes using only CSS :has(:checked). The checkbox state drives the entire color scheme - background, text, and button. No JavaScript involved.
Action Button
.ch-card:has(#ch-darkmode:checked) { background: #0e1219; color: #f1eeee; }

זיהוי מצב ריק – Empty State Detection

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

.list-container:not(:has(li)) .empty-state {
    display: block;
}

.list-container:has(li) .empty-state {
    display: none;
}

בעבר היה צורך ב-JavaScript כמו if (list.children.length === 0). עכשיו הדפדפן מטפל בנראות באופן ריאקטיבי.

שאילתות כמות – Quantity Queries

עיצוב grid בצורה שונה לפי מספר הפריטים. אם יש 4 ילדים או יותר, מעבר למתווה רב-עמודות:

.grid:has(:nth-child(4)) {
    grid-template-columns: repeat(2, 1fr);
}

.grid:not(:has(:nth-child(4))) {
    grid-template-columns: 1fr;
}

השוואה עם JavaScript

לפני :has, עיצוב מותנה לאלמנט הורה דרש שאילתות DOM ושינוי מחלקות ידנית. ההשגה של אותו אפקט של דוגמה 1 ב-JavaScript:

document.addEventListener("DOMContentLoaded", function() {
    const divs = document.querySelectorAll('div');

    divs.forEach(div => {
        if (div.querySelector('img')) {
            div.style.border = '2px solid green';
            div.style.padding = '10px';
        }
    });
});

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

היבטCSS :has()JavaScript
שורות קוד1-3+5-10
ריאקטיבי לשינויי DOMכן, אוטומטיתדורש MutationObserver
ביצועיםאופטימיזציה של הדפדפןהרצת סקריפט + reflow
עובד ללא JSכןלא
לוגיקה מורכבתלאכן

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

תמיכה בדפדפנים

הפסאודו-קלאס :has הגיע לסטטוס Baseline בדצמבר 2023 ונתמך כעת בכל הדפדפנים המרכזיים. Chrome 105+,‏ Firefox 121+,‏ Safari 15.4+ ו-Edge 105+ תומכים בו, עם כיסוי של מעל 96% מהמשתמשים ברחבי העולם נכון לתחילת 2026.

ניתן להשתמש ב-CSS @supports עם @supports selector(:has(*)) לזיהוי תכונות במקרה שנדרש fallback.

Data on support for the css-has feature across the major browsers from caniuse.com

שאלות נפוצות

שאלות נפוצות על הסלקטור :has() ב-CSS:

מהו הסלקטור :has() ב-CSS?
זהו פסאודו-קלאס מ-CSS Selectors Level 4 שמאפשר לעצב אלמנט הורה בהתבסס על הצאצאים שלו. לדוגמה, div:has(img) מטרגט כל div שמכיל אלמנט img.
האם :has() נתמך בכל הדפדפנים?
כן. Chrome 105+,‏ Firefox 121+,‏ Safari 15.4+ ו-Edge 105+ תומכים בו, עם כיסוי של מעל 96% מהמשתמשים ברחבי העולם נכון לתחילת 2026. הסלקטור הגיע לסטטוס Baseline בדצמבר 2023.
האם :has() מחליף JavaScript לבחירת אלמנטים הורים?
לצורך עיצוב, כן. :has() מטפל בעיצוב הורה-ילד ישירות ב-CSS ללא צורך בשאילתות DOM. הוא גם ריאקטיבי - עיצוב מתעדכן אוטומטית כשה-DOM משתנה. ל-JavaScript עדיין יש מקום עבור לוגיקה שמעבר לעיצוב.
האם :has() משפיע על ביצועי העמוד?
סלקטורים לא ממוקדים כמו :has(img) עלולים להאט את הרינדור כיוון שהדפדפן בודק כל אלמנט. השתמשו בקידומת טיפוס כמו div:has(img) וב-:has(> img) לטרגוט צאצאים ישירים בלבד.
האם ניתן לשלב :has() עם פסאודו-קלאסים אחרים?
כן. :has() משתלב היטב עם :not(),‏ :is(),‏ :where() ופסאודו-קלאסים של מצב כמו :checked או :invalid.
מה ההבדל בין :has() לבין :is()?
:is() מטרגט את האלמנט עצמו לפי רשימת סלקטורים. :has() מטרגט אלמנט לפי מה שהוא מכיל. לדוגמה, div:is(.red, .blue) מטרגט divs עם אותן מחלקות, בעוד div:has(.red) מטרגט divs שמכילים ילד עם מחלקה .red.

סיכום

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

אם אתם מחפשים תכונות CSS מודרניות נוספות, כדאי להכיר את תכונת CSS Nesting או את תכונת mask-image.

דיון ותגובות
0 תגובות  ]

השאירו תגובה

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

Savvy WordPress Development official logo