CSS3 والتصميم المتجاوب

المحددات البسيطة: النوع والفئة والمعرف

25 دقيقة الدرس 3 من 60

فهم محددات CSS

المحددات هي آلية الاستهداف في CSS. كل مجموعة قواعد تكتبها تبدأ بمحدد يخبر المتصفح بالضبط أي عناصر HTML يجب أن تتلقى الأنماط المحددة في كتلة التصريحات. بدون المحددات، لن يكون لدى CSS طريقة لمعرفة أين يطبق أنماطك. فكر في المحددات كعناوين على الأظرف -- فهي توجه تعليمات التنسيق إلى الوجهة الصحيحة في الصفحة.

يقدم CSS مجموعة غنية ومتنوعة من أنواع المحددات، من محددات اسم العنصر البسيطة إلى المجمعات والفئات الزائفة المتطورة للغاية. في هذا الدرس، نركز على المحددات البسيطة -- اللبنات الأساسية التي ستستخدمها في كل ورقة أنماط تكتبها تقريبا. إتقان هذه المحددات يمنحك القدرة على استهداف أي عنصر في الصفحة بدقة ووضوح.

المحددات البسيطة التي سنغطيها هي: محددات النوع ومحددات الفئة ومحددات المعرف والمحدد العام ومحددات السمات وتجميع المحددات. لكل منها غرض مميز وصيغة ومجموعة من أفضل الممارسات. بنهاية هذا الدرس، ستعرف متى تستخدم كل واحد منها وكيف تجمعها بفعالية.

محددات النوع (محددات العنصر)

محدد النوع، ويسمى أيضا محدد العنصر أو محدد الوسم، يستهدف كل مثيل لعنصر HTML معين في الصفحة. ما عليك سوى كتابة اسم الوسم -- بدون أحرف خاصة ولا بادئات -- وسيتلقى كل عنصر من ذلك النوع الأنماط المصرح بها.

صيغة محدد النوع

/* يستهدف جميع عناصر <h1> في الصفحة */
h1 {
    color: #1a1a2e;
    font-size: 2.5rem;
    font-weight: 700;
    margin-bottom: 16px;
}

/* يستهدف جميع عناصر <p> في الصفحة */
p {
    color: #444444;
    font-size: 1rem;
    line-height: 1.8;
    margin-bottom: 12px;
}

/* يستهدف جميع عناصر <div> في الصفحة */
div {
    padding: 10px;
    box-sizing: border-box;
}

