معالج SASS/SCSS

محدد الأب (&)

20 دقيقة الدرس 6 من 30

محدد الأب (&) في SASS

يعتبر محدد الأب (&) واحداً من أقوى وأكثر ميزات SASS استخداماً. يتيح لك الإشارة إلى المحدد الأب في القواعد المتداخلة، مما يمكّنك من كتابة CSS أكثر إيجازاً وقابلية للصيانة. فهم محدد الأب أمر حاسم لإتقان SASS.

ما هو محدد الأب (&)؟

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

مثال أساسي على محدد الأب

// SCSS
.button {
  background: blue;
  color: white;

  &:hover {
    background: darkblue;
  }
}

// CSS المترجم
.button {
  background: blue;
  color: white;
}

.button:hover {
  background: darkblue;
}
ملاحظة: يتم استبدال & بالمحدد الأب بالضبط، بما في ذلك أي أصناف أو معرفات أو محددات أخرى. لا يضيف مسافة فقط - بل يدمج مباشرة.

استخدام & مع الأصناف الوهمية

أحد الاستخدامات الأكثر شيوعاً لمحدد الأب هو مع الأصناف الوهمية مثل :hover و :focus و :active و :visited وغيرها. هذا يحافظ على الحالات المرتبطة معاً في الكود الخاص بك.

أصناف وهمية متعددة

// SCSS
.link {
  color: blue;
  text-decoration: none;
  transition: all 0.3s ease;

  &:hover {
    color: darkblue;
    text-decoration: underline;
  }

  &:focus {
    outline: 2px solid blue;
    outline-offset: 2px;
  }

  &:active {
    color: navy;
    transform: translateY(1px);
  }

  &:visited {
    color: purple;
  }
}

// CSS المترجم
.link {
  color: blue;
  text-decoration: none;
  transition: all 0.3s ease;
}

.link:hover {
  color: darkblue;
  text-decoration: underline;
}

.link:focus {
  outline: 2px solid blue;
  outline-offset: 2px;
}

.link:active {
  color: navy;
  transform: translateY(1px);
}

.link:visited {
  color: purple;
}

استخدام & مع العناصر الوهمية

يعمل محدد الأب بسلاسة مع العناصر الوهمية (::before و ::after و ::first-letter وما إلى ذلك). هذا مثالي لإضافة عناصر زخرفية أو أيقونات.

مثال على العناصر الوهمية

// SCSS
.quote {
  position: relative;
  padding: 20px 40px;
  font-style: italic;

  &::before {
    content: """;
    position: absolute;
    left: 10px;
    top: 0;
    font-size: 60px;
    color: #ccc;
    font-family: Georgia, serif;
  }

  &::after {
    content: """;
    position: absolute;
    right: 10px;
    bottom: -40px;
    font-size: 60px;
    color: #ccc;
    font-family: Georgia, serif;
  }
}

// CSS المترجم
.quote {
  position: relative;
  padding: 20px 40px;
  font-style: italic;
}

.quote::before {
  content: """;
  position: absolute;
  left: 10px;
  top: 0;
  font-size: 60px;
  color: #ccc;
  font-family: Georgia, serif;
}

.quote::after {
  content: """;
  position: absolute;
  right: 10px;
  bottom: -40px;
  font-size: 60px;
  color: #ccc;
  font-family: Georgia, serif;
}

اصطلاح التسمية BEM (Block Element Modifier)

محدد الأب مثالي لكتابة CSS بأسلوب BEM. BEM هي منهجية تسمية تساعدك على إنشاء مكونات قابلة لإعادة الاستخدام وتجنب تعارضات التسمية.

بنية BEM: Block__Element--Modifier. على سبيل المثال: .card__title--large

BEM مع محدد الأب

// SCSS
.card {
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);

  // العنصر: card__header
  &__header {
    border-bottom: 1px solid #eee;
    margin-bottom: 15px;
    padding-bottom: 15px;
  }

  // العنصر: card__title
  &__title {
    font-size: 24px;
    font-weight: bold;
    margin: 0;
    color: #333;

    // المعدل: card__title--small
    &--small {
      font-size: 18px;
    }

    // المعدل: card__title--large
    &--large {
      font-size: 32px;
    }
  }

  // العنصر: card__body
  &__body {
    color: #666;
    line-height: 1.6;
  }

  // العنصر: card__footer
  &__footer {
    margin-top: 15px;
    padding-top: 15px;
    border-top: 1px solid #eee;
  }

  // المعدل: card--featured
  &--featured {
    border: 3px solid gold;
    box-shadow: 0 4px 12px rgba(255,215,0,0.3);
  }

  // المعدل: card--dark
  &--dark {
    background: #333;
    color: white;

    .card__title {
      color: white;
    }

    .card__body {
      color: #ccc;
    }
  }
}

