The CSS Podcast - 015: Pseudo-classes
لنفترض أنّ لديك نموذج اشتراك عبر البريد الإلكتروني،
وتريد أن يحتوي حقل نموذج البريد الإلكتروني على حدّ أحمر إذا كان يتضمّن عنوان بريد إلكتروني غير صالح.
كيف يمكن إجراء ذلك؟
يمكنك استخدام :invalid
فئة زائفة CSS،
وهي إحدى الفئات الزائفة العديدة التي يوفّرها المتصفّح.
تتيح لك الفئة الزائفة تطبيق الأنماط استنادًا إلى تغييرات الحالة والعوامل الخارجية. وهذا يعني أنّ تصميمك يمكن أن يتفاعل مع إدخال المستخدم، مثل عنوان بريد إلكتروني غير صالح. يتم تناول هذه العناصر في وحدة أدوات الاختيار، وستشرح لك هذه الوحدة هذه العناصر بمزيد من التفصيل.
على عكس العناصر الزائفة، التي يمكنك التعرّف على المزيد عنها في الوحدة السابقة، ترتبط الفئات الزائفة بحالات معيّنة قد يكون العنصر فيها، بدلاً من تصميم أجزاء من هذا العنصر بشكل عام.
حالات تفاعلية
تنطبق الفئات الزائفة التالية بسبب تفاعل المستخدم مع صفحتك.
:hover
إذا كان لدى المستخدم جهاز تأشير، مثل ماوس أو لوحة لمس،
ووضع المؤشر فوق أحد العناصر،
يمكنك ربط هذا الإجراء باستخدام
:hover
لتطبيق الأنماط.
هذه طريقة مفيدة للإشارة إلى إمكانية التفاعل مع أحد العناصر.
:active
يتم تفعيل هذه الحالة عند التفاعل مع عنصر بشكل نشط، مثل النقر، قبل رفع الإصبع عن النقرة. إذا تم استخدام جهاز تأشير مثل الماوس، تكون هذه الحالة عند بدء النقر ولم يتم تحريره بعد.
:focus
و:focus-within
و:focus-visible
إذا كان بإمكان عنصر تلقّي التركيز، مثل <button>
، يمكنك التفاعل مع هذه الحالة باستخدام الفئة الزائفة :focus
.
يمكنك أيضًا التفاعل إذا تلقّى عنصر ثانوي من العنصر الخاص بك التركيز باستخدام
:focus-within
.
ستعرض العناصر القابلة للتركيز، مثل الأزرار، حلقة تركيز عندما تكون قيد التركيز، حتى عند النقر عليها. في هذا النوع من الحالات، سيطبّق المطوّر رمز CSS التالي:
button:focus {
outline: none;
}
تزيل ورقة CSS هذه حلقة التركيز التلقائية في المتصفّح عندما يركّز عنصر ما،
ما يؤدي إلى حدوث مشكلة في إمكانية الوصول للمستخدمين الذين يتنقّلون في صفحة ويب باستخدام لوحة المفاتيح.
إذا لم يكن هناك نمط تركيز، لن يتمكّن المستخدمون من تتبُّع موضع التركيز الحالي عند استخدام مفتاح Tab.
باستخدام :focus-visible
، يمكنك عرض نمط تركيز عندما يتلقّى عنصر التركيز باستخدام لوحة المفاتيح، مع استخدام القاعدة outline: none
أيضًا لمنع ذلك عندما يتفاعل جهاز مؤشر مع العنصر.
button:focus {
outline: none;
}
button:focus-visible {
outline: 1px solid black;
}
:target
يختار :target
الفئة الزائفة عنصرًا يتضمّن id
مطابقًا لجزء من عنوان URL.
لنفترض أنّ لديك رمز HTML التالي:
<article id="content">
<!-- ... -->
</article>
يمكنك إرفاق أنماط بهذا العنصر عندما يحتوي عنوان URL على #content
.
#content:target {
background: yellow;
}
ويفيد ذلك في إبراز المساحات التي قد تم ربطها بشكل خاص، مثل المحتوى الرئيسي على موقع إلكتروني، باستخدام رابط تخطّي.
الحالات السابقة
:link
يمكن تطبيق الفئة الزائفة :link
على أي عنصر <a>
يتضمّن قيمة href
لم تتم زيارتها بعد.
:visited
يمكنك تنسيق رابط سبق أن زاره المستخدم باستخدام الفئة الزائفة
:visited
.
هذه الحالة هي عكس حالة :link
، ولكن لديك عدد أقل من خصائص CSS التي يمكنك استخدامها لأسباب أمنية.
يمكنك فقط تنسيق color
وbackground-color
وborder-color
وoutline-color
ولون fill
وstroke
بتنسيق SVG.
المسائل المتعلقة بالطلبات
إذا حدّدت نمط :visited
،
يمكن إلغاؤه بواسطة فئة زائفة للرابط ذات مستوى تحديد مساوٍ على الأقل.
لهذا السبب، ننصحك باستخدام قاعدة LVHA لتنسيق الروابط باستخدام الفئات الزائفة بترتيب معيّن: :link
و:visited
و:hover
و:active
.
a:link {}
a:visited {}
a:hover {}
a:active {}
حالات النموذج
يمكن لفئات العناصر الزائفة التالية اختيار عناصر النموذج، في الحالات المختلفة التي قد تكون عليها هذه العناصر أثناء التفاعل معها.
:disabled
و:enabled
إذا تم إيقاف عنصر نموذج، مثل <button>
، من خلال المتصفح، يمكنك ربط هذا العنصر بالحالة باستخدام الفئة الزائفة :disabled
.
تتوفّر الفئة الزائفة :enabled
للحالة المعاكسة،
مع أنّ عناصر النماذج تكون :enabled
تلقائيًا،
لذلك قد لا تحتاج إلى استخدام هذه الفئة الزائفة.
:checked
و:indeterminate
تتوفّر فئة :checked
الزائفة عندما يكون عنصر نموذج متوافق،
مثل مربّع اختيار أو زر اختيار، في حالة محدّدة.
الحالة :checked
هي حالة ثنائية (صحيحة أو غير صحيحة)،
ولكن مربّعات الاختيار تتضمّن حالة وسيطة عندما لا تكون محدّدة بعلامة أو غير محدّدة بعلامة.
ويُعرف ذلك باسم حالة
:indeterminate
.
من الأمثلة على هذه الحالة عندما يكون لديك عنصر تحكّم "اختيار الكل" يضع علامة في جميع مربّعات الاختيار في مجموعة. إذا أزال المستخدم العلامة من أحد مربّعات الاختيار هذه، لن يمثّل مربّع الاختيار الرئيسي تحديد "الكل"، وبالتالي يجب وضعه في حالة غير محدّدة.
يحتوي العنصر <progress>
أيضًا على حالة غير محدّدة يمكن تصميمها.
من حالات الاستخدام الشائعة إظهارها بمظهر مخطط للإشارة إلى أنّه من غير المعروف مقدار ما يلزم إضافته.
:placeholder-shown
إذا كان حقل النموذج يتضمّن السمة placeholder
بدون قيمة،
يمكن استخدام الفئة الزائفة :placeholder-shown
لإضافة أنماط إلى تلك الحالة.
وبمجرد توفّر محتوى في الحقل، سواء كان يتضمّن placeholder
أم لا، لن تنطبق هذه الحالة.
حالات التحقّق
يمكنك الاستجابة للتحقّق من صحة نموذج HTML باستخدام فئات زائفة مثل
:valid
و:invalid
و:in-range
.
تكون الفئتان الزائفتان :valid
و:invalid
مفيدتَين في سياقات مثل حقل البريد الإلكتروني الذي يتضمّن pattern
يجب مطابقته ليكون حقلًا صالحًا.
يمكن عرض حالة القيمة الصالحة هذه للمستخدم، ما يساعده في فهم أنّه يمكنه الانتقال بأمان إلى الحقل التالي.
تتوفّر الفئة الزائفة :in-range
إذا كان عنصر الإدخال يتضمّن min
وmax
،
مثل عنصر إدخال رقمي وكانت القيمة ضمن تلك الحدود.
باستخدام نماذج HTML، يمكنك تحديد أنّ الحقل مطلوب باستخدام السمة required
.
ستتوفّر الفئة الزائفة :required
للحقول المطلوبة.
يمكن اختيار الحقول غير المطلوبة باستخدام الفئة الزائفة
:optional
.
اختيار العناصر حسب الفهرس والترتيب والتكرار
هناك مجموعة من الفئات الزائفة التي تختار العناصر استنادًا إلى موضعها في المستند.
:first-child
و:last-child
إذا أردت العثور على العنصر الأول أو الأخير، يمكنك استخدام :first-child
و:last-child
.
ستعرض فئات العناصر الزائفة هذه إما العنصر الأول أو الأخير في مجموعة من العناصر الشقيقة.
:only-child
يمكنك أيضًا اختيار العناصر التي لا تحتوي على عناصر شقيقة باستخدام الفئة الزائفة :only-child
.
:first-of-type
و:last-of-type
يمكنك اختيار
:first-of-type
و
:last-of-type
اللذين يبدوان في البداية
كأنهما يؤديان الوظيفة نفسها التي يؤديها :first-child
و:last-child
، ولكن ضع في اعتبارك رمز HTML التالي:
<div class="my-parent">
<p>A paragraph</p>
<div>A div</div>
<div>Another div</div>
</div>
وهذا هو تنسيق CSS:
.my-parent div:first-child {
color: red;
}
لن يتم تلوين أي عناصر باللون الأحمر لأنّ العنصر الفرعي الأول هو فقرة وليس div.
تكون الفئة الزائفة :first-of-type
مفيدة في هذا السياق.
.my-parent div:first-of-type {
color: red;
}
على الرغم من أنّ <div>
الأولى هي العنصر الثانوي الثاني، إلا أنّها تظل العنصر الأول من نوعه داخل العنصر .my-parent
، لذا سيتم تلوينها باللون الأحمر باستخدام هذه القاعدة.
:nth-child
و:nth-of-type
ولا يقتصر الأمر على العناصر الفرعية الأولى والأخيرة والأنواع.
تتيح لك الفئتان الزائفتان :nth-child
و:nth-of-type
تحديد عنصر يقع في فهرس معيّن.
يبدأ الفهرسة في أدوات اختيار لغة CSS من الرقم 1.
تحسب الفئتان الزائفتان :nth-last-child()
و:nth-last-of-type()
من النهاية بدلاً من البداية.
يمكنك أيضًا تمرير أكثر من فهرس واحد إلى هذه الفئات الزائفة.
إذا أردت اختيار جميع العناصر الزوجية، يمكنك استخدام :nth-child(even)
.
يمكنك أيضًا إنشاء أدوات اختيار أكثر تعقيدًا تعثر على العناصر على فواصل زمنية منتظمة باستخدام صيغة An+B المصغّرة.
li:nth-child(3n+3) {
background: yellow;
}
يختار هذا المحدد كل عنصر ثالث، بدءًا من العنصر 3.
إنّ n
في هذا التعبير هو الفهرس،
الذي يبدأ من صفر، أما 3 (3n
) فهو مقدار ضرب هذا الفهرس.
لنفترض أنّ لديك 7 سلع <li>
.
العنصر الأول الذي تم اختياره هو 3 لأنّ 3n+3
تتم ترجمته إلى (3 * 0) + 3
.
سيختار التكرار التالي العنصر 6 لأنّ n
قد زاد الآن إلى 1
،
وبالتالي (3 * 1) + 3)
.
يعمل هذا التعبير مع كلّ من :nth-child
و:nth-of-type
.
تتيح :nth-child()
و:nth-last-child()
أيضًا استخدام بنية "of S" التي تتيح لك فلترة النتائج المطابقة باستخدام أداة اختيار، على غرار :nth-of-type()
. li:nth-of-type(even)
تعادل :nth-child(even of li)
. في حين أنّ :nth-of-type
لا يتيح لك سوى الفلترة استنادًا إلى نوع العنصر (مثل li
أو p
)، يتيح لك تركيب "of S" الفلترة استنادًا إلى أي أداة اختيار.
إذا كان لديك جدول، قد تحتاج إلى إضافة خطوط إلى كل صف. على الرغم من أنّه يمكنك استهداف كل صف آخر باستخدامtr:nth-child(even)
، لن ينجح ذلك إذا كنت تستبعد بعض الصفوف من خلال الفلترة. إذا كنت تنفّذ الفلترة من خلال تطبيق السمة hidden
، يمكنك إضافة of :not([hidden])
إلى أداة الاختيار لفلترة العناصر المخفية مسبقًا قبل اختيار الصفوف الزوجية.
tr:nth-child(even of :not([hidden])){
background: lightgrey;
}
يمكنك تجربة هذا النوع من أدوات الاختيار على أداة اختبار nth-child أو أداة اختيار الكمية.
:only-of-type
أخيرًا، يمكنك العثور على العنصر الوحيد من نوع معيّن في مجموعة من العناصر الشقيقة باستخدام
:only-of-type
.
يكون ذلك مفيدًا إذا أردت اختيار قوائم تحتوي على عنصر واحد فقط،
أو إذا أردت العثور على العنصر الوحيد الذي يظهر بالخط العريض في فقرة.
العثور على عناصر فارغة
قد يكون من المفيد أحيانًا تحديد العناصر الفارغة تمامًا، وهناك فئة زائفة لذلك أيضًا.
:empty
إذا لم يكن للعنصر أي عناصر فرعية، ينطبق عليه الفئة الزائفة
:empty
.
مع ذلك، لا يقتصر الأطفال على عناصر HTML أو عقد النصوص، بل يمكن أن يكونوا أيضًا مساحة بيضاء،
وهو ما قد يكون مربكًا عند تصحيح أخطاء HTML التالية والتساؤل عن سبب عدم عملها مع :empty
:
<div>
</div>
والسبب هو وجود بعض المسافات البيضاء بين علامتي الفتح والإغلاق <div>
،
لذا لن يعمل :empty
.
يمكن أن تكون الفئة الزائفة :empty
مفيدة إذا كان لديك تحكّم محدود في HTML وأردت إخفاء العناصر الفارغة، مثل محرّر محتوى WYSIWYG.
في هذا المثال، أضاف أحد المحرّرين فقرة فارغة.
<article class="post">
<p>Donec ullamcorper nulla non metus auctor fringilla.</p>
<p></p>
<p>Curabitur blandit tempus porttitor.</p>
</article>
باستخدام :empty
، يمكنك العثور على هذه التعليقات وإخفائها.
.post :empty {
display: none;
}
العثور على عناصر متعدّدة واستبعادها
تساعدك بعض الفئات الزائفة في كتابة CSS أكثر إيجازًا.
:is()
إذا أردت العثور على جميع العناصر الثانوية h2
وli
وimg
في العنصر .post
،
قد تفكّر في كتابة قائمة محدّدات على النحو التالي:
.post h2,
.post li,
.post img {
…
}
باستخدام الفئة الزائفة :is()
،
يمكنك كتابة نسخة أكثر اختصارًا:
.post :is(h2, li, img) {
/* ... */
}
إنّ الفئة الزائفة :is
ليست أكثر إيجازًا من قائمة أدوات الاختيار فحسب، بل إنّها أيضًا أكثر تساهلاً.
في معظم الحالات، إذا حدث خطأ أو كان هناك محدّد غير متوافق في قائمة المحدّدات، لن تعمل قائمة المحدّدات بأكملها.
إذا حدث خطأ في المحدّدات التي تم تمريرها في فئة :is
الصورية، سيتجاهل المحدّد غير الصالح، ولكن سيستخدم المحدّدات الصالحة.
:not()
يمكنك أيضًا استبعاد العناصر باستخدام الفئة الزائفة :not()
.
على سبيل المثال، يمكنك استخدامها لتنسيق جميع الروابط التي لا تتضمّن السمة class
.
a:not([class]) {
color: blue;
}
يمكن أن تساعدك :not
الفئة الزائفة أيضًا في تحسين إمكانية الوصول.
على سبيل المثال، يجب أن يتضمّن <img>
alt
، حتى لو كانت قيمة فارغة،
وبالتالي يمكنك كتابة قاعدة CSS تضيف مخططًا تفصيليًا أحمر سميكًا إلى الصور غير الصالحة:
img:not([alt]) {
outline: 10px red;
}
:has()
ماذا لو أردت تنسيق العناصر استنادًا إلى ما تحتويه؟ يمكنك استخدام الفئة الزائفة :has()
لإجراء ذلك. على سبيل المثال، قد تحتاج إلى تطبيق أنماط على الأزرار التي تتضمّن رموزًا.
button:has(svg) {
/* ... */
}
في أبسط إعداداته، كما في المثال السابق، يمكنك اعتبار :has()
أداة اختيار رئيسية. يمكنك أيضًا استخدام أداة اختيار العنصر الرئيسي المطابق مع أدوات اختيار أخرى لاستهداف عناصر أخرى.
form:has(input:valid) label {
font-weight: bold;
}
form:has(input:valid) label::after {
content: "✅";
}
في هذا المثال، نطبّق أنماطًا على عنصر التصنيف والعنصر الزائف label::after
عندما يحتوي إدخال النموذج على الفئة الزائفة valid
.
لا يمكن تضمين الفئة الزائفة :has()
داخل فئة :has()
أخرى، ولكن يمكن دمجها مع فئات زائفة أخرى.
:is(h1, h2, h3):has(a) {
/* ... */
}
قائمة أدوات الاختيار لا تتسامح مع الأخطاء، لذا إذا كانت أي أداة اختيار في القائمة غير صالحة، سيتم تجاهل جميع قواعد الأنماط.
.my-element:has(img, ::before) {
/* any styles here will be discarded since pseudo elements can't be included in the :has() selector list */
}
التحقّق من فهمك
اختبِر معلوماتك حول الفئات الزائفة
تعمل الفئات الزائفة كما لو تم تطبيق فئة ديناميكيًا على عنصر ما، بينما تعمل العناصر الزائفة على العنصر نفسه.
أي مما يلي يمثّل فئة زائفة وظيفية؟
:not()
:is()
:target
:empty
أيّ من الفئات الزائفة التالية ناتجة عن تفاعل المستخدم؟
:press
:squeeze
:hover
:target
:focus-within
أيّ مما يلي يندرج ضمن <form>
فئات الحالة الزائفة؟
:fresh
:indeterminate
:valid
:loading
:checked
:enabled
:in-range