محددات النوع واسعة بطبيعتها. عندما تكتب p { color: #444; }، فأنت تخبر المتصفح بتطبيق ذلك اللون على كل فقرة في الصفحة -- بدون استثناءات. هذا يجعل محددات النوع مثالية لتعيين الأنماط الأساسية التي تؤسس قاعدة متسقة عبر موقعك بالكامل. على سبيل المثال، يمكنك استخدام محددات النوع لتحديد أحجام الخطوط الافتراضية للعناوين وارتفاعات الأسطر للفقرات وسلوك الحدود للصور.

تعيين الأنماط الأساسية بمحددات النوع

/* أنماط الطباعة الأساسية */
body {
    font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
    color: #333333;
    line-height: 1.6;
    margin: 0;
    padding: 0;
}

h1 { font-size: 2.5rem; margin-bottom: 20px; }
h2 { font-size: 2rem; margin-bottom: 16px; }
h3 { font-size: 1.5rem; margin-bottom: 12px; }
h4 { font-size: 1.25rem; margin-bottom: 10px; }

p { margin-bottom: 1em; }

a {
    color: #0066cc;
    text-decoration: none;
}

img {
    max-width: 100%;
    height: auto;
    display: block;
}

ul, ol {
    padding-left: 1.5em;
    margin-bottom: 1em;
}
نصيحة: محددات النوع مثالية لإنشاء "إعادة تعيين" أو "تطبيع" CSS أساسي في أعلى ورقة الأنماط. من خلال تأسيس أنماط افتراضية متسقة لعناصر HTML الشائعة، تمنع تناقضات المتصفحات من التأثير على تصميمك. تبدأ العديد من أوراق الأنماط المحترفة بقواعد محدد النوع لعناصر body و h1-h6 و p و a و img و ul و ol قبل الانتقال إلى أنماط المكونات القائمة على الفئات.
تحذير: نظرا لأن محددات النوع تستهدف كل مثيل لعنصر ما، فقد تنتج آثارا جانبية غير مقصودة في المشاريع الكبيرة. إذا كتبت div { border: 1px solid red; }، فإن كل <div> في الصفحة -- بما في ذلك تلك الموجودة داخل مكونات الطرف الثالث والنوافذ المنبثقة وأشرطة التنقل -- ستحصل على حد أحمر. استخدم محددات النوع بعناية للإعدادات الافتراضية العامة، واعتمد على الفئات لأنماط المكونات المحددة.

محددات الفئة

محدد الفئة هو الأداة الرئيسية في CSS الحديث. يستهدف العناصر التي تحتوي على قيمة محددة في سمة class الخاصة بها. تكتب محدد الفئة بوضع نقطة (.) قبل اسم الفئة. على عكس محددات النوع، لا تؤثر محددات الفئة إلا على العناصر التي تختار صراحة المشاركة من خلال تضمين تلك الفئة في HTML الخاص بها.

صيغة محدد الفئة

/* CSS */
.card {
    background-color: #ffffff;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    padding: 24px;
    margin-bottom: 20px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}

.highlight {
    background-color: #fff3cd;
    border-left: 4px solid #ffc107;
    padding: 12px 16px;
}

.text-center {
    text-align: center;
}

استخدام الفئات في HTML

<!-- هذا العنصر div يتلقى أنماط .card -->
<div class="card">
    <h3>عنوان المقال</h3>
    <p>بعض محتوى المقال هنا.</p>
</div>

<!-- هذه الفقرة تتلقى أنماط .highlight -->
<p class="highlight">هذا إشعار مهم.</p>

<!-- هذا العنصر div ليس له فئة، لذا لا يحصل على أنماط فئة -->
<div>
    <p>هذا غير منسق بالقواعد أعلاه.</p>
</div>

فئات متعددة على عنصر واحد

واحدة من أقوى ميزات محددات الفئة هي أن عنصر HTML واحد يمكن أن يحتوي على فئات متعددة. ما عليك سوى فصل كل اسم فئة بمسافة داخل سمة class. يتلقى العنصر أنماطا من جميع الفئات المدرجة في وقت واحد. هذا يعزز التركيب -- بناء مظاهر معقدة من خلال الجمع بين فئات مساعدة صغيرة ومركزة.

مثال الفئات المتعددة

/* CSS - فئات صغيرة ومركزة */
.card {
    background: #ffffff;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 20px;
}

.shadow {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.rounded-lg {
    border-radius: 16px;
}

.mb-4 {
    margin-bottom: 2rem;
}

.text-primary {
    color: #0066cc;
}

تطبيق فئات متعددة في HTML

<!-- هذا العنصر يتلقى أنماطا من جميع الفئات الأربع -->
<div class="card shadow rounded-lg mb-4">
    <h3 class="text-primary">ميزة مميزة</h3>
    <p>هذه البطاقة لها زوايا مستديرة وظل وهامش سفلي.</p>
</div>

<!-- نفس مكون البطاقة، مجموعة مختلفة -->
<div class="card mb-4">
    <h3>ميزة أساسية</h3>
    <p>هذه البطاقة ليس لها ظل أو تدوير إضافي.</p>
</div>
ملاحظة: ترتيب أسماء الفئات في سمة class في HTML لا يحدد أي الأنماط لها الأولوية. إذا حددت فئتان نفس الخاصية، فإن الفئة التي تظهر لاحقا في ورقة أنماط CSS هي التي تفوز (بافتراض تساوي الخصوصية). ترتيب HTML لا علاقة له -- فقط ترتيب مصدر CSS هو المهم.

تسلسل الفئات لمزيد من الدقة

يمكنك تسلسل محددات فئات متعددة معا في CSS (بدون مسافات) لاستهداف العناصر التي تحتوي على جميع الفئات المحددة فقط. هذه تقنية قوية لإنشاء أنماط المعدلات والأنماط الشرطية.

تسلسل محددات الفئة

/* يستهدف العناصر التي تحتوي على فئتي .btn و .btn-primary معا */
.btn.btn-primary {
    background-color: #0066cc;
    color: #ffffff;
    border: none;
}

/* يستهدف العناصر التي تحتوي على فئتي .btn و .btn-danger معا */
.btn.btn-danger {
    background-color: #dc3545;
    color: #ffffff;
    border: none;
}

/* يستهدف العناصر التي تحتوي على .card و .featured و .large */
.card.featured.large {
    border: 2px solid gold;
    padding: 40px;
    font-size: 1.2em;
}

التسلسل في HTML

<!-- يطابق .btn.btn-primary -->
<button class="btn btn-primary">إرسال</button>

<!-- يطابق .btn.btn-danger -->
<button class="btn btn-danger">حذف</button>

<!-- يطابق .card.featured.large -->
<div class="card featured large">
    <h3>عرض خاص</h3>
</div>

<!-- لا يطابق .card.featured.large (ينقصه .large) -->
<div class="card featured">
    <h3>عرض عادي</h3>
</div>

محددات المعرف

محدد المعرف يستهدف عنصرا واحدا فريدا في الصفحة. تكتبه بوضع رمز المربع (#) قبل اسم المعرف. في HTML الصالح، يجب أن تكون كل قيمة سمة id فريدة داخل المستند -- لا يمكن لعنصرين مشاركة نفس المعرف. هذا يجعل محددات المعرف الأكثر تحديدا بين المحددات البسيطة.

صيغة محدد المعرف

/* CSS */
#main-header {
    background-color: #1a1a2e;
    color: #ffffff;
    padding: 20px 40px;
    position: sticky;
    top: 0;
    z-index: 1000;
}

#hero-section {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    min-height: 80vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

#footer {
    background-color: #2d2d2d;
    color: #cccccc;
    padding: 40px;
    text-align: center;
}

استخدام المعرفات في HTML

<header id="main-header">
    <nav>...</nav>
</header>

<section id="hero-section">
    <h1>مرحبا بك في موقعي</h1>
</section>

<footer id="footer">
    <p>حقوق النشر 2025</p>
</footer>

الفئة مقابل المعرف: أفضل الممارسات

أحد أكثر الأسئلة شيوعا التي يطرحها المبتدئون هو: "متى يجب أن أستخدم فئة ومتى يجب أن أستخدم معرفا؟" إليك إطار قرار واضح:

  • استخدم الفئات للتنسيق. الفئات قابلة لإعادة الاستخدام وقابلة للتركيب ولها خصوصية معتدلة. إنها الأداة القياسية لجميع التنسيقات المرئية في CSS الحديث.
  • استخدم المعرفات لربط JavaScript والروابط المرجعية. المعرفات مثالية لـ document.getElementById() في JavaScript ولإنشاء روابط مرجعية (<a href="#section-name">). تستخدم أيضا بواسطة سمة HTML <label for="..."> لربط التسميات بحقول النماذج.
  • تجنب المعرفات للتنسيق كلما أمكن ذلك. محددات المعرف لها خصوصية عالية جدا (سنغطي الخصوصية في درس لاحق)، مما يجعل من الصعب تجاوزها دون اللجوء إلى محددات عالية الخصوصية أخرى أو علامة !important. يمكن أن يؤدي هذا إلى "حروب الخصوصية" التي تجعل CSS أصعب في الصيانة.
  • المعرفات لا يمكن إعادة استخدامها. إذا قمت بتنسيق شيء بمعرف واحتجت لاحقا إلى نفس التنسيق على عنصر آخر، فسيتعين عليك إعادة الهيكلة. الفئات تتجنب هذه المشكلة تماما لأنها مصممة لإعادة الاستخدام.

مقارنة الفئة والمعرف

/* سيء: استخدام المعرفات للتنسيق (صعب إعادة الاستخدام والتجاوز) */
#submit-button {
    background-color: #0066cc;
    color: white;
    padding: 10px 24px;
    border: none;
    border-radius: 4px;
}

