دليل لمحددات الفئة الزائفة CSS الحديثة المدعومة حديثًا
نشرت: 2022-03-10 محددات الفئة الزائفة هي تلك التي تبدأ بحرف النقطتين " :
" وتتطابق بناءً على حالة العنصر الحالي. قد تكون الحالة متعلقة بشجرة المستند ، أو استجابة لتغير في الحالة مثل :hover
أو :checked
.
:any-link
على الرغم من تحديدها في المحددات المستوى 4 ، إلا أن هذه الفئة الزائفة تتمتع بدعم عبر المتصفحات لبعض الوقت. ستطابق الفئة الزائفة any-link
ارتباطًا تشعبيًا مرساة طالما أنها تحتوي على href
. سوف يتطابق بطريقة مكافئة لمطابقة كل من :link
و :visited
مرة واحدة. بشكل أساسي ، قد يؤدي ذلك إلى تقليل الأنماط الخاصة بك بواسطة محدد واحد إذا كنت تضيف خصائص أساسية مثل color
الذي ترغب في تطبيقه على جميع الروابط بغض النظر عن حالة زيارتها.
:any-link { color: blue; text-underline-offset: 0.05em; }
ملاحظة مهمة حول الخصوصية هي أن :any-link
سيفوز ضد محدد حتى لو تم a
a
مستوى أدنى في التسلسل نظرًا لأنه يحتوي على خصوصية فئة. في المثال التالي ، ستكون الروابط أرجوانية:
:any-link { color: purple; } a { color: red; }
لذلك إذا قمت بتقديم :any-link
، فكن على دراية بأنك ستحتاج إلى إدراجه في a
كمحدد إذا كانت ستكون في منافسة مباشرة على الخصوصية.
:focus-visible
أراهن أن أحد أكثر انتهاكات إمكانية الوصول شيوعًا عبر الويب هو إزالة outline
للعناصر التفاعلية مثل الروابط والأزرار ومدخلات النموذج الخاصة بهم :focus
. أحد الأغراض الرئيسية لهذا outline
هو العمل كمؤشر مرئي للمستخدمين الذين يستخدمون لوحات المفاتيح بشكل أساسي للتنقل. تعتبر حالة التركيز المرئي أمرًا بالغ الأهمية كأداة لإيجاد الطريق حيث يقوم هؤلاء المستخدمون بتبويب علامات التبويب عبر الواجهة وللمساعدة في تعزيز العنصر التفاعلي. على وجه التحديد ، يتم تغطية التركيز المرئي في معيار نجاح WCAG 2.4.11: مظهر التركيز (الحد الأدنى).
الغرض من الفئة الزائفة :focus-visible
هو إظهار حلقة تركيز فقط عندما يحدد وكيل المستخدم من خلال الاستدلال أنه يجب أن يكون مرئيًا. بعبارة أخرى: ستحدد المتصفحات وقت التقديم :focus-visible
بناءً على أشياء مثل أسلوب الإدخال ونوع العنصر وسياق التفاعل. لأغراض الاختبار عبر كمبيوتر سطح المكتب مع إدخال لوحة المفاتيح والماوس ، يجب أن ترى :focus-visible
عند الانتقال إلى عنصر تفاعلي ولكن ليس عند النقر فوقه ، باستثناء إدخالات النص ومناطق النص التي يجب أن تظهر :focus-visible
لجميع أنواع مدخلات التركيز.
ملاحظة : لمزيد من التفاصيل ، راجع مسودة العمل الخاصة بمواصفات :focus-visible
.
يبدو أن أحدث إصدارات متصفحي Firefox و Chromium تتعامل الآن مع :focus-visible
على مدخلات النموذج وفقًا للمواصفات التي تنص على أن UA يجب أن يزيل :focus
عندما :focus-visible
. Safari لا يدعم حتى الآن :focus-visible
لذلك نحن بحاجة إلى ضمان :focus
كبديل لتجنب إزالة outline
لإمكانية الوصول.
بالنظر إلى زر وإدخال نص مع مجموعة الأنماط التالية ، دعنا نرى ما يحدث:
input:focus, button:focus { outline: 2px solid blue; outline-offset: 0.25em; } input:focus-visible { outline: 2px solid transparent; border-color: blue; } button:focus:not(:focus-visible) { outline: none; } button:focus-visible { outline: 2px solid transparent; box-shadow: 0 0 0 2px #fff, 0 0 0 4px blue; }
الكروم وفايرفوكس
-
input
إزالة بشكل صحيح:focus
عندما يتم تركيز العناصر عبر إدخال الماوس لصالح:focus-visible
مما يؤدي إلى تغييرborder-color
وإخفاءoutline
عند إدخال لوحة المفاتيح -
button
لا يستخدم فقط:focus-visible
بدون القاعدة الإضافيةbutton:focus:not(:focus-visible)
الذي يزيل المخطط التفصيلي على:focus
، ولكنه سيسمح برؤيةbox-shadow
فقط عند إدخال لوحة المفاتيح
سفاري
-
input
يستمر في استخدام:focus
فقط -
button
يبدو أن هذا يحترم جزئيًا هدف:focus-visible
على الزر عن طريق إخفاء:focus
عند النقر ، ولكن لا يزال يُظهر:focus
على تفاعل لوحة المفاتيح
حتى الآن ، ستكون التوصية هي الاستمرار في تضمين :focus
ثم تحسينها تدريجيًا لاستخدام :focus-visible
الذي يسمح به الرمز التجريبي. إليك CodePen لتستمر في الاختبار باستخدام:
:focus-within
تحظى فئة :focus-within
pseudo class بدعم بين جميع المتصفحات الحديثة ، وتعمل تقريبًا كمحدد رئيسي ولكن فقط لشرط محدد للغاية. عند إرفاقه بعنصر يحتوي ويتطابق عنصر فرعي مع :focus
، يمكن إضافة الأنماط إلى العنصر المحتوي و / أو أي عناصر أخرى داخل الحاوية.
التحسين العملي لاستخدام هذا السلوك هو تصميم ملصق نموذج عندما يكون التركيز على الإدخال المرتبط. لكي يعمل هذا ، نقوم بلف الملصق والإدخال في حاوية ، ثم نعلق :focus-within
تلك الحاوية بالإضافة إلى تحديد الملصق:
.form-group:focus-within label { color: blue; }
ينتج عن هذا تحول التسمية إلى اللون الأزرق عندما يكون التركيز على الإدخال.
يتضمن هذا العرض التوضيحي CodePen أيضًا إضافة مخطط تفصيلي مباشرة إلى .form-group
:
:is()
يُعرف أيضًا باسم الفئة الزائفة "تطابق أي" ، يمكن لـ :is()
أخذ قائمة من المحددات لمحاولة التطابق معها. على سبيل المثال ، بدلاً من سرد أنماط العناوين بشكل فردي ، يمكنك تجميعها ضمن محدد :is(h1, h2, h3)
.
زوجان من السلوكيات الفريدة حول :is()
قائمة المحدد:
- إذا كان المحدد المدرج غير صالح ، فستستمر القاعدة في مطابقة المحددات الصالحة.
:is(-ua-invalid, article, p)
ستطابق القاعدةarticle
وp
. - ستساوي الخصوصية المحسوبة خصوصية المحدد الذي تم اجتيازه بأعلى مستوى من الخصوصية. على سبيل المثال
:is(#id, p)
سيكون له خصوصية#id
- 1.0.0 - بينما:is(p, a)
سيكون له خصوصية 0.0.1.
يعتبر السلوك الأول لتجاهل المحددات غير الصالحة ميزة أساسية. عند استخدام محددات أخرى في مجموعة حيث يكون أحد المحددات غير صالح ، فإن المتصفح سيلغي القاعدة بأكملها. يتم تشغيل هذا في بعض الحالات التي لا تزال فيها بادئات البائع ضرورية ، ويؤدي تجميع المحددات البادئة وغير مسبوقة إلى فشل القاعدة بين جميع المتصفحات. باستخدام :is()
يمكنك تجميع هذه الأنماط بأمان وسيتم تطبيقها عندما تتطابق ويتم تجاهلها عندما لا تتطابق.
بالنسبة لي ، فإن تجميع أنماط العناوين كما ذكرنا سابقًا يعد بالفعل فوزًا كبيرًا باستخدام هذا المحدد. إنه أيضًا نوع القاعدة التي سأشعر بالراحة عند استخدامها دون رجوع عند تطبيق أنماط غير حرجة ، مثل:
:is(h1, h2, h3) { line-height: 1.2; } :is(h2, h3):not(:first-child) { margin-top: 2em; }
في هذا المثال (الذي يأتي من أنماط المستندات في مشروعي SmolCSS) ، فإن الحصول على line-height
أكبر موروث من الأنماط الأساسية أو الافتقار إلى margin-top
لا يمثل بالفعل مشكلة للمتصفحات غير الداعمة. إنها ببساطة أقل من مثالية. ما لا ترغب في استخدامه :is()
حتى الآن سيكون أنماط تخطيط مهمة مثل Grid أو Flex التي تتحكم بشكل كبير في واجهتك.
بالإضافة إلى ذلك ، عند تقييدك بمحدد آخر ، يمكنك اختبار ما إذا كان المحدد الأساسي يطابق محددًا تنازليًا داخل :is()
. على سبيل المثال ، تحدد القاعدة التالية فقط الفقرات التي تنحدر مباشرة من المقالات. يتم استخدام المحدد العام كمرجع لمحدد القاعدة p
.
p:is(article > *)
للحصول على أفضل دعم حالي ، إذا كنت ترغب في البدء في استخدامه ، فستحتاج أيضًا إلى مضاعفة الأنماط من خلال تضمين القواعد المكررة باستخدام :-webkit-any()
و :matches()
. تذكر أن تضع هذه القواعد الفردية ، أو حتى المتصفح الداعم سوف يتخلص منها! بمعنى آخر ، قم بتضمين كل ما يلي:
:matches(h1, h2, h3) { } :-webkit-any(h1, h2, h3) { } :is(h1, h2, h3) { }
وتجدر الإشارة في هذه المرحلة إلى أنه جنبًا إلى جنب مع المحدِّدات الأحدث نفسها ، هناك نسخة محدَّثة من @supports
وهي @supports selector
. هذا متاح أيضًا لأن @supports not selector
.
ملاحظة : في الوقت الحالي (من المتصفحات الحديثة) ، لا يدعم Safari سوى هذه القاعدة.
يمكنك التحقق مما :is()
الدعم بشيء مثل ما يلي ، لكنك في الواقع ستخسر دعم Safari لأن Safari يدعم :is()
ولكنه لا يدعم @supports selector
.
@supports selector(:is(h1)) { :is(h1, h2, h3) { line-height: 1.1; } }
:where()
الفئة الزائفة :where()
متطابقة تقريبًا مع :is()
باستثناء اختلاف جوهري واحد: سيكون لها دائمًا خصوصية صفرية. هذا له آثار لا تصدق على الأشخاص الذين يبنون أطر عمل وموضوعات وأنظمة تصميم . باستخدام :where()
، يمكن للمؤلف تعيين الإعدادات الافتراضية ويمكن للمطورين المتلقين للمعلومات تضمين تجاوزات أو امتدادات بدون تضارب في الخصوصية.
ضع في اعتبارك المجموعة التالية من img
الصور. باستخدام :where()
، حتى مع وجود محدد خصوصية أعلى ، تظل الخصوصية صفرية. في المثال التالي ، ما حدود اللون التي تعتقد أن الصورة ستحتوي عليها؟
:where(article img:not(:first-child)) { border: 5px solid red; } :where(article) img { border: 5px solid green; } img { border: 5px solid orange; }
القاعدة الأولى لها خصوصية صفرية منذ احتوائها بالكامل داخل :where()
. لذلك بشكل مباشر ضد القاعدة الثانية ، القاعدة الثانية هي الفائز. تقديم محدد عنصر img
فقط كقاعدة أخيرة ، سوف يفوز بسبب التتالي. هذا لأنه سيحسب بنفس الخصوصية مثل :where(article) img
منذ :where()
الجزء لا يزيد من الخصوصية.
يعد استخدام :where()
جنبًا إلى جنب مع العناصر الاحتياطية أكثر صعوبة نظرًا لميزة الخصوصية الصفرية نظرًا لأن هذه الميزة هي على الأرجح سبب رغبتك في استخدامها مرة أخرى :is()
. وإذا أضفت قواعد احتياطية ، فمن المحتمل أن تتفوق على :where()
نظرًا لطبيعتها. وله دعم عام أفضل من @supports selector
، لذا فإن محاولة استخدام ذلك لصياغة احتياطي من غير المرجح أن توفر الكثير (إن وجد) من المكاسب. بشكل أساسي ، كن على دراية بعدم القدرة على إنشاء احتياطات بشكل صحيح لـ :where()
وتحقق بعناية من بياناتك الخاصة لتحديد ما إذا كان من الآمن البدء في استخدامها لجمهورك الفريد.
يمكنك إجراء مزيد من الاختبار :where()
باستخدام CodePen التالية التي تستخدم محددات img
أعلاه:
معزز :not()
تم دعم القاعدة :not()
selector منذ Internet Explorer 9. ولكن المحددات المستوى 4 تعزز :not()
بالسماح لها بأخذ قائمة محددات ، تمامًا مثل :is()
و :where()
.
توفر القواعد التالية نفس النتيجة في دعم المتصفحات:
article :not(h2):not(h3):not(h4) { margin-bottom: 1.5em; } article :not(h2, h3, h4) { margin-bottom: 1.5em; }
تتمتع قدرة :not()
على قبول قائمة المحددات بدعم متصفح حديث رائع.
كما رأينا مع :is()
، مُحسَّن :not()
يمكن أيضًا أن يحتوي على مرجع إلى محدد القاعدة باعتباره منحدرًا باستخدام *
. يوضح CodePen هذه القدرة عن طريق تحديد الروابط التي ليست من نسل nav
.
المكافأة : يتضمن العرض التوضيحي السابق أيضًا مثالاً على التسلسل :not()
و :is()
لتحديد الصور التي ليست أشقاء متجاورين لأي من عناصر h2
أو h3
.
مقترح ولكنه "معرض للخطر" - :has()
الفئة الزائفة النهائية التي تعتبر اقتراحًا مثيرًا للغاية ولكن لا يوجد بها متصفح حالي ينفذها حتى بطريقة تجريبية هي :has()
. في الواقع ، تم إدراجه في مسودة المحرر المستوى 4 المحدد على أنه "معرض للخطر" مما يعني أنه من المعروف أنه يواجه صعوبات في استكمال تنفيذه وبالتالي قد يتم حذفه من التوصية.
إذا تم تنفيذه ، فسيكون :has()
أساسًا "المحدد الرئيسي" الذي يتوق العديد من مستخدمي CSS إلى توفيره. سيعمل مع منطق مشابه لمزيج من :focus-within
و :is()
مع المحددات السفلية ، حيث تبحث عن وجود أحفاد ولكن التصميم المطبق سيكون للعنصر الأصل.
بالنظر إلى القاعدة التالية ، إذا احتوى التنقل على زر ، فسيؤدي ذلك إلى تقليل التنقل في الحشوة العلوية والسفلية:
nav { padding: 0.75rem 0.25rem; nav:has(button) { padding-top: 0.25rem; padding-bottom: 0.25rem; }
مرة أخرى ، لم يتم تنفيذ هذا حاليًا في أي متصفح حتى بشكل تجريبي - ولكن من الممتع التفكير فيه! قدم Robin Rendle رؤى إضافية حول هذا المحدد المستقبلي على CSS-Tricks.
تنويه مشرف من المستوى 3 :empty
فئة زائفة مفيدة قد تكون فاتتك من المحددات المستوى 3 هي :empty
والتي تطابق عنصرًا عندما لا يحتوي على عناصر فرعية ، بما في ذلك العقد النصية.
تتطابق القاعدة p:empty
مع <p></p>
ولكن ليس <p>Hello</p>
.
إحدى الطرق التي يمكنك استخدامها :empty
هي إخفاء العناصر التي ربما تكون عناصر نائبة للمحتوى الديناميكي الذي يتم ملؤه بجافا سكريبت. ربما يكون لديك div سيتلقى نتائج البحث ، وعندما يتم ملؤه سيكون له حدود وبعض المساحة المتروكة. ولكن مع عدم وجود نتائج حتى الآن ، فأنت لا تريد أن تشغل مساحة على الصفحة. باستخدام :empty
يمكنك إخفاؤه باستخدام:
.search-results:empty { display: none; }
قد تفكر في إضافة رسالة في حالة فارغة وتميل إلى إضافتها بعنصر content
زائف. يتمثل الخطأ هنا في أن الرسائل قد لا تكون متاحة لمستخدمي التكنولوجيا المساعدة والتي لا تتفق فيما إذا كان بإمكانهم الوصول إلى content
. بمعنى آخر ، للتأكد من إمكانية الوصول إلى نوع الرسالة "لا توجد نتائج" ، قد ترغب في إضافة ذلك كعنصر حقيقي مثل فقرة (لن يكون من الممكن الوصول إلى aria-label
div مخفي).
موارد للتعرف على المحددات
يحتوي CSS على العديد من المحددات بما في ذلك الفئات الزائفة. فيما يلي بعض الأماكن الأخرى للتعرف على المزيد حول ما هو متاح:
- تتضمن وثائق محددات MDN CSS قائمة شاملة مصنفة ؛
- لقد كتبت دليلاً من جزأين لمحددات CSS المتقدمة ، يمكنك البدء بالجزء الأول ؛
- استمتع بالتعلم عن محددات CSS مع لعبة CSS Diner ؛
- أنشأت Kitty Giraudel أداة شرح محدد من شأنها تقسيم ووصف أجزاء من المحدد المقدم.