الـ CSS Selectors أو “مُحددات CSS” هي الطريقة اللي بنستخدمها عشان نختار عنصر معين من عناصر الـ HTML ونطبّق عليه التنسيق اللي إحنا عايزينه.
ولو ماعرفتش تختار العنصر الصح، يا إما التنسيق مش هيتطبق خالص… يا إمّا هيتطبق على عنصر تاني أنت أصلًا مش قاصده. وده أكبر سبب بيخلّي ناس كتير تقول:
“الكود مظبوط… بس الـ CSS مش شغال!”
علشان كده معرفة الـ Selectors بشكل صحيح هي الأساس قبل ما تبدأ أي تنسيق.
لكن قبل ما نقول للـ CSS:
“طبّق التنسيق ده على العنصر ده”
لازم نفهم الأول: إزاي المتصفح بيشوف كود الـ HTML؟
وإزاي بيحوّله من نص مكتوب لشكل هيكلي منظم اسمه شجرة الـ DOM؟
ما هي شجرة الـ DOM؟#
تعالى نروح “ورا الكواليس” ونشوف اللي بيحصل أول ما تفتح أي صفحة ويب.
المتصفح بيبدأ يقرأ ملف الـ HTML سطر ورا التاني من فوق لتحت.
كل وسم بيعدّي عليه، بيحوّله لعنصر حقيقي ويضيفه جوه حاجة اسمها:
Document Object Model – DOM
تقدر تتخيل الـ DOM كأنها خريطة منظمة لكل العناصر اللي في صفحتك:
مين الأب؟
مين الأبناء؟
مين جوه مين؟
وترتيب العناصر عامل إزاي؟
على سبيل المثال:
- أول عنصر في أي صفحة هو
<html>… وده الجذر (Root). - جواه هنلاقي الابن الأول
<head>… وده الجزء اللي المستخدم ما بيشوفهوش. - وبعدين
<body>… وده اللي بيظهر فعليًا للزائر. - جوه الـ body ممكن تلاقي
<div>، وجواه<p>، وهكذا…
المتصفح بياخد الهيكل ده ويبنيه في شكل Nodes (عُقد) متوصّلة ببعض زي شجرة.
وبمجرد ما الشجرة دي تتكوّن… يبدأ دور الـ CSS.
الـ CSS يبدأ يدور جوا الشجرة:
مين العناصر اللي المفروض أطبّق عليها التنسيق؟
هل أختارهم باسم الوسم؟
ولا بالـ class؟
ولا بالـ id؟
ولا بأي Selector تاني؟
خلاصة الكلام
الـ DOM هي النسخة اللي المتصفح بيفهمها من صفحة الـ HTML،
ومن خلالها الـ CSS يقدر يوصل لأي عنصر ويتحكم فيه زي ما يحب.
الـ CSS Selectors – إزاي نختار العناصر؟#
وصلنا بقى للجزء اللي فعليًا بيخليك تتحكّم في شكل الصفحة:
إزاي تختار عناصر الـ HTML باستخدام الـ Selectors؟
الـ Selector ببساطة هو “الجملة” اللي بنوجه بيها CSS ونقول له:
طبّق التنسيق ده… على العنصر ده تحديدًا.
وهنشوف دلوقتي كل نوع بمثال عملي علشان الصورة تبقى واضحة ومفهومة.
1. اختيار العنصر باسم الوسم – Element Selector#
أول وأبسط طريقة هي إنك تختار العنصر باسمه،
زي: p, h1, div … إلخ.
لو عندك في الـ HTML:
<p>HTML is a HyperText Markup Language</p>
<p>CSS is a Cascanding Style Sheet</p>
وكتبت في الـ CSS:
p {
color: blue;
}
كده إنت بتقول للمتصفح:
“أي عنصر
<p>في الصفحة… خليه لونه أزرق.”
وبالتالي كل الفقرات في الصفحة هيتطبق عليها نفس التنسيق.
والطريقة دي ممتازة لو عايز تغيّر جميع العناصر من نفس النوع مرة واحدة.
2. اختيار العنصر بالـ Class – Class Selector#
وده واحد من أهم وأكتر الـ Selectors استخدامًا.
نضيف كلاس للعنصر في الـ HTML، وبعدها نمسكه في الـ CSS
بعلامة النقطة . .
مثال:
في الـ HTML:
<p class="note">ده باراجراف عليه كلاس note.</p>
<p>وده باراجراف تاني عادي.</p>
وفي الـ CSS:
.note {
color: green;
}
هنا التنسيق اتطبّق بس على العنصر اللي عليه كلاس note.
وده اللي بيميز الـ class… إنك تقدر:
- تجمع عناصر مختلفة في CSS تحت نفس التنسيق
- وتستخدم نفس الكلاس أكتر من مرة
- وتتحكم في أجزاء معينة من الصفحة من غير ما تأثر على الباقي
اختيار اسم الكلاس… مهم جدًا!
في قواعد بسيطة لازم تلتزم بيها:
- استخدم اسم واضح ليه معنى
- تجنّب الأسماء العامة زي (red – big – x)
- لو الاسم مكوّن من كلمتين أو أكتر… استخدم kebab-case
زي كده:
<button class="btn btn-primary"></button>
أمثلة صحيحة:
<div class="card"></div>
<button class="btn btn-primary"></button>
<ul class="nav-list"></ul>
أمثلة خاطئة (وليه غلط؟):
<div class="red"></div> <!-- اسم معتمد على اللون، مش وظيفي -->
<div class="big-div"></div> <!-- وصف شكلي، مش معنى وظيفي -->
<div class="x"></div> <!-- اسم غير مفهوم -->
3. اختيار العنصر بالمعرّف – ID Selector#
الـ ID شبه الـ class…
بس الفرق الكبير إنه مخصص لعنصر واحد فقط في الصفحة.
وبنستهدفه في CSS باستخدام علامة الـ #.
مثال للتوضيح:
في الـ HTML:
<h1 id="main-title">العنوان الرئيسي</h1>
وفي الـ CSS:
#main-title {
color: red;
}
ده ممتاز جدًا للعناصر المميزة اللي مفيش منها غير نسخة واحدة، زي:
الهيدر – اللوجو – السلايدر – الفوتر… إلخ.
⚠️ ملاحظة مهمة جدًا
الـ ID لا يجوز يتكرر في نفس الصفحة.
يعني الكود ده غلط:
<h1 id="main-title">العنوان الرئيسي</h1>
<h2 id="main-title">العنوان الفرعي</h2>
ده بيعمل مشاكل في:
- الـ CSS
- والـ JavaScript
- والـ SEO كمان
لأن المتصفح بيعتبر إن الـ ID لازم يكون Unique.
قواعد كتابة الـ ID بشكل صحيح
زي ما للـ class قواعده… كمان للـ ID قواعد لازم تتبعها:
- لازم يبدأ بحرف، مش رقم
- يفضّل استخدام kebab-case أو camelCase
- يكون قصير ومعبّر عن وظيفته
- والأهم: مينفعش يتكرر
أمثلة صحيحة لاستخدام الـ ID
<div id="main-header"></div>
<input id="userEmail">
<section id="heroSection"></section>
أمثلة خاطئة
<div id="1header"></div> <!-- يبدأ برقم -->
<div id="header header2"></div> <!-- يحتوي مسافة -->
<div id="test"></div>
<div id="test"></div> <!-- تكرار ID ممنوع -->
طب أستخدم Class ولا ID؟
ده سؤال مهم، وخد القاعدة الذهبية:
- لو للـ CSS → استخدم class
- لو للـ JavaScript أو عنصر واحد فريد → استخدم id
الـ class مرن… يتكرر كتير… ومناسب للتنسيق.
أما الـ id فبيستخدم غالبًا للاستهداف في JavaScript أو للربط الداخلي داخل الصفحة.
4. الاختيار حسب علاقة العناصر ببعض – Relationship Selectors#
في بعض الأحيان، مش كل العناصر ليها class أو ID، أو ممكن يكون صعب تحطهم.
في الحالة دي، نقدر نختار العناصر اعتمادًا على علاقتها بعناصر تانية في الصفحة.
ده اللي بنسميه Relationship Selectors، وهي بتساعدنا نتحكم في عناصر معينة بسهولة وسرعة.
4.1 عنصر جوه عنصر – Descendant Selector#
في الحالة دي، بنختار أي عنصر جوه عنصر آخر، حتى لو مش ابن مباشر.
HTML:
<div>
<p>ده جوا الديف.</p> <!-- هيتطبق عليه التنسيق -->
</div>
<p>ده برا الديف.</p>
CSS:
div p {
color: purple;
}
النتيجة: اللون هيتغيّر بس للباراجراف اللي جوه الـ div.
لو عندنا عناصر متداخلة:
<div>
<p>ده جوا الديف.</p>
<main>
<p>ابن غير مباشر للديف</p> <!-- هيطبق عليه التنسيق -->
</main>
</div>
<p>ده برا الديف.</p>
حتى الباراجراف داخل الـ <main> هيتطبّق عليه اللون لأنه ابن غير مباشر.
الطريقة دي لا تفرق بين الابن المباشر والحفيد.
4.2 ابن مباشر للعنصر – Child Selector#
في الطريقة دي، بنستهدف الأبناء المباشرين فقط، مش الأحفاد.
HTML:
<div>
<p>ده ابن مباشر.</p>
<span>
<p>ده حفيد.</p>
</span>
</div>
CSS:
div > p {
color: orange;
}
النتيجة: لون أول باراجراف بس هيتغير، أما الحفيد فلونه مش هيتغير.
4.3 الأخ اللي بعده مباشرة – Adjacent Sibling Selector#
بنختار العنصر اللي بيجي بعد عنصر تاني مباشرة.
HTML:
<h2>عنوان</h2>
<p>ده أول باراجراف بعد الـ h2.</p>
<p>ده باراجراف تاني.</p>
CSS:
h2 + p {
color: red;
}
النتيجة: هيتأثر أول باراجراف بعد الـ h2 فقط.
دي طريقة ممتازة لتنسيق عناصر متجاورة زي تفاصيل المنتجات، العناوين، أو أي محتوى متسلسل.
4.4 أي أخ بعده – General Sibling Selector#
بنختار أي عنصر في نفس المستوى وبيجي بعد عنصر محدد، مش شرط يكون مباشرة.
HTML:
<h2>عنوان</h2>
<p>باراجراف 1</p>
<p>باراجراف 2</p>
CSS:
h2 ~ p {
color: teal;
}
النتيجة: كل الفقرات اللي بعد <h2> هيتغيّر لونها، مش بس الأول.
وخلاصة اللي فات
دلوقتي بقيت قادر تختار أي عنصر في الصفحة:
- بالاسم (Element Selector)
- بالكلاس (Class Selector)
- بالـ ID
- أو حسب علاقته بعناصر تانية (Relationship Selectors)
وده أساس مهم جدًا، لأن أي تنسيق هتطبقه بعد كده بيعتمد على اختيارك الصحيح للعنصر.
5. اختيار العنصر بالخواص – Attribute Selectors#
في الطريقة دي، بدل ما نختار العنصر بالاسم أو الكلاس أو الـ ID، بنختاره بناءً على الخصائص (Attributes) اللي موجودة فيه.
وده مفيد جدًا خصوصًا مع عناصر زي الـ <input>, <a>، أو أي عنصر فيه سمات مختلفة.
مثال أساسي:
كود الـ CSS:
input[type="text"] {
border-color: blue;
}
input[type="email"] {
border-color: green;
}
input[required] {
background-color: yellow;
}
[required] {
outline: 2px solid orange;
}
هنا بنستهدف العناصر حسب نوعها أو حسب وجود خاصية معينة.
طرق متقدمة لتحديد العناصر بالخواص
مش بس نقدر نستهدف العنصر إذا كانت الخاصية بقيمة محددة، لكن كمان نقدر نستخدم عمليات مطابقة جزئية.
5.1️ احتواء خاصية العنصر على نص معين – *=#
input[type*="mail"] {
border-color: green;
}
كود الـ HTML:
<input type="email" />
النتيجة: تنسيق الـ CSS هيطبق على أي عنصر نوعه يحتوي على كلمة mail، مش شرط يكون كاملًا email.
علامة النجمة * بتدل على احتواء النص داخل الخاصية.
5.2️ بداية الخاصية بنص معين – ^=#
input[type^="ema"] {
border-color: green;
}
ده بيستهدف أي عنصر تكون الخاصية بتاعته بتبدأ بالنص اللي كتبته، هنا أي type يبدأ بـ ema.
5.3️ نهاية الخاصية بنص معين – $=#
input[type$="ail"] {
background-color: red;
}
ده بيطبق التنسيق على أي عنصر تنتهي الخاصية عنده بالنص اللي حددناه، هنا أي type ينتهي بـ ail، زي email.
خلاصة سريعة لـ Attribute Selectors
[attr]→ العنصر اللي فيه الخاصية موجودة فقط[attr="value"]→ العنصر اللي خاصيته = قيمة معينة[attr*="text"]→ العنصر اللي خاصيته تحتوي على نص معين[attr^="text"]→ العنصر اللي خاصيته تبدأ بنص معين[attr$="text"]→ العنصر اللي خاصيته تنتهي بنص معين
6. اختيارات الطفل حسب الترتيب - Child-based Selectors#
الـ Child-based Selectors بتختار العناصر بناءً على ترتيبها داخل الأب بدون ما تهتم بنوع العنصر نفسه.
يعني مش مهم العنصر ده div ولا p ولا li… المهم ترتيبه بين إخوته.
6.1 المحدد :nth-child()#
يختار العنصر رقم X بين كل إخوته.
الصيغة:
element:nth-child(n)
أمثلة:
مثال 1: اختيار العنصر الثاني داخل الأب
div p:nth-child(2) {
color: red;
}
واللي بيحصل هنا:
- بنختار ثاني طفل داخل الـ div.
- لو الثاني ده مش P → مش هيتلون، لأن الـ selector محتاج “تطابق نوع + تطابق ترتيب”.
مثال 2: اختيار كل طفل زوجي
li:nth-child(even) {
background: #f0f0f0;
}
وهنا اللي بيحصل:
- بيطبق التنسيق على العناصر الزوجية: 2، 4، 6، 8.
- ولو استخدمت
oddo. هيطبق علي العناصر الفردية.
مثال 3: اختيار الأطفال باستخدام معادلة
li:nth-child(3n + 1) {
color: blue;
}
واللي بيحصل هنا:
- دي معادلة بتختار العناصر:
1، 4، 7، 10، … - الـ 3n معناها كل 3 عناصر، و +1 يعني يبدأ من الأول.
6.2 المحدد :nth-last-child()#
نفس فكرة nth-child() لكن العدّ بيبدأ من الآخر.
مثال:
p:nth-last-child(1) {
font-weight: bold;
}
واللي بيحصل هنا:
1من الآخر → يعني آخر عنصر وسط إخوته.- لو العنصر الأخير فعلاً P → هيتطبق عليه.
6.3 المحدد :first-child#
يختار أول طفل داخل الأب.
مثال:
div p:first-child {
color: green;
}
واللي بيحصل هنا:
- لو أول عنصر داخل الـ div هو P → يبقى هيتم تطبيق اللون الأخضر.
- لو أول واحد كان عنصر تاني (مثلاً span) → مش هيشتغل.
6.4 المحدد :last-child#
يختار آخر طفل داخل الأب.
مثال:
ul li:last-child {
margin-bottom: 0;
}
واللي بيحصل هنا:
- ينفّذ التنسيق على آخر
<li>داخل الـ<ul>. - مفيد جدًا لإزالة المسافات بين العناصر الأخيرة.
6.5️ المحدد :only-child#
يتطبق على العنصر لو كان الطفل الوحيد داخل الأب.
مثال:
div p:only-child {
font-size: 20px;
color: purple;
}
وهنا اللي بيحصل:
- يُطبق فقط لو داخل الـ div مفيش غير عنصر واحد بس، وهو كمان P.
- لو فيه P و span → مش هيشتغل، لأن العنصر مش وحيد.
ملخص سريع:
| الـ Selector | الوظيفة |
|---|---|
nth-child() | تحديد عنصر حسب ترتيبه من البداية |
nth-last-child() | تحديد عنصر حسب ترتيبه من النهاية |
first-child | أول طفل داخل الأب |
last-child | آخر طفل |
only-child | الطفل الوحيد |
7. محددات الـ Type-based Selectors#
الـ Type-based Selectors بتشتغل بناءً على ترتيب العنصر بين إخوته من نفس النوع فقط.
يعني هنا نوع العنصر مهم جدًا — عكس Child-based Selectors اللي كان يهمها الترتيب فقط.
7.1️ المحدد :nth-of-type()#
يختار العنصر رقم X من نوعه داخل نفس الأب.
الصيغة:
element:nth-of-type(n)
مثال 1: اختيار ثاني <p> داخل عناصر الأب
div p:nth-of-type(2) {
color: red;
}
واللي بيحصل هنا:
- مش مهم ترتيب
<p>وسط كل العناصر. - المهم يكون ثاني عنصر من نوع p فقط داخل الـ div.
- حتى لو قبله 3 عناصر div أو span، مش فارق.
مثال 2: اختيار كل <li> زوجي
li:nth-of-type(even) {
background: #f0f0f0;
}
وهنا اللي بيحصل:
- يعدّ فقط عناصر li، ويطبق التنسيق على 2، 4، 6، … من نفس النوع.
مثال 3: استخدام معادلة
p:nth-of-type(3n + 1) {
font-weight: bold;
}
واللي بيحصل هنا:
- يختار
<p>رقم: 1، 4، 7، 10. - المعادلة تحسب للنوع P فقط.
7.2️ المحدد :nth-last-of-type()#
نفس فكرة nth-of-type() لكن العدّ يبدأ من النهاية.
مثال:
p:nth-last-of-type(1) {
color: blue;
}
واللي بيحصل هنا:
- يحدد آخر عنصر p في الأب.
- حتى لو فيه عناصر تانية مختلفة حوالين الـ p، مش مؤثرة.
7.3️ المحدد :first-of-type#
يختار أول عنصر من نوعه داخل الأب.
مثال:
section h2:first-of-type {
margin-top: 0;
}
الشرح:
- يختار أول
<h2>يظهر داخل الـ section. - لو أول عنصر داخل الـ section كان
<h3>، مش مهمة. - المهم أول h2 فقط.
7.4️ المحدد :last-of-type#
يختار آخر عنصر من نوعه داخل الأب.
مثال:
article p:last-of-type {
color: green;
}
الشرح:
- يختار آخر فقرة p في العنصر article.
- بغض النظر عن وجود عناصر أخرى بعده.
7.5️ المحدد :only-of-type#
يتطبق لو كان العنصر هو الوحيد من نفس نوعه داخل الأب.
مثال:
div span:only-of-type {
font-size: 20px;
color: purple;
}
واللي بيحصل هنا:
- يشتغل فقط لو داخل الـ div يوجد span واحد فقط.
- لو فيه span + p هيشتغل لأن span الوحيد من نوعه.
- لو فيه span + span مش هيشتغل.
الفرق بين Child-based و Type-based بسرعة:#
| الـ Selector Group | بيهتم بإيه؟ |
|---|---|
| Child-based | ترتيب العنصر بين كل إخوته (بغض النظر عن النوع) |
| Type-based | ترتيب العنصر بين إخوته من نفس النوع فقط |
8. محدد الـ Universal selector#
الـ Universal selector هو أبسط Selector في CSS: *
يعني حرف النجمة بيمثّل كل العناصر داخل المستند أو داخل نطاق محدد.
لو كتبت:
* {
box-sizing: border-box;
}
فده معناه: طبّق box-sizing: border-box على كل عنصر في الصفحة.
أمثلة بسيطة وشرحها#
1. تطبيق على كل العناصر#
* {
margin: 0;
padding: 0;
}
الشرح:
بيشيل المسافات الافتراضية لكل العناصر — طريقة شائعة لعمل CSS reset بسيط.
2. ضمن نطاق محدد (قصر التأثير)#
.main * {
color: #333;
}
وهنا اللي بيحصل:
مش كل العناصر في الصفحة، لكن كل العناصر جوا العنصر اللي كلاس .main فقط. مفيد لو عايز تسيطر على منطقة من الصفحة من غير ما تأثر على الباقي.
3. مع Children/Type لتحديد أدق#
.container > * {
margin-bottom: 10px;
}
واللي بيحصل هنا:
يستهدف كل الأطفال المباشرين للـ .container ويضيف بينهم فراغ. مفيد بدل ما تكتب قائمة طويلة بالعناصر.
استخدامات متقدمة ومزايا#
الـ Reset / Normalize خفيف: تستخدمه لعمل قواعد عامة مثل
box-sizing,marginوpaddingعلى مستوى المشروع.تطبيق قواعد عامة على نطاق محدد: زي
.card * { color: inherit; }للتأكد إن داخل الـ card الألوان موروثة.تنسيق الأطفال بدون معرفة نوعهم: لما يكون الأب بيحتوي على عناصر من أنواع مختلفة وعايز تعاملهم بنفس الطريقة (مثلاً مساحة فراغ موحدة بين كل عناصر القائمة).
الجمع بين الـ Universal Selector وSelectors تانية#
1. مع Class أو ID (للقصر)#
#sidebar * {
font-size: 14px;
}
وهنا: هيقتصر التأثير على كل العناصر داخل #sidebar فقط.
2. مع Attribute#
form[data-form="signup"] * {
line-height: 1.6;
}
وهنا: بنضمن تنسيق متناسق داخل فورم محدد.
3. مع Pseudo-classes وChild selectors#
ul li:first-child > * {
color: blue;
}
أما هنا: أي عنصر داخل أول li في ul هيكون لونه أزرق.
تأثير الـ Universal Selector على Specificity (الأسبقيّة)#
- الـ
*له قيمة specificity = 0 تقريبًا (زيه زي القواعد العامة). - لما تدمجه مع class أو id، الأسبقيّة تحسب حسب باقي المكوّنات (
.main *يرث أسبقيّة.mainفقط). - يعني القاعدة العامة: قواعد مخصصة (مثل
#id .class p) ستغلب قواعد عامة (*,element) لو اتعارضوا.
أداء Rendering (Performance) وملاحظات مهمة#
- استخدام
*عالمياً على الصفحة كاملة بكثرة وبطرق معقّدة ممكن يؤثر سلبًا على الأداء لأن المتصفح يحتاج يفحص كل عنصر ليتحقق من التطابق. - القاعدة العملية: قصر نطاق الـ universal (مثلاً
.component *) أفضل من استخدامه على مستوى الوثيقة كلها باستمرار. - تجنّب استعمال قواعد عامة ثقيلة مع combinators أو pseudo-classes المعقّدة لأن ده يزيد الحسابات على DOM خصوصًا في صفحات كبيرة.
تحذيرات ومشكلات شائعة#
*لا يطابق بعض الأشياء الافتراضية مثل الـ pseudo-elements (::before,::after) إلا إذا تحددها صراحة.- لو حطيت قواعد عامة قوية بـ
*بعدين حطيت قواعد متخصصة، ممكن تحتاج تستخدم!importantأو قواعد أسبقية أعلى — وده سيبقى مشكلة تصميمية. الأفضل تنظيم القواعد لتفادي!important. - استخدام
*مع خواص ثقيلة (مثلtransform,filter) على كل العناصر ممكن يسبب مشاكل أداء.
نصائح عملية وBest Practices#
استخدم
*للـ resets العامة البسيطة مثل:*, *::before, *::after { box-sizing: border-box; }دي قاعدة مشهورة ومعتمدة.
قصر نطاق التأثير كلما تقدر:
.article * { color: inherit; }أفضل من
* { color: inherit; }.لو هتستخدم
*لإنشاء مسافات بين كل الأطفال استعمل child combinator لتقليل الحسابات:.list > * + * { margin-top: 8px; }(هنا بنستخدم الـ universal ومع adjacent sibling لعمل فاصل بين العناصر بأقل تكلفة).
راقب الأسبقية: قواعد عامة أولًا، ثم أكثر تحديدًا بعدين — نظم ملف الـ CSS من العام إلى الخاص.
أمثلة عملية كاملة (HTML + CSS) — كلّها في بلوك واحد للتجريب#
<!-- HTML -->
<div class="card">
<h2>Title</h2>
<p>Paragraph one.</p>
<img src="#" alt="img">
<button>Click</button>
</div>
/* CSS */
/* reset box model للصفحة */
*, *::before, *::after {
box-sizing: border-box;
}
/* قواعد عامة للـ card فقط */
.card * {
font-family: "Arial", sans-serif;
color: #222;
}
/* فواصل موحدة بين الأطفال المباشرين */
.card > * + * {
margin-top: 12px;
}
/* استهداف عناصر داخل الـ card بدون معرفة نوعها */
.card img {
max-width: 100%;
display: block;
}
وهنا اللي بيحصل:
- أول قاعدة بتخلي الحسابات البُعدية أسهل (box-sizing).
- تاني قاعدة بتطبّق خط ولون على كل العناصر داخل
.cardفقط — مش على الصفحة كلها. - ثالث قاعدة بتضيف مسافات منتظمة بين كل أطفال الـ
.cardمن غير ما نكتب أسماء الأنواع.
9. محددات الـ User-action Pseudo Classes#
المحددات دي بتشتغل وقت تفاعل المستخدم مع العناصر… يعني التنسيق بيظهر بمجرد حدوث أكشن من المستخدم زي المرور بالماوس، الضغط، أو التركيز على عنصر فورم.
ودي من أهم الأساسيات اللي بتدي موقعك إحساس بالحياة والتفاعل (Interactivity).
هنشرح كل واحدة منهم مع أمثلة بنفس الأسلوب اللي مشينا عليه قبل كده. عشان نفهم إزاي نستخدم كل محدد.
9.1 محدد الـ :hover#
بتشتغل لما المستخدم يمرّر الماوس فوق عنصر بدون ما يضغط عليه.
مثال:
<button class="btn">اضغط هنا</button>
.btn {
background-color: #eee;
padding: 10px 20px;
border: 1px solid #ccc;
}
.btn:hover {
background-color: #333;
color: #fff;
cursor: pointer;
}
واللي بيحصل هنا:
أول ما الماوس يعدّي فوق الزرار، لونه بيتقلب من رمادي لفاتح إلى غامق، والنص بيبقى أبيض، ده تأثير بصري مهم بيقول للمستخدم العنصر قابل للضغط.
9.2 محدد الـ :focus#
بتشتغل لما عنصر، زي input أو textarea، يبقى محدد (Focus) سواء بالموس أو من خلال لوحة المفاتيح.
مثال:
<input type="text" placeholder="اكتب اسمك">
input {
border: 1px solid #aaa;
padding: 8px;
}
input:focus {
border-color: dodgerblue;
outline: none;
box-shadow: 0 0 5px rgba(30, 144, 255, 0.4);
}
وهنا اللي بيحصل:
لما المستخدم يضغط على خانة الكتابة، الإطار بيتحول لأزرق وبيظهر شادو خفيف، ده بيدي إحساس إن العنصر جاهز للكتابة.
9.3 محدد الـ :active#
بيشتغل لحظة الضغط على العنصر، سواء كان زرار أو لينك.
مثال:
<a href="#" class="link">اضغط على اللينك</a>
.link {
color: teal;
text-decoration: none;
}
.link:active {
color: red;
}
وهنا اللي بيحصل:
أول ما تضغط على اللينك (لحظيًا)، لونه بيتحول للأحمر، بيدّي Feedback سريع للمستخدم إنه ضغط بالفعل.
9.4 محدد الـ :visited#
بتشتغل على الروابط (links) اللي المستخدم زارها قبل كده.
مثال:
<a href="https://example.com" class="nav-link">صفحة خارجية</a>
.nav-link:visited {
color: purple;
}
وهنا اللي بيحصل: لو المستخدم دخل اللينك ده قبل كده، هيظهر باللون البنفسجي، دي طريقة تساعده يعرف هو راح فين قبل كده، خصوصًا في المدونات أو القوائم الطويلة.
بس خد بالك:
لأسباب أمنية، CSS بتسمحلك بس تغيّر لون الخط تقريبًا… مش أي خصائص عشوائية، علشان ما تستخدمش الكشف عن تاريخ زيارة المستخدم لمواقع تانية.
مثال عملي شامل — كل pseudo-classes مع بعض#
<button class="cta">اشترك الآن</button>
.cta {
padding: 12px 25px;
font-size: 18px;
background: #ddd;
border: 1px solid #aaa;
transition: 0.2s;
}
.cta:hover {
background: #333;
color: #fff;
}
.cta:active {
transform: scale(0.97);
}
.cta:focus {
outline: 2px solid dodgerblue;
}
إيه اللي بيحصل هنا؟
- الـ Hover: اللون يتغير عند المرور بالماوس.
- الـ Active: الزرار يهبط سنة صغيرة عند الضغط (حركة لطيفة).
- الـ Focus: الإطار الأزرق يظهر لو وصلت للزرار بالكيبورد (Tab).
وده بيخلّي الزرار شكله أكثر احترافية وبيدي تجربة استخدام ممتازة.
ملاحظات وتطبيقات متقدمة#
1. الجمع بين أكثر من واحد#
button:hover:active {
background: firebrick;
}
معناه: لما تكون واقف على الزرار وضغطت كمان، اديني لون خاص.
2. مع Selectors تانية#
.form-group input:focus {
border-color: #0d6efd;
}
3. عمل Animations مع :hover#
.card:hover {
transform: translateY(-5px);
}
4. منع الـ hover على التليفونات#
الموبايلات ماعندهاش hover
بس المتصفحات ساعات بتفتكره “tap”
علشان كده يفضل تحط تأثيرات خفيفة.
10. المحددات State / Selecting Pseudo Classes#
المحددات دي بتشتغل على حالة العنصر (State)، وبتُستخدم غالبًا مع عناصر الـ Form زي:input, textarea, select, checkbox, radio.
وهي جزء أساسي جدًا في بناء نماذج احترافية، لأنها بتخليك تغيّر شكل العنصر بحسب حالته الحالية، سواء كان صالح، أو فيه خطأ، أو متعلم عليه، أو مقفول.
هنشرح كل واحدة بمثال واقعي وكمان الشرح هيكون خطوة بخطوة عشان نفهم.
10.1 محدد الـ :checked#
بتشتغل على العناصر اللي ممكن تتعلّم عليها (checked)، زي:
- Checkbox
- Radio button
<option>جوا<select>
مثال عملي:
<label>
<input type="checkbox" id="agree" />
أوافق على الشروط
</label>
input:checked + label,
input:checked {
accent-color: green;
}
وهنا اللي بيحصل:
- أول ما المستخدم يعلّم على الـ checkbox، العنصر يدخل في حالة
checked. - ممكن تغيّر اللون باستخدام
accent-colorأو تغيّر شكل اللابل اللي بعده.
مثلاً:
- قبل الضغط، مربع فاضي
- بعد الضغط، لونه بيتحول لأخضر
10.2 محدد الـ :disabled#
بتشتغل لما العنصر يكون مقفول وغير قابل للتفاعل.
مثال:
<input type="text" placeholder="مش متاح" disabled>
input:disabled {
background-color: #eee;
color: #999;
cursor: not-allowed;
}
وهنا اللي بيحصل:
- العنصر مش قابل للضغط أو الكتابة.
- المستخدم يشوف لون باهت يوضح إنه غير فعّال.
- الـ cursor بيتحوّل لشكل ممنوع (🚫).
مهمة جدًا في UI لما يكون في مراحل لازم تتعمل قبل خطوة معينة.
10.3 محدد الـ :valid#
بتشتغل لو قيمة الـ input صحيحة طبقًا لنوعه أو القيود عليه.
مثال:
<input type="email" placeholder="ادخل بريدك">
input:valid {
border-color: green;
}
واللي بيحصل هنا:
بمجرد المستخدم يكتب بريد إلكتروني صحيح (يحتوي
@و.)
البوردر سوف يتحول للون الأخضر.لو كتب أي كلام غلط، تنسيق الـ CSS ده مش هيتطبق.
مهم جدًا في الـ real-time validation.
10.4 محدد الـ :invalid#
عكس :valid تمامًا، بتشتغل لما قيمة العنصر غير صحيحة.
مثال:
<input type="email" placeholder="ادخل بريدك" required>
input:invalid {
border-color: red;
}
وهنا اللي بيحصل:
- من أول ما المستخدم يبتدي يكتب حاجة غلط بيظهر له الإطار الأحمر.
- لو الإدخال فاضي والسطر فيه
requiredبرضه يعتبر invalid.
مثال عملي شامل - Form احترافي#
<form>
<label>Email</label>
<input type="email" required>
<label>
<input type="checkbox" id="terms">
أوافق على الشروط
</label>
<button disabled id="submit-btn">تسجيل</button>
</form>
/* Valid / Invalid */
input:valid {
border: 2px solid green;
}
input:invalid {
border: 2px solid red;
}
/* Checkbox checked */
input[type="checkbox"]:checked + span,
input[type="checkbox"]:checked {
accent-color: green;
}
/* Disabled Button */
button:disabled {
background: #ccc;
cursor: not-allowed;
}
اللي بيحصل هنا:
الـ email
- أخضر لو صحيح
- أحمر لو خطأ
الـ checkbox
- لونه يتغير لما المستخدم يوافق
الزرار
مقفول
disabledمستني المستخدم يعمل الخطوتين:
- يكتب Email صحيح
- يعلم على checkbox
وكل ده من غير ولا سطر JavaScript.
11. محددات الـ UI Pseudo Classes - حالات واجهة الاستخدام المتقدمة#
المحددات دي بتستخدمها لما تحب تتحكم في العنصر نفسه أو العناصر اللي جواه بناءً على الحالة اللي بتحصل أثناء الاستخدام.
ودي مهمة جدًا لبناء نماذج متفاعلة (Interactive Forms) من غير ولا سطر JavaScript.
هنشرح أهمهم:
:focus-within:focus-visible:enabled:required:optional
مع أمثلة واقعية زي اللي اشتغلنا عليها قبل كده.
11.1 محدد الـ :focus-within#
بيشتغل على العنصر الأب طالما أي عنصر جواه حصل له focus.
وده مهم جدًا في تصميم الـ Form لما تكون عايز تغيّر شكل الـ div كله بمجرد ما المستخدم يدخل يكتب في أي Input داخله.
مثال:
<div class="form-group">
<label>البريد الإلكتروني</label>
<input type="email" required>
</div>
.form-group {
padding: 10px;
border: 1px solid #ccc;
}
.form-group:focus-within {
border-color: dodgerblue;
background-color: #f0f8ff;
}
واللي بيحصل هنا:
- أول ما المستخدم يضغط على الـ input، العنصر الأب
.form-groupكله بياخد حالة focus. - فيتغير لون الإطار ويتغير لون الخلفية.
- يحسّس المستخدم إنه داخل “منطقة كتابة”.
ده بالظبط اللي بتشوفه في Google Forms وStripe Checkout.
11.2 محدد الـ :focus-visible#
بيشتغل بس لما المستخدم يدخل على العنصر من الكيبورد (تاب)، مش من الماوس.
وده مهم جدًا للـ Accessibility — ذوي الاحتياجات الخاصة اللي بيتعاملوا بالكيبورد.
مثال:
<button class="btn">احجز الآن</button>
.btn:focus-visible {
outline: 3px solid #0d6efd;
outline-offset: 4px;
}
وهنا اللي بيحصل:
- لو المستخدم ضغط بالماوس، مفيش outline.
- لو ضغط
Tabوعمل فوكس على الزرار، بيظهر outline واضح. - ده بيدي تجربة محترمة ويسهّل التنقل بالكيبورد.
11.3 محدد الـ :enabled#
بيستهدف العناصر المفعّلة (enabled)، يعني اللي مش عليهم disabled.
مفيد لو عندك زرار أو input مفتوح وعايز تديله شكل مختلف عن المقفول.
مثال:
<input type="text" placeholder="اكتب هنا">
input:enabled {
background: #fff;
cursor: text;
}
واللي بيحصل هنا:
- العنصر طالما مش
disabledبياخد التنسيق ده. - مفيد لما تعمل switch بين حالتين (enabled / disabled) في UI.
11.4 محدد الـ :required#
يستهدف أي Input عليه required.
ممتاز جدًا علشان توضح للمستخدم إن الحقل إلزامي.
مثال:
<input type="text" required placeholder="اسمك كامل">
input:required {
border-left: 4px solid orange;
}
وهنا اللي بيحصل:
- أي حقل إجباري بيظهر عليه شريط برتقالي.
- طريقة واضحة للمستخدم إنه لازم يملأه.
11.5 محدد الـ :optional#
عكس required وده بيستهدف الحقول اللي مش إجبارية.
مثال:
<input type="text" placeholder="ملاحظات (اختياري)">
input:optional {
border-left: 4px solid #ccc;
}
وهنا اللي بيحصل:
- العناصر اللي بدون
requiredفقط هي اللي هتاخد التنسيق ده. - بيساعد في التفريق بين الحقول الإلزامية والاختيارية.
مثال شامل - Form فيه كل الحالات#
<form class="my-form">
<div class="form-group">
<label>البريد الإلكتروني</label>
<input type="email" required>
</div>
<div class="form-group">
<label>الاسم (اختياري)</label>
<input type="text">
</div>
<button class="btn" disabled>متابعة</button>
</form>
/* Focus Within */
.form-group:focus-within {
border-color: #0d6efd;
background: #eef6ff;
}
/* Required */
input:required {
border-left: 4px solid orange;
}
/* Optional */
input:optional {
border-left: 4px solid #ccc;
}
/* Enabled / Disabled */
button:disabled {
background: #999;
cursor: not-allowed;
}
button:enabled {
background: #0d6efd;
color: #fff;
cursor: pointer;
}
/* Focus Visible */
.btn:focus-visible {
outline: 3px solid #0d6efd;
outline-offset: 3px;
}
النتيجة النهائية في هذا المثال
- الحقول الإلزامية واضحة للمستخدم.
- الـ form بيستجيب بمجرد المستخدم يدخل يكتب.
- زرار الإرسال باين لو Enabled أو Disabled.
- التجربة كلها Accessible ومحترفة من غير JavaScript.
12. المحددات الحديثة New CSS4 Logical Selectors#
دي مجموعة من أقوى المحددات في CSS الحديثة، واللي بتسمحلك تعمل منطق منطقي Logical Conditions جوّه الـ CSS نفسه.
معاها تقدر تختار عناصر بناءً على محتوياتها أو بناءً على وجود عناصر معينة جواها. حاجة كده كانت من المستحيل تتعمل قبل CSS4.
12.1 محدد الـ :has()#
أقوى محدد في CSS لحد الآن وبيخلّي CSS يشوف للأمام بدل ما يعتمد على الأبناء فقط.
الفكرة ببساطة:
المحدد ده بيختار العنصر لو بيحتوي على عنصر أو حالة معينة بداخله.
مثال 1 - تلوين الـ div اللي جواه زرار Active
div:has(button.active) {
border: 2px solid green;
}
وهنا اللي بيحصل:
هنا أنا مش بختار الزرار، أنا بختار الـ div نفسه، بناءً على وجود زرار بداخله عليه كلاس active.
مثال 2 - تمييز كل form فيها input فارغ
form:has(input:invalid) {
background: #ffe6e6;
}
وهنا اللي بيحصل:
تخيل كأن الـ CSS بيقول:
لو الفورم جواه Input مش صالح هنقوم بتغيير لون الخلفية.
ده بديل رائع لكتابة الـ JavaScript لمجرد التحقق.
مثال 3 - اختيار بطاقات المنتجات اللي فيها سعر مخفّض
.product:has(.price.discount) {
box-shadow: 0 0 15px orange;
}
وهنا اللي بيحصل:
بتقدر تعمل “اكتشاف ذكي” للحالات جوّه العنصر بدون داتا إضافية ولا JS.
12.2 محدد الـ :is()#
محدد اختصاري بيسهّل كتابة Selectors طويلة ومعقدة.
الفكرة ببساطة:
يجمع مجموعة من المحددات بدل ما تكتبهم كلهم.
مثال - اختصار تحديد عناصر مختلفة داخل .card
.card :is(h2, h3, p) {
margin-bottom: 10px;
}
واللي بيحصل هنا:
بدل ما تكتب:
.card h2,
.card h3,
.card p { ... }
تكتبها مرة واحدة.
12.3 محدد الـ :where()#
زي :is() بالظبط. لكن بدون أي Specificity (قوّته = صفر).
عن طريقها تقدر تعمل Reset Styles بدون ما تتعارض مع أي تنسيق تاني.
مثال — تعيين هوامش لجميع العناصر الداخلية لأي Section:
section :where(h1, h2, h3, p, ul, li) {
margin: 0;
padding: 0;
}
واللي بيحصل هنا:
لأن :where() Specificity بتاعته = 0
فمش هيأثر على تصميمك الأساسي وسيبقى ليه الأولوية.
12.4 محدد الـ :not()#
يختار أي عنصر ماعدا اللي انت مستثنيه.
مثال - تلوين كل الأزرار ما عدا الزر الذي يحتوي علي كلاس معين
button:not(.danger) {
background: #007bff;
color: #fff;
}
مثال — استثناء عنصر معين من قائمة التنسيق
ul li:not(:first-child) {
border-top: 1px solid #ddd;
}
واللي هيحصل هنا:
كل العناصر هتتطبيق عليها التنسيق
ما عدا أول عنصر.
مثال تطبيقي شامل على الـ Logical Selectors
خلّينا نعمل مثال بسيط لمنتجات متجر:
كود الـ HTML:
<div class="product">
<h3>Product A</h3>
<span class="price">$90</span>
</div>
<div class="product">
<h3>Product B</h3>
<span class="price discount">$49</span>
</div>
<div class="product featured">
<h3>Product C</h3>
<span class="price">$120</span>
</div>
كود الـ CSS:
/* تحديد البطاقات التي فيها سعر مخفّض */
.product:has(.price.discount) {
border: 2px solid orange;
}
/* تقليل الMargin للعناوين */
.product :is(h3, .price) {
margin-bottom: 8px;
}
/* إزالة التنسيق عن العنوان اللي في Featured */
.product.featured :not(h3) {
opacity: 0.7;
}
/* Reset عام بدون Specificity */
.product :where(*) {
padding: 0;
}
والجدول اللي تحت ده هيعرفك الفرق بينهم
| المحدد | وظيفته |
|---|---|
:has() | يختار العنصر بناءً على ما يحتويه |
:is() | اختصار لمجموعة Selectors |
:where() | زي :is() لكن بدون Specificity |
:not() | استثناء عناصر من التحديد |
13. محددات الـ Pseudo-elements#
الـ Pseudo-elements هي أجزاء افتراضية يضيفها CSS كأنها عناصر جديدة داخل الـ HTML،
وتسمح لك بالتحكّم في أجزاء دقيقة داخل العنصر، مثل أول حرف، أو إضافة محتوى قبل أو بعد العنصر…
وهي من أقوى الأدوات في تصميم الواجهات.
13.1 محدد الـ ::before#
تُستخدم لإضافة محتوى قبل العنصر بدون الحاجة لإضافة عناصر HTML حقيقية.
مثال - إضافة أيقونة قبل عنوان قسم
h2::before {
content: "🔹 ";
font-size: 24px;
color: #3498db;
}
واللي هيحصل فعلاً:
الـ
::beforeبيضيف النص/الرمز قبل محتوى العنصر الأصلي."🔹 "هو المحتوى الافتراضي الظاهر.تقدر تضيف صورة باستخدام:
content: url(icon.png);
الفايدة هنا:
مفيد جدًا في توحيد تصميم العناوين، القوائم، أو الإشعارات بدون ما تمسّ الكود نفسه.
13.2 محدد الـ ::after#
زي ::before بالضبط، لكن المحتوى بيظهر بعد العنصر.
مثال - علامة “جديد” بعد المنتج
.product.new::after {
content: " (New)";
color: green;
font-weight: bold;
}
واللي هيحصل ببساطة:
هنا إنت ضفت نص “New” بعد اسم المنتج بدون ما تعدل HTML.
ده مفيد لو بتولّد محتوى ديناميكي.
مثال تاني - شريط زخرفي أسفل العنوان
h3::after {
content: "";
display: block;
width: 50px;
height: 3px;
background: #ff9800;
margin-top: 6px;
}
واللي هيحصل هنا:
- لأن المحتوى فارغ، استخدمنا
content: "". - تنسيق الـ
display: blockعشان يظهر كسطر جديد. - بنضيف “Bar” تصميمي أسفل العنوان.
بس خد بالك:
الـ ::before و ::after لا يعملان بدون content:
حتى لو قيمته فارغة، يجب إضافته.
13.3 الـ ::first-letter#
يختار أول حرف في فقرة أو عنصر نصي.
مثال - تصميم Drop Cap (الحرف الأول الكبير في بداية المقالات)
p::first-letter {
font-size: 3rem;
color: #b63a3a;
font-weight: bold;
float: left;
margin-right: 8px;
}
واللي هيحصل:
- تكبير الحرف الأول ليعطي إحساس المقالات المطبوعة القديمة.
- الـ
float: leftلجعل باقي النص يلتف حوله. - إضافة Margin لترك مساحة جانبية.
وعشان الحرف يظهر بشكل صحيح:
- يعمل فقط مع العناصر الـ block أو inline-block.
- الحرف الأول يشمل علامات الاقتباس أحيانًا حسب اللغة.
13.4 محدد الـ ::selection#
يتحكم في شكل النص عند تحديده (Selection) بالماوس.
مثال - تغيير لون النص وخلفيته عند تحديد المستخدم له
::selection {
background: #1e88e5;
color: #fff;
}
بس لازم تعرف:
- اللون الافتراضي غالبًا يكون أزرق فاتح، هنا غيرناه بالكامل.
- يعطي هوية بصرية مميزة للموقع، ويُستخدم في العلامات التجارية.
دعم المتصفحات:
معظم المتصفحات تدعمه، لكن لو أردت دعمًا أوسع أضِف:
::-moz-selection {
background: #1e88e5;
color: #fff;
}
مثال تطبيقي شامل على الـ Pseudo-elements#
كود الـ HTML:
<h2 class="title">Welcome to CSS Guide</h2>
<p class="intro">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi in magna sed lorem varius tincidunt.
</p>
<button class="cta">Subscribe</button>
كود الـ CSS:
/* قبل العنوان */
.title::before {
content: "★ ";
color: gold;
font-size: 20px;
}
/* بعد الزر */
.cta::after {
content: " →";
font-weight: bold;
}
/* أول حرف من الفقرة */
.intro::first-letter {
font-size: 2.7rem;
color: #d35400;
float: left;
margin-right: 10px;
}
/* تحديد النص */
::selection {
background: #333;
color: #fff;
}
وده ملخص عشان تعرف الفرق بينهم
| الـ Pseudo-element | وظيفته |
|---|---|
::beforeالـ | إضافة محتوى قبل العنصر |
::after الـ | إضافة محتوى بعد العنصر |
::first-letter الـ | تنسيق أول حرف فقط |
::selection الـ | تخصيص شكل النص عند تحديده |
14. الـ Grouping Selectors#
الـ Grouping Selectors بتستخدمها لما يكون عندك أكتر من عنصر عايز تطبق عليه نفس التنسيق، بدل ما تكرر الكود.
الصيغة بتكون كالتالي:
h1, h2, h3 {
color: #333;
}
وعشان نفهم:
الفاصلة , معناها “و”.
يعني:
غيّر لون h1 و h2 و h3 كلهم بنفس القيمة.
مثال تاني:
تطبيق نفس الـ padding على عناصر مختلفة:
button, input, select {
padding: 10px;
}
15. الـ Complex Selectors#
وهي مجموعة Selectors بتتجمع مع بعض لتشكيل شرط دقيق جدًا.
كل جزء من السطر بيمثل طبقة من الشروط.
من الأخر بنظبق مجموعة من الـ Selectors اللي فاتوا في تنسيق واحد فقط.
مثال عشان نفهم:
ul li.item:first-child > a[href^="http"]
تحليل الكود خطوة بخطوة:
بإستخدام الـ ul
بتقول أن داخل أي قائمة غير مرتبة.وكمان الـ li.item:first-child
بتقول أن أول عنصر<li>بشرط يكون عليه الكلاسitem.العلامة ده >
بتقول إن لازم يكون العنصر اللي بعده ابن مباشر.كمان لما نكتب a[href^=“http”]
بنقول إن عنصر<a>يبدأ رابط الـ href بتاعه بـ"http".
والنتيجة اللي هتحصل:
هيختار “رابط” داخل أول عنصر <li class="item"> في الـ <ul> بشرط إن الرابط يبدأ بـ http.
مثال قوي ومهم (باستخدام :has())
اختر كل div يحتوي input إجباري required
div:has(input[required]) {
border: 2px solid red;
}
وهنا هيحصل:
الـ :has() هنا بيخلّي CSS يعرف إن جوّه الـ <div> ده فيه <input> مطلوب.
فلو موجود نضيف له إطار أحمر.
مثال عملي أوضح:
<div class="field">
<label>Name</label>
<input type="text" required>
</div>
<div class="field">
<label>Message</label>
<input type="text">
</div>
.field:has(input[required]) {
background: #ffe5e5;
}
واللي هيحصل هنا:
- أول div هيبقى لونه فاتح لأنه يحتوي input required
- التاني هيفضل عادي.
وفي الختام
لو فيه جزء في الـ CSS يستاهل إنك تتقنه من البداية فهو CSS Selectors.
ليه؟
لإن كل سطر تنسيق هتكتبه بعد كده بيعتمد بنسبة كبيرة على اختيارك للعنصر الصح، بأبسط طريقة، وأوضح أسلوب، وأكفأ أداء.
يمكن مش هتستعمل كل الأنواع اللي شرحناها في مشروع واحد، وده طبيعي جدًا… لكن أهم حاجة إنك تكون عارف كل أداة موجودة في إيدك.
ولما تيجي تواجه مشكلة محتاجة طريقة معينة، اختيار عنصر بناءً على نوعه، ترتيبه، علاقته، حالته، أو حتى محتواه. هتلاقي الحل جاهز في دماغك بدل ما تلف كتير أو تعمل حلول مُعقّدة.
ومع الوقت والخبرة، هتبدأ تستخدم الـ Selectors بشكل احترافي يخليك تبني صفحات أنضف، أسرع، وأسهل في التطوير.
اختيار العنصر الصح، بالطريقة الصح. ده السر الحقيقي وراء أي كود CSS محترم.
وبكده تكون خلاص فهمت “خريطة الطريق” الكاملة للـ Selectors، وكل اللي ناقص دلوقتي إنك تبدأ تطبّق.