/* جيد: استخدام فئة للتنسيق (قابلة لإعادة الاستخدام) */
.btn-primary {
    background-color: #0066cc;
    color: white;
    padding: 10px 24px;
    border: none;
    border-radius: 4px;
}

/* الآن يمكن لأي زر استخدام هذا التنسيق: */
/* <button class="btn-primary">إرسال</button> */
/* <button class="btn-primary">حفظ</button> */
/* <a class="btn-primary" href="#">اعرف المزيد</a> */
تحذير: استخدام نفس المعرف على عناصر متعددة هو HTML غير صالح. بينما قد تستمر المتصفحات في عرض الصفحة، فإن طرق JavaScript مثل document.getElementById() ستجد فقط أول ظهور، ويصبح سلوك CSS غير متوقع. احرص دائما على أن تكون المعرفات فريدة داخل الصفحة.

المحدد العام

المحدد العام (*) يطابق كل عنصر في الصفحة، بغض النظر عن نوعه أو فئته أو معرفه. إنه أوسع محدد ممكن. بينما له استخدام محدود في تنسيق الإنتاج، فإنه يخدم عدة أغراض مهمة في التطوير وإعادة التعيين الأساسية.

صيغة المحدد العام

/* ينطبق على كل عنصر في الصفحة */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* هذا أحد أكثر الاستخدامات شيوعا:
   إعادة تعيين "box-sizing" تضمن أن جميع العناصر
   تشمل الحشو والحد في عرضها/ارتفاعها الإجمالي */