// CSS المترجم
.card {
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.card__header {
  border-bottom: 1px solid #eee;
  margin-bottom: 15px;
  padding-bottom: 15px;
}

.card__title {
  font-size: 24px;
  font-weight: bold;
  margin: 0;
  color: #333;
}

.card__title--small {
  font-size: 18px;
}

.card__title--large {
  font-size: 32px;
}

/* ... وهكذا ... */

استخدام & مع محددات الأشقاء

يمكن استخدام محدد الأب مع محددات الأشقاء (+، ~) لتنسيق العناصر بناءً على أشقائها. هذا مفيد لإنشاء أنظمة التباعد أو تنسيق القوائم.

محدد الشقيق المجاور (+)

// SCSS
.item {
  padding: 10px;
  border-bottom: 1px solid #ddd;

  // تنسيق العناصر التي تأتي مباشرة بعد عنصر آخر
  & + & {
    margin-top: 10px;
  }
}

// CSS المترجم
.item {
  padding: 10px;
  border-bottom: 1px solid #ddd;
}

.item + .item {
  margin-top: 10px;
}

محدد الشقيق العام (~)

// SCSS
.alert {
  padding: 15px;
  border-radius: 4px;
  margin-bottom: 10px;

  // تنسيق جميع التنبيهات بعد الأول
  & ~ & {
    opacity: 0.8;
  }

  &.alert-error {
    background: #fee;
    border: 1px solid #fcc;
    color: #c33;
  }

  &.alert-success {
    background: #efe;
    border: 1px solid #cfc;
    color: #3c3;
  }
}

// CSS المترجم
.alert {
  padding: 15px;
  border-radius: 4px;
  margin-bottom: 10px;
}

.alert ~ .alert {
  opacity: 0.8;
}

.alert.alert-error {
  background: #fee;
  border: 1px solid #fcc;
  color: #c33;
}

.alert.alert-success {
  background: #efe;
  border: 1px solid #cfc;
  color: #3c3;
}

الإضافة إلى الأب (اللواحق)

يمكنك إضافة سلاسل نصية إلى محدد الأب بوضع & قبل النص. هذا مفيد لإنشاء أشكال مختلفة أو أصناف حالة.

نمط اللاحقة

// SCSS
.button {
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;

  // ينشئ .button-primary
  &-primary {
    background: blue;
    color: white;
  }

  // ينشئ .button-secondary
  &-secondary {
    background: gray;
    color: white;
  }

  // ينشئ .button-large
  &-large {
    padding: 15px 30px;
    font-size: 18px;
  }

  // ينشئ .button-small
  &-small {
    padding: 5px 10px;
    font-size: 12px;
  }
}

// CSS المترجم
.button {
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.button-primary {
  background: blue;
  color: white;
}

.button-secondary {
  background: gray;
  color: white;
}

.button-large {
  padding: 15px 30px;
  font-size: 18px;
}

.button-small {
  padding: 5px 10px;
  font-size: 12px;
}

محدد الأب في المحددات المركبة

يمكن دمج محدد الأب مع محددات أخرى لإنشاء قواعد معقدة. هذا مفيد للتنسيق بناءً على حالات الأب أو السياقات.

التنسيق القائم على السياق

// SCSS
.nav-item {
  padding: 10px 15px;
  color: #333;

  // عندما يكون داخل .navbar-dark
  .navbar-dark & {
    color: white;
  }

  // عندما يكون داخل .sidebar
  .sidebar & {
    display: block;
    border-bottom: 1px solid #eee;
  }

  // عندما يحتوي body على صنف .mobile
  body.mobile & {
    padding: 15px;
    font-size: 16px;
  }
}

// CSS المترجم
.nav-item {
  padding: 10px 15px;
  color: #333;
}

.navbar-dark .nav-item {
  color: white;
}

.sidebar .nav-item {
  display: block;
  border-bottom: 1px solid #eee;
}

body.mobile .nav-item {
  padding: 15px;
  font-size: 16px;
}
نصيحة: عندما يظهر & في أي مكان باستثناء بداية المحدد، فإنه يمثل محدد الأب في ذلك الموضع. هذا مفيد بشكل لا يصدق للتصميم والتنسيق الخاص بالسياق.

أنماط محدد الأب المتقدمة

مراجع أب متعددة

// SCSS
.button {
  background: blue;
  color: white;
  padding: 10px 20px;

  &:hover {
    background: darkblue;
  }

  &:active,
  &:focus {
    outline: 2px solid lightblue;
    outline-offset: 2px;
  }

  // حالة معطلة
  &[disabled],
  &.disabled,
  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
  }

  // عندما يكون الزر داخل نموذج قيد الإرسال
  .form--submitting & {
    opacity: 0.6;

    &::after {
      content: "...";
      margin-left: 5px;
    }
  }
}

// يتضمن CSS المترجم كل هذه الأشكال...

الأخطاء الشائعة والتنبيهات

تحذير: لا يمكن استخدام محدد الأب لإنشاء محددات أب جديدة في منتصف محدد مركب. على سبيل المثال، .foo & .bar لا يعمل كما قد تتوقع.

ما لا يجب فعله

// خطأ - هذا لن يعمل
.parent {
  .child & .grandchild {
    // خطأ: لا يمكن استخدام محدد الأب هنا
  }
}

// صحيح - ضع & في البداية أو النهاية
.parent {
  .outer & {
    .grandchild {
      // هذا يعمل
    }
  }
}

الترتيب مهم

// SCSS
.button {
  // هذا ينشئ .button:hover.active
  &:hover&.active {
    background: green;
  }

  // هذا ينشئ .button.active:hover
  &.active&:hover {
    background: red;
  }
}

// في CSS، هذه في الواقع متكافئة،
// لكن معرفة الترتيب يساعد في قابلية القراءة

مثال من العالم الحقيقي: قائمة التنقل

مكون تنقل كامل

// SCSS
.nav {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  background: #333;

  &__item {
    position: relative;

    // إضافة فاصل بين العناصر
    & + & {
      &::before {
        content: "";
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        height: 20px;
        width: 1px;
        background: rgba(255,255,255,0.2);
      }
    }
  }

  &__link {
    display: block;
    padding: 15px 20px;
    color: white;
    text-decoration: none;
    transition: all 0.3s ease;

    &:hover {
      background: rgba(255,255,255,0.1);
      color: #ffd700;
    }

    &:focus {
      outline: 2px solid #ffd700;
      outline-offset: -2px;
    }

    &--active {
      background: rgba(255,255,255,0.15);
      font-weight: bold;

      &::after {
        content: "";
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 3px;
        background: #ffd700;
      }
    }
  }

  &--vertical {
    flex-direction: column;

    .nav__item + .nav__item::before {
      display: none;
    }

    .nav__link {
      border-bottom: 1px solid rgba(255,255,255,0.1);
    }
  }

  &--light {
    background: white;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);

    .nav__link {
      color: #333;

      &:hover {
        background: #f5f5f5;
        color: blue;
      }

      &--active::after {
        background: blue;
      }
    }
  }
}

