اكتشف محدد CSS :has()، الذي يغير قواعد اللعبة في تحديد العنصر الأب. تعلم التطبيقات العملية، والتوافق مع المتصفحات، والتقنيات المتقدمة لإحداث ثورة في تنسيق CSS الخاص بك.
إتقان محدد CSS :has(): إطلاق العنان لقوة تحديد العنصر الأب
لسنوات، كان مطورو CSS يتوقون إلى طريقة بسيطة وفعالة لتحديد العناصر الأب بناءً على أبنائها. لقد انتهى الانتظار! وصلت الفئة الزائفة :has()
أخيرًا، وهي تحدث ثورة في كيفية كتابتنا لـ CSS. يسمح لك هذا المحدد القوي باستهداف عنصر أب إذا كان يحتوي على عنصر ابن معين، مما يفتح عالمًا من الإمكانيات للتنسيق الديناميكي والمتجاوب.
ما هو محدد :has()؟
الفئة الزائفة :has()
هي فئة زائفة علائقية في CSS تقبل قائمة محددات كوسيط. تقوم بتحديد عنصر إذا تطابق أي من المحددات في القائمة مع عنصر واحد على الأقل من بين العناصر المنحدرة من العنصر الأصلي. بعبارة أبسط، فإنها تتحقق مما إذا كان العنصر الأب لديه ابن معين، وإذا كان الأمر كذلك، يتم تحديد الأب.
الصيغة الأساسية هي:
parent:has(child) { /* قواعد CSS */ }
يحدد هذا الأمر العنصر parent
فقط إذا كان يحتوي على عنصر child
واحد على الأقل.
لماذا يعتبر محدد :has() مهمًا جدًا؟
تقليديًا، كانت قدرة CSS محدودة في تحديد العناصر الأب بناءً على أبنائها. غالبًا ما كان هذا القصور يتطلب حلولًا معقدة باستخدام JavaScript أو حلولًا بديلة لتحقيق التنسيق الديناميكي. يلغي محدد :has()
الحاجة إلى هذه الأساليب المرهقة، مما يسمح بكتابة كود CSS أنظف وأكثر قابلية للصيانة وأفضل أداءً.
إليك لماذا يعتبر :has()
مغيرًا لقواعد اللعبة:
- تبسيط التنسيق: يمكن الآن تحقيق قواعد التنسيق المعقدة التي كانت تتطلب سابقًا JavaScript باستخدام CSS خالص.
- تحسين الصيانة: كود CSS النظيف والموجز أسهل في الفهم والتصحيح والصيانة.
- أداء محسن: يؤدي استخدام محددات CSS الأصلية بشكل عام إلى أداء أفضل مقارنة بالحلول المعتمدة على JavaScript.
- مرونة أكبر: يوفر محدد
:has()
مرونة أكبر في إنشاء تصميمات ديناميكية ومتجاوبة.
أمثلة أساسية على محدد :has()
لنبدأ ببعض الأمثلة البسيطة لتوضيح قوة محدد :has()
.
مثال 1: تنسيق حاوية Div بناءً على وجود صورة
لنفترض أنك تريد إضافة إطار إلى عنصر <div>
فقط إذا كان يحتوي على عنصر <img>
:
div:has(img) {
border: 2px solid blue;
}
ستطبق قاعدة CSS هذه إطارًا أزرق على أي <div>
يحتوي على عنصر <img>
واحد على الأقل.
مثال 2: تنسيق عنصر قائمة بناءً على وجود وسم Span
لنفترض أن لديك قائمة من العناصر، وتريد تمييز عنصر القائمة إذا كان يحتوي على عنصر <span>
بفئة معينة:
li:has(span.highlight) {
background-color: yellow;
}
ستغير قاعدة CSS هذه لون خلفية أي <li>
يحتوي على <span>
بالفئة "highlight" إلى اللون الأصفر.
مثال 3: تنسيق تسمية نموذج بناءً على صلاحية الإدخال
يمكنك استخدام :has()
لتنسيق تسمية نموذج بناءً على ما إذا كان حقل الإدخال المرتبط بها صالحًا أم غير صالح (بالاقتران مع الفئة الزائفة :invalid
):
label:has(+ input:invalid) {
color: red;
font-weight: bold;
}
سيجعل هذا التسمية حمراء وسميكة إذا كان حقل الإدخال الذي يليه مباشرة غير صالح.
استخدامات متقدمة لمحدد :has()
يصبح محدد :has()
أكثر قوة عند دمجه مع محددات وفئات زائفة أخرى في CSS. إليك بعض حالات الاستخدام المتقدمة:
مثال 4: استهداف العناصر الفارغة
يمكنك استخدام الفئة الزائفة :not()
بالاقتران مع :has()
لاستهداف العناصر التي *لا* تحتوي على ابن معين. على سبيل المثال، لتنسيق الحاويات التي *لا* تحتوي على صور:
div:not(:has(img)) {
background-color: #f0f0f0;
}
سيطبق هذا خلفية رمادية فاتحة على أي <div>
لا يحتوي على عنصر <img>
.
مثال 5: إنشاء تخطيطات معقدة
يمكن استخدام محدد :has()
لإنشاء تخطيطات ديناميكية بناءً على محتوى الحاوية. على سبيل المثال، يمكنك تغيير تخطيط الشبكة بناءً على وجود نوع معين من العناصر داخل خلية الشبكة.
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.grid-item:has(img) {
grid-column: span 2;
}
سيجعل هذا عنصر الشبكة يمتد على عمودين إذا كان يحتوي على صورة.
مثال 6: تنسيق النماذج الديناميكي
يمكنك استخدام :has()
لتنسيق عناصر النموذج ديناميكيًا بناءً على حالتها (على سبيل المثال، ما إذا كانت في حالة تركيز أو مملوءة أو صالحة).
.form-group:has(input:focus) {
box-shadow: 0 0 5px rgba(0, 0, 255, 0.5);
}
.form-group:has(input:valid) {
border-color: green;
}
.form-group:has(input:invalid) {
border-color: red;
}
سيضيف هذا ظل صندوق أزرق عند التركيز على حقل الإدخال، وإطارًا أخضر إذا كان الإدخال صالحًا، وإطارًا أحمر إذا كان الإدخال غير صالح.
مثال 7: التنسيق بناءً على عدد الأبناء
بينما لا يقوم :has()
مباشرةً بحساب عدد الأبناء، يمكنك دمجه مع محددات وخصائص CSS أخرى لتحقيق تأثيرات مماثلة. على سبيل المثال، يمكنك استخدام :only-child
لتنسيق العنصر الأب إذا كان لديه ابن واحد فقط من نوع معين.
div:has(> p:only-child) {
background-color: lightgreen;
}
سيقوم هذا بتنسيق <div>
بخلفية خضراء فاتحة فقط إذا كان يحتوي على عنصر <p>
واحد كابن مباشر له.
التوافق مع المتصفحات والحلول البديلة
حتى أواخر عام 2023، يتمتع محدد :has()
بدعم ممتاز في المتصفحات الحديثة، بما في ذلك Chrome و Firefox و Safari و Edge. ومع ذلك، من الضروري التحقق من التوافق على Can I use قبل نشره في بيئة الإنتاج، خاصة إذا كنت بحاجة إلى دعم المتصفحات القديمة.
فيما يلي تفصيل لاعتبارات التوافق:
- المتصفحات الحديثة: دعم ممتاز في أحدث إصدارات Chrome و Firefox و Safari و Edge.
- المتصفحات القديمة: لا يوجد دعم في المتصفحات القديمة (مثل Internet Explorer).
توفير الحلول البديلة
إذا كنت بحاجة إلى دعم المتصفحات القديمة، فستحتاج إلى توفير حلول بديلة. إليك بعض الاستراتيجيات:
- JavaScript: استخدم JavaScript لاكتشاف دعم المتصفح لـ
:has()
وتطبيق تنسيق بديل إذا لزم الأمر. - استعلامات الميزات: استخدم استعلامات ميزات CSS (
@supports
) لتوفير تنسيقات مختلفة بناءً على دعم المتصفح. - التحسين التدريجي: ابدأ بتصميم أساسي وعملي يعمل في جميع المتصفحات، ثم قم بتحسين التصميم تدريجيًا للمتصفحات التي تدعم
:has()
.
إليك مثال على استخدام استعلام الميزات:
.parent {
/* تنسيق أساسي لجميع المتصفحات */
border: 1px solid black;
}
@supports selector(:has(img)) {
.parent:has(img) {
/* تنسيق محسن للمتصفحات التي تدعم :has() */
border: 3px solid blue;
}
}
سيطبيق هذا الكود إطارًا أسود على عنصر .parent
في جميع المتصفحات. في المتصفحات التي تدعم :has()
، سيطبق إطارًا أزرق إذا كان عنصر .parent
يحتوي على صورة.
اعتبارات الأداء
بينما يوفر :has()
مزايا كبيرة، من الضروري مراعاة تأثيره المحتمل على الأداء، خاصة عند استخدامه بشكل مكثف أو مع محددات معقدة. تحتاج المتصفحات إلى تقييم المحدد لكل عنصر في الصفحة، مما قد يصبح مكلفًا من الناحية الحسابية.
إليك بعض النصائح لتحسين أداء :has()
:
- حافظ على بساطة المحددات: تجنب استخدام محددات معقدة للغاية داخل الفئة الزائفة
:has()
. - حدد النطاق: طبق
:has()
على عناصر أو حاويات محددة بدلاً من تطبيقه بشكل عام. - اختبر الأداء: استخدم أدوات المطور في المتصفح لمراقبة أداء قواعد CSS الخاصة بك وتحديد الاختناقات المحتملة.
أخطاء شائعة يجب تجنبها
عند العمل مع محدد :has()
، من السهل ارتكاب أخطاء يمكن أن تؤدي إلى نتائج غير متوقعة. إليك بعض المزالق الشائعة التي يجب تجنبها:
- مشاكل الخصوصية (Specificity): تأكد من أن قواعد
:has()
الخاصة بك لديها خصوصية كافية لتجاوز قواعد CSS الأخرى. استخدم نفس خطوات استكشاف أخطاء الخصوصية وإصلاحها كالعادة. - التداخل غير الصحيح: تحقق جيدًا من تداخل العناصر للتأكد من أن محدد
:has()
يستهدف العنصر الأب الصحيح. - المحددات المعقدة للغاية: تجنب استخدام محددات معقدة للغاية داخل الفئة الزائفة
:has()
، لأن هذا يمكن أن يؤثر على الأداء. - افتراض الأبناء المباشرين: تذكر أن
:has()
يتحقق من *أي* عنصر منحدر، وليس فقط الأبناء المباشرين. استخدم رابط الابن المباشر (>
) إذا كنت بحاجة إلى استهداف الأبناء المباشرين فقط (على سبيل المثال،div:has(> img)
).
أفضل الممارسات لاستخدام :has()
لتحقيق أقصى استفادة من محدد :has()
وتجنب المشاكل المحتملة، اتبع أفضل الممارسات التالية:
- استخدمه بحكمة: استخدم
:has()
فقط عندما يوفر ميزة واضحة على تقنيات CSS الأخرى أو حلول JavaScript. - اجعله بسيطًا: فضل المحددات البسيطة والقابلة للقراءة على المحددات المعقدة والمتشابكة.
- اختبر جيدًا: اختبر قواعد CSS الخاصة بك في متصفحات وأجهزة مختلفة للتأكد من أنها تعمل كما هو متوقع.
- وثق الكود الخاص بك: أضف تعليقات إلى كود CSS لشرح الغرض والوظيفة من قواعد
:has()
الخاصة بك. - ضع في اعتبارك إمكانية الوصول: تأكد من أن استخدامك لـ
:has()
لا يؤثر سلبًا على إمكانية الوصول. على سبيل المثال، لا تعتمد فقط على تغييرات التنسيق التي يطلقها:has()
لنقل معلومات مهمة؛ استخدم سمات ARIA أو آليات بديلة للمستخدمين من ذوي الإعاقة.
أمثلة من العالم الحقيقي وحالات الاستخدام
دعنا نستكشف بعض الأمثلة من العالم الحقيقي لكيفية استخدام محدد :has()
لحل تحديات التصميم الشائعة.
مثال 8: إنشاء قوائم تنقل متجاوبة
يمكنك استخدام :has()
لإنشاء قوائم تنقل متجاوبة تتكيف مع أحجام الشاشات المختلفة بناءً على وجود عناصر قائمة معينة.
تخيل سيناريو تريد فيه عرض قائمة تنقل مختلفة اعتمادًا على ما إذا كان المستخدم قد سجل الدخول أم لا. إذا كانوا قد سجلوا الدخول، فيمكنك عرض إجراءات الملف الشخصي وتسجيل الخروج، وإذا لم يكن الأمر كذلك، فيمكنك عرض تسجيل الدخول/التسجيل.
nav:has(.user-profile) {
/* تنسيقات للمستخدمين المسجلين دخولهم */
}
nav:not(:has(.user-profile)) {
/* تنسيقات للمستخدمين غير المسجلين دخولهم */
}
مثال 9: تنسيق مكونات البطاقات
يمكن استخدام محدد :has()
لتنسيق مكونات البطاقات بناءً على محتواها. على سبيل المثال، يمكنك إضافة ظل إلى بطاقة فقط إذا كانت تحتوي على صورة.
.card:has(img) {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
مثال 10: تنفيذ السمات الديناميكية
يمكنك استخدام :has()
لتنفيذ سمات ديناميكية بناءً على تفضيلات المستخدم أو إعدادات النظام. على سبيل المثال، يمكنك تغيير لون خلفية الصفحة بناءً على ما إذا كان المستخدم قد قام بتمكين الوضع المظلم.
body:has(.dark-mode) {
background-color: #333;
color: #fff;
}
توضح هذه الأمثلة تعدد استخدامات محدد :has()
وقدرته على حل مجموعة واسعة من تحديات التصميم.
مستقبل CSS: ماذا بعد؟
يمثل إدخال محدد :has()
خطوة مهمة إلى الأمام في تطور CSS. إنه يمكّن المطورين من إنشاء أوراق أنماط أكثر ديناميكية واستجابة وقابلية للصيانة مع اعتماد أقل على JavaScript. مع استمرار نمو دعم المتصفحات لـ :has()
، يمكننا أن نتوقع رؤية المزيد من الاستخدامات المبتكرة والإبداعية لهذا المحدد القوي.
بالنظر إلى المستقبل، تستكشف مجموعة عمل CSS ميزات وتحسينات أخرى مثيرة من شأنها توسيع قدرات CSS بشكل أكبر. وتشمل هذه:
- استعلامات الحاوية (Container Queries): السماح للمكونات بتكييف تنسيقها بناءً على حجم حاويتها، بدلاً من إطار العرض.
- طبقات التتالي (Cascade Layers): توفير مزيد من التحكم في تتالي وخصوصية قواعد CSS.
- محددات أكثر تقدمًا: تقديم محددات جديدة يمكنها استهداف العناصر بناءً على سماتها ومحتواها وموقعها في شجرة المستند.
من خلال البقاء على اطلاع بأحدث تطورات CSS وتبني ميزات جديدة مثل :has()
، يمكن للمطورين إطلاق العنان للإمكانات الكاملة لـ CSS وإنشاء تجارب ويب استثنائية حقًا.
الخاتمة
يعد محدد :has()
إضافة قوية إلى صندوق أدوات CSS، حيث يتيح تحديد العنصر الأب ويفتح إمكانيات جديدة للتنسيق الديناميكي والمتجاوب. في حين أنه من الضروري مراعاة توافق المتصفحات وتأثيرات الأداء، فإن فوائد استخدام :has()
لكتابة كود CSS أنظف وأكثر قابلية للصيانة وأفضل أداءً لا يمكن إنكارها. احتضن هذا المحدد الذي يغير قواعد اللعبة وأحدث ثورة في تنسيق CSS الخاص بك اليوم!
تذكر أن تضع في اعتبارك إمكانية الوصول وتوفير آليات بديلة للمتصفحات القديمة. باتباع أفضل الممارسات الموضحة في هذا الدليل، يمكنك الاستفادة من الإمكانات الكاملة لمحدد :has()
وإنشاء تجارب ويب استثنائية حقًا للمستخدمين في جميع أنحاء العالم.