أشهر استخدام للمحدد العام هو إعادة تعيين box-sizing. بشكل افتراضي، يحسب نموذج صندوق CSS العرض الإجمالي للعنصر كـ width + padding + border، مما يؤدي إلى حسابات حجم محيرة. تعيين box-sizing: border-box على جميع العناصر عبر المحدد العام يغير هذا بحيث يكون width هو العرض الإجمالي بما في ذلك الحشو والحد. تقريبا كل إطار عمل CSS حديث وورقة أنماط احترافية تتضمن إعادة التعيين هذه.

إعادة تعيين Box-Sizing الحديثة

/* النهج الموصى به: الوراثة من html */
html {
    box-sizing: border-box;
}

*, *::before, *::after {
    box-sizing: inherit;
}

/* هذا النمط يتيح للمكونات الفردية الخروج إذا لزم الأمر
   عن طريق تعيين box-sizing: content-box على عنصر أب */
نصيحة: المحدد العام له خصوصية منخفضة جدا (صفر أساسا)، لذا فإن أي محدد آخر سيتجاوزه بسهولة. هذا يجعله آمنا لإعادة التعيين العامة -- ستأخذ أنماط مكوناتك المحددة الأولوية دائما بدون أي تعارضات في الخصوصية.

محددات السمات

محددات السمات تستهدف العناصر بناء على وجود أو قيمة سمات HTML الخاصة بها. تكتب داخل أقواس مربعة [ ] وتوفر مرونة ملحوظة لاستهداف العناصر دون الحاجة إلى إضافة فئات أو معرفات إضافية. محددات السمات مفيدة بشكل خاص لتنسيق عناصر النماذج والروابط وأي HTML يستخدم سمات data-* المخصصة.

وجود السمة الأساسي: [attr]

أبسط شكل يحدد العناصر التي تمتلك سمة معينة، بغض النظر عن قيمة السمة.

محدد وجود السمة

/* يستهدف أي عنصر يمتلك سمة "title" */
[title] {
    cursor: help;
    border-bottom: 1px dotted #999;
}

/* يستهدف أي عنصر يمتلك سمة "required" */
[required] {
    border-color: #cc0000;
}

/* يستهدف أي عنصر يمتلك سمة "disabled" */
[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
}

HTML لوجود السمة

<!-- يطابقه [title] -->
<abbr title="لغة توصيف النص التشعبي">HTML</abbr>

<!-- يطابقه [required] -->
<input type="email" required>

<!-- يطابقه [disabled] -->
<button disabled>لا يمكن النقر</button>

<!-- لا يطابق أيا مما سبق (لا يحتوي على title أو required أو disabled) -->
<p>فقرة عادية</p>

مطابقة القيمة الدقيقة: [attr=val]

هذا الشكل يحدد العناصر التي تساوي فيها السمة قيمة محددة بالضبط.

محدد سمة القيمة الدقيقة

/* يستهدف عناصر <input> مع type="email" */
[type="email"] {
    background-image: url("email-icon.svg");
    background-repeat: no-repeat;
    background-position: right 10px center;
    padding-right: 36px;
}

/* يستهدف عناصر <input> مع type="password" */
[type="password"] {
    letter-spacing: 0.3em;
}

/* يستهدف العناصر ذات قيمة سمة بيانات محددة */
[data-theme="dark"] {
    background-color: #1a1a2e;
    color: #e0e0e0;
}

[data-theme="light"] {
    background-color: #ffffff;
    color: #333333;
}

القيمة المفصولة بمسافات: [attr~=val]

هذا المحدد يطابق العناصر التي تكون فيها قيمة السمة قائمة كلمات مفصولة بمسافات، وإحدى تلك الكلمات تساوي بالضبط القيمة المحددة. هذا يختلف عن المطابقة الدقيقة لأنه يعمل مع قيم السمات متعددة الكلمات.

محدد السمة المفصولة بمسافات

/* يستهدف العناصر التي تحتوي سمة "class" على كلمة "featured" */
[class~="featured"] {
    border: 2px solid gold;
}

/* يستهدف العناصر التي تحتوي سمة "rel" على كلمة "noopener" */
[rel~="noopener"] {
    /* تنسيق الروابط الخارجية */
    color: #cc6600;
}