// الاستخدام في HTML:
// <nav class="nav">
//   <div class="nav__item">
//     <a href="#" class="nav__link nav__link--active">الرئيسية</a>
//   </div>
//   <div class="nav__item">
//     <a href="#" class="nav__link">من نحن</a>
//   </div>
// </nav>

تمرين 1: إنشاء مكون بطاقة باستخدام محدد الأب

أنشئ مكون بطاقة باستخدام محدد الأب يتضمن:

  • صنف .card الأساسي مع حشوة وحدود
  • عناصر BEM: __header و __title و __body و __footer
  • معدلات: --featured (مع حدود ذهبية)، --compact (حشوة أقل)
  • حالة تحويم ترفع البطاقة قليلاً
  • استخدم محدد الأشقاء لإضافة تباعد بين بطاقات متعددة

تمرين 2: بناء نظام أزرار

أنشئ نظام أزرار شامل مع:

  • صنف .btn الأساسي
  • أشكال مختلفة باستخدام نمط اللاحقة: -primary و -secondary و -danger و -success
  • أحجام باستخدام معدلات BEM: --small و --large
  • حالات: :hover و :active و :focus و :disabled
  • حالة تحميل باستخدام محدد الأب والعنصر الوهمي ::after

تمرين 3: مكون يدرك السمة

أنشئ مكوناً يتكيف مع سمات مختلفة:

  • أنشئ مكون .message
  • استخدم محدد الأب لتنسيقه بشكل مختلف عندما يكون داخل .theme-dark
  • استخدم محدد الأب لتنسيقه بشكل مختلف عندما يكون داخل .theme-light
  • أضف أيقونة باستخدام العنصر الوهمي ::before
  • قم بتضمين أشكال مختلفة لرسائل النجاح والخطأ والتحذير