HTML لمحدد ~=

<!-- مطابق: "featured" هي إحدى الكلمات المفصولة بمسافات -->
<div class="card featured large">خاص</div>

<!-- غير مطابق: "featured-item" ليست الكلمة الدقيقة "featured" -->
<div class="card featured-item">غير مطابق</div>

<!-- مطابق: "noopener" موجودة في قائمة rel -->
<a href="#" rel="noopener noreferrer">رابط خارجي</a>

مطابقة البادئة: [attr^=val]

محدد الإقحام-يساوي يطابق العناصر التي تبدأ قيمة سمتها بالسلسلة المحددة. هذا مفيد للغاية لاستهداف الروابط بناء على بروتوكولها أو استهداف العناصر ذات اصطلاحات التسمية المنهجية.

محدد سمة البادئة

/* يستهدف الروابط التي تبدأ بـ "https" */
[href^="https"] {
    color: green;
}

/* يستهدف الروابط التي تبدأ بـ "http:" (غير آمنة) */
[href^="http:"] {
    color: red;
}

/* يستهدف الروابط التي تبدأ بـ "mailto:" */
[href^="mailto:"] {
    background-image: url("mail-icon.svg");
    padding-left: 20px;
}

/* يستهدف الروابط التي تبدأ بـ "tel:" */
[href^="tel:"] {
    background-image: url("phone-icon.svg");
    padding-left: 20px;
}

/* يستهدف العناصر التي تبدأ فئتها بـ "col-" */
[class^="col-"] {
    float: left;
    padding: 0 15px;
}

مطابقة اللاحقة: [attr$=val]

محدد الدولار-يساوي يطابق العناصر التي تنتهي قيمة سمتها بالسلسلة المحددة. هذا مفيد بشكل خاص لتنسيق الروابط بناء على امتداد الملف.

محدد سمة اللاحقة

/* يستهدف روابط ملفات PDF */
[href$=".pdf"] {
    background-image: url("pdf-icon.svg");
    padding-right: 20px;
    color: #cc0000;
}

/* يستهدف روابط ملفات الصور */
[href$=".jpg"],
[href$=".png"],
[href$=".gif"] {
    border-bottom: 2px solid #0066cc;
}

/* يستهدف روابط المستندات الخارجية */
[href$=".doc"],
[href$=".docx"] {
    background-image: url("word-icon.svg");
    padding-right: 20px;
}

مطابقة السلسلة الفرعية: [attr*=val]

محدد النجمة-يساوي يطابق العناصر التي تحتوي قيمة سمتها على السلسلة المحددة في أي مكان. هذا هو أكثر محددات السمات مرونة، لكن استخدمه بحذر لتجنب المطابقات الواسعة جدا.

محدد سمة السلسلة الفرعية

/* يستهدف أي رابط يحتوي على "youtube" في href */
[href*="youtube"] {
    color: #ff0000;
}

/* يستهدف أي رابط يحتوي على "github" في href */
[href*="github"] {
    color: #333;
    font-family: monospace;
}

/* يستهدف العناصر التي تحتوي على "btn" في أي مكان في فئتها */
[class*="btn"] {
    cursor: pointer;
    display: inline-block;
    text-align: center;
}
ملاحظة: محددات السمات حساسة لحالة الأحرف بشكل افتراضي لقيم السمات. إذا كنت بحاجة إلى مطابقة غير حساسة لحالة الأحرف، أضف علامة i قبل القوس الإغلاق: [href$=".PDF" i] ستطابق كلا من .pdf و .PDF. هذه ميزة من CSS Selectors Level 4 مدعومة في جميع المتصفحات الحديثة.

محدد سمة غير حساس لحالة الأحرف

/* يطابق .pdf و .PDF و .Pdf وغيرها */
[href$=".pdf" i] {
    color: #cc0000;
}

/* يطابق type="TEXT" و type="text" و type="Text" وغيرها */
[type="text" i] {
    border: 1px solid #ccc;
}

تجميع المحددات بالفواصل

عندما تحتاج محددات متعددة إلى نفس مجموعة الأنماط، يمكنك تجميعها معا بفصلها بفواصل. هذا يتجنب تكرار كتل التصريحات المتطابقة ويحافظ على إيجاز CSS. يعمل التجميع مع أي نوع من المحددات -- محددات النوع أو محددات الفئة أو محددات المعرف أو محددات السمات أو أي مجموعة.

تجميع المحددات

/* بدون تجميع: متكرر ومهدر */
h1 {
    font-family: Georgia, serif;
    color: #1a1a2e;
}
h2 {
    font-family: Georgia, serif;
    color: #1a1a2e;
}
h3 {
    font-family: Georgia, serif;
    color: #1a1a2e;
}

/* مع التجميع: نظيف وقابل للصيانة */
h1, h2, h3 {
    font-family: Georgia, serif;
    color: #1a1a2e;
}

/* تجميع أنواع مختلفة من المحددات */
h1, .page-title, #main-heading {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.2;
}

/* تجميع مع محددات السمات */
[type="text"],
[type="email"],
[type="password"],
[type="tel"],
[type="url"] {
    width: 100%;
    padding: 10px 14px;
    border: 1px solid #ccc;
    border-radius: 4px;
    font-size: 1rem;
}
نصيحة: عند تجميع المحددات، ضع كل محدد في سطر خاص به لسهولة القراءة. هذا يسهل إضافة أو إزالة المحددات لاحقا ويساعد في التحكم بالإصدارات (كل تغيير يظهر كإضافة أو إزالة سطر واضحة في git diffs).
تحذير: إذا كان أي محدد في القائمة المجمعة غير صالح، فإن القاعدة بأكملها يتم تجاهلها في CSS القياسي. على سبيل المثال، h1, h2:unknown-pseudo, h3 { color: red; } لن تنطبق على أي من المحددات الثلاثة لأن h2:unknown-pseudo غير صالح. هذا مصدر شائع للأخطاء، لذا تحقق دائما من المحددات المجمعة.

اصطلاحات التسمية

اختيار أسماء جيدة للفئات والمعرفات هو مهارة حاسمة تؤثر مباشرة على قابلية قراءة وصيانة الكود. التسمية السيئة تؤدي إلى الارتباك، بينما التسمية المدروسة تجعل أوراق الأنماط توثق نفسها بنفسها.

قواعد أسماء CSS الصالحة

  • يمكن أن تحتوي أسماء الفئات والمعرفات على أحرف وأرقام وشرطات (-) وشرطات سفلية (_).
  • يجب ألا تبدأ برقم. الاسم 3column غير صالح، لكن col-3 صالح.
  • هي حساسة لحالة الأحرف: .Card و .card هما محددان مختلفان.
  • تجنب الأحرف الخاصة والمسافات وعلامات الترقيم غير الشرطات والشرطات السفلية.

اصطلاحات التسمية الشائعة

Kebab-Case (الموصى به)

/* الاصطلاح الأكثر شيوعا في CSS */
.nav-bar { }
.hero-section { }
.card-title { }
.btn-primary { }
.form-input-group { }
.footer-social-links { }

BEM (كتلة عنصر معدل)

/* منهجية شائعة للمشاريع الكبيرة */
/* الكتلة: اسم المكون */
.card { }

/* العنصر: جزء من الكتلة، مفصول بـ __ */
.card__title { }
.card__image { }
.card__body { }

/* المعدل: تنويع، مفصول بـ -- */
.card--featured { }
.card--compact { }
.card__title--large { }

CamelCase (أقل شيوعا في CSS)

/* أكثر شيوعا في JavaScript، يستخدم أحيانا في CSS */
.navBar { }
.heroSection { }
.cardTitle { }

اصطلاح kebab-case (كلمات مفصولة بشرطات) هو الأكثر استخداما في CSS لأنه سهل القراءة ومتسق مع أسماء خصائص CSS (التي كلها kebab-case مثل font-size و background-color) ومدعوم من كل نظام أدوات CSS. منهجية BEM (كتلة عنصر معدل) شائعة في المشاريع الأكبر لأنها تنشئ علاقة واضحة بين المكونات وأجزائها.

الأسماء الدلالية مقابل الأسماء العرضية

فضل دائما الأسماء الدلالية (ما هو العنصر أو ما يفعله) على الأسماء العرضية (ما يبدو عليه). الأسماء العرضية تنهار عندما تتغير التصاميم.

التسمية الدلالية مقابل العرضية

/* سيء: أسماء عرضية (تصف المظهر) */
.red-text { color: red; }
.big-font { font-size: 2rem; }
.left-box { float: left; width: 50%; }
.blue-button { background: blue; }

/* ماذا يحدث عندما يغير المصمم الزر إلى أخضر؟
   إما أن تعيد تسمية الفئة في كل مكان (مؤلم) أو يكون لديك
   فئة اسمها .blue-button لكنها في الواقع خضراء (محير). */

/* جيد: أسماء دلالية (تصف الغرض) */
.error-message { color: red; }
.page-title { font-size: 2rem; }
.sidebar { float: left; width: 50%; }
.btn-primary { background: blue; }

/* عندما يتغير اللون الأساسي إلى أخضر، يظل اسم الفئة
   منطقيا تماما. */

دمج أنواع المحددات

يمكنك دمج أنواع مختلفة من المحددات البسيطة لإنشاء قواعد أكثر استهدافا. عندما تكتب محددات معا بدون مسافة، فأنت تحدد شروطا متعددة يجب أن يستوفيها العنصر في وقت واحد.

دمج محددات النوع والفئة

/* فقط عناصر <p> مع فئة "intro" */
p.intro {
    font-size: 1.25rem;
    font-style: italic;
    color: #555;
}

/* فقط عناصر <a> مع فئة "nav-link" */
a.nav-link {
    text-decoration: none;
    padding: 8px 16px;
    color: #333;
}

/* فقط عناصر <input> مع فئة "large" */
input.large {
    font-size: 1.25rem;
    padding: 14px 18px;
}

/* فقط عناصر <div> مع فئة "container" */
div.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

دمج محددات النوع والسمات

/* فقط عناصر <input> مع type="text" */
input[type="text"] {
    border: 2px solid #ccc;
    border-radius: 4px;
}

/* فقط عناصر <a> مع href يبدأ بـ "https" */
a[href^="https"] {
    color: green;
    font-weight: bold;
}

/* فقط عناصر <img> مع سمة alt */
img[alt] {
    border: 2px solid transparent;
}

/* فقط عناصر <img> بدون سمة alt (فحص إمكانية الوصول) */
img:not([alt]) {
    border: 4px solid red;
    outline: 2px dashed red;
}

دمج شروط متعددة

/* <input> مع type="email" وفئة "large" وسمة required */
input[type="email"].large[required] {
    border: 2px solid #0066cc;
    font-size: 1.25rem;
    padding: 12px;
}

/* عناصر <a> مع فئة "btn" و href ينتهي بـ ".pdf" */
a.btn[href$=".pdf"] {
    background-color: #cc0000;
    color: white;
    padding: 8px 16px;
}
ملاحظة: عند دمج محددات النوع مع محددات الفئة أو السمات، يأتي محدد النوع دائما أولا: p.intro صحيح، بينما .intro p تعني شيئا مختلفا تماما (إنها مجمع سلالة يستهدف عناصر <p> داخل عنصر بفئة .intro). سنغطي المجمعات في درس لاحق.

نظرة عامة على خصوصية المحددات

لأنواع المحددات المختلفة أوزان خصوصية مختلفة، تحدد أي الأنماط تفوز عندما تستهدف قواعد متعددة نفس العنصر. إليك نظرة عامة سريعة على الخصوصية للمحددات التي غطيناها (سنستكشف الخصوصية بالتفصيل الكامل في درس مخصص):

  • المحدد العام (*) -- الخصوصية: 0-0-0 (بدون وزن)
  • محددات النوع (h1 و p و div) -- الخصوصية: 0-0-1
  • محددات الفئة (.card) -- الخصوصية: 0-1-0
  • محددات السمات ([type="text"]) -- الخصوصية: 0-1-0 (نفس الفئات)
  • محددات المعرف (#header) -- الخصوصية: 1-0-0

محدد الفئة أكثر تحديدا بعشر مرات من محدد النوع، ومحدد المعرف أكثر تحديدا بعشر مرات من محدد الفئة. عندما تتعارض قاعدتان، تفوز القاعدة ذات الخصوصية الأعلى، بغض النظر عن ترتيب المصدر.

الخصوصية عمليا

/* الخصوصية: 0-0-1 (محدد نوع) */
p {
    color: black;
}

/* الخصوصية: 0-1-0 (محدد فئة -- يفوز على النوع) */
.highlight {
    color: orange;
}

/* الخصوصية: 1-0-0 (محدد معرف -- يفوز على الفئة) */
#special-text {
    color: red;
}

/* بالنسبة لـ <p class="highlight" id="special-text">
   سيكون النص أحمر لأن #special-text له أعلى خصوصية */

أنماط عملية وأمثلة واقعية

دعنا نجمع كل شيء معا في مثال شامل يستخدم جميع أنواع المحددات التي غطيناها في سيناريو صفحة ويب واقعي.

مثال واقعي كامل

/* === إعادة التعيين العامة (المحدد العام) === */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* === الأنماط الأساسية (محددات النوع) === */
body {
    font-family: "Inter", -apple-system, sans-serif;
    color: #333;
    line-height: 1.6;
}

h1, h2, h3 {
    line-height: 1.3;
    margin-bottom: 0.75em;
}

a { color: #0066cc; text-decoration: none; }
a:hover { text-decoration: underline; }

img { max-width: 100%; height: auto; }

/* === أنماط المكونات (محددات الفئة) === */
.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

.nav-link {
    display: inline-block;
    padding: 8px 16px;
    color: #555;
    font-weight: 500;
}

.card {
    background: #fff;
    border: 1px solid #e5e5e5;
    border-radius: 8px;
    padding: 24px;
    margin-bottom: 20px;
}

.card.featured {
    border-color: gold;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}

.btn {
    display: inline-block;
    padding: 10px 24px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 1rem;
}

.btn.btn-primary { background: #0066cc; color: #fff; }
.btn.btn-secondary { background: #6c757d; color: #fff; }

/* === أنماط المعالم (محددات المعرف) === */
#site-header {
    position: sticky;
    top: 0;
    background: #fff;
    border-bottom: 1px solid #eee;
    z-index: 100;
}

/* === أنماط النماذج (محددات السمات) === */
[type="text"],
[type="email"],
[type="password"] {
    width: 100%;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 4px;
}

[required] {
    border-left: 3px solid #0066cc;
}

/* الروابط الخارجية تحصل على أيقونة */
a[href^="http"]:not([href*="mysite.com"]) {
    padding-right: 16px;
    background: url("external-icon.svg") no-repeat right center;
    background-size: 12px;
}

تمرين عملي 1: تحديد المحددات

انظر إلى قواعد CSS التالية وحدد نوع كل محدد. ثم حدد أي عناصر HTML ستطابقها كل قاعدة:

/* 1 */ article { border-bottom: 1px solid #eee; }
/* 2 */ .sidebar { width: 300px; float: right; }
/* 3 */ #main-content { flex: 1; }
/* 4 */ * { font-family: sans-serif; }
/* 5 */ [data-visible="true"] { display: block; }
/* 6 */ h1, h2, .section-title { color: navy; }
/* 7 */ input.search-box[type="text"] { border-radius: 20px; }
/* 8 */ a[href$=".pdf"] { color: red; }

الإجابات: (1) محدد نوع -- جميع عناصر <article>. (2) محدد فئة -- العناصر ذات class="sidebar". (3) محدد معرف -- العنصر ذو id="main-content". (4) المحدد العام -- كل عنصر. (5) محدد سمة (مطابقة دقيقة) -- العناصر ذات data-visible="true". (6) محددات مجمعة -- جميع عناصر <h1> و <h2> و .section-title. (7) دمج نوع + فئة + سمة -- عنصر <input> بفئة search-box و type="text". (8) محدد لاحقة السمة -- الروابط التي ينتهي href الخاص بها بـ .pdf.

تمرين عملي 2: بناء مكون منسق

أنشئ مكون إشعارات باستخدام تقنيات المحددات من هذا الدرس. اكتب كلا من HTML و CSS للمتطلبات التالية:

  • فئة أساسية .notification مع حشو وتدوير زوايا وهامش.
  • ثلاث فئات معدلة: .notification--success (أخضر) و .notification--warning (أصفر) و .notification--error (أحمر).
  • فئة .notification__title للعنوان داخل كل إشعار.
  • فئة .notification__message لنص المحتوى.
  • استخدم محدد السمة [data-dismissible="true"] لإضافة نمط زر الإغلاق.

حاول كتابة هذا بنفسك قبل النظر إلى أي حل. هذا التمرين يعزز تسمية الفئات باصطلاح BEM ومحددات السمات ودمج أنواع المحددات.

تمرين عملي 3: تحدي محددات السمات

اكتب قواعد CSS باستخدام محددات السمات فقط للسيناريوهات التالية:

  • نسق جميع الروابط التي تشير إلى مواقع خارجية (تلميح: تبدأ بـ http).
  • نسق جميع الروابط التي تشير إلى عناوين بريد إلكتروني (تلميح: تبدأ بـ mailto:).
  • نسق جميع الصور التي تحتوي على سمة alt بشكل مختلف عن تلك التي لا تحتوي عليها.
  • نسق حقول إدخال النماذج بناء على سمة type (text و email و password و checkbox).
  • نسق العناصر التي تحتوي على سمة data-status تحتوي على كلمة "active".

ES
Edrees Salih
منذ 10 ساعات

We are still cooking the magic in the way!