هل سبق لك أن حاولت تعمل override ل style معين لكن منجحتش؟ أنا عن نفسي حصل معايا مرات، ال cascade هي سبب في ده، في السلسلة دي هنتكلم عن إيه هي ال cascade وإيه القوانين إلي على أساسها يتقرر أي style هيتطبق.


تعريف نظري لل cascade

ال cascade هي الخوارزمية التي تحدد إيه ال style إلي element معين هيخدو لما يتم تنسيق هذا ال element بأكثر من طريقة. في مقال اليوم سنتكلم عن موضوعين بخصوص هذه الخوارزمية (الحدة specificity و الترتيب order).

ال specificity و order

اسمحلي أبدأ معك بسؤال، في نظرك لون الفقرة في الكود التالي هيكون إيه؟

  <div id="myId">
    <p class=”my-class”>
      أنا فقرة نصية باللغة العربية، حضرتك لوني إيه؟ 
    </p>
  </div>
div#myId .my-class {
    color: red;
  }

  div p {
    color: green;
  }

لو إجابتك "أخضر"، يبقى لازم تكمل معايا المقال للآخر.

النتيجة:

Cascade CSS Part 1

السبب إلي ممكن يدعوك تقول لون الفقرة أخضر هو لأن div p هو التالي في ال css إذن هيفوز على ال selector الفوق. وده صحيح، لكن لما تكون ال specificity تبع الإثنين متساوية، عندها بنرجع للترتيب الخاص ب ال selectors عشان نعرف مين ال style إلي العنصر ده هيخدو، اما لو ال specificity تبع أحد ال selectors أكثر من الآخر، الترتيب لا يؤخذ بعين الاعتبار.


كيف نحسب ال specificity؟

نلقي نظرة على ال selectors ونحسب:

  • كل id في ال selector بياخد 1,0,0
  • كل class أو pseudo-class أو attribute في ال selector بياخد 0,1,0
  • كل element أو pseudo element في ال selector بياخد 0,0,1

نرجع  للمثال السابق ونطبق عليه عشان نفهم الأرقام الغريبة دي:

  • في ال selector الأول div#myId .my-class عندنا واحد id وواحد class وكمان واحد element، إذن ال specificity تبع ال selector الأول هي 1,1,1
  • أما ال selector الثاني div p ف ال specificity تبعو هتكون 0,0,2 عشان كل element بياخد 0,0,1

بعدما عرفنا ال specificity تبع كل من الإثنين، عشان تقارن بينهم، تطبق القواعد التالية:

  • واحد id فقط بيفوز على أي عدد من classes أو ما جاورهم كال pseudo-classes وعلى أي عدد من ال elements أو ما جاورهم كال pseudo-elements.
  • واحد class بيفوز على أي عدد من ال elements أو ما جاورهم كال pseudo-elements.

وبهذا نكون عرفنا ليه ال selector الأول فاز على ال selector الثاني رغم انه قبلو في الترتيب.

💡
الأرقام الفوق مش أرقام بنظام العد العشري، يعني لو عندك عشر classes، ده لا يعني أنهم يساوي واحد id.

مثال:

  #one-id {
    color: red;
  } /* specificity: 1,0,0 */


  .class1.class2.class3.class4.class5.class6
  .class7.class8.class9.class10.class11 {
    color: blue;
  } /* specificity: 0,11,0 */

رقم واحد الثاني في 0,11,0  لا يحسب على خانة IDs كما كان ليحسب على خانة المئات في العدد 110 لذلك قلت الأرقام ليست بنظام العشري، وواحد id أقوى من أي عدد من ال classes.

Cascade CSS Part 1

بعدما تعلمنا كيف نحسب ال specificity خلينا ناخد عليها بعض الأمثلة سريعا عشان نعمق فهمنا للموضوع:

ul a { } /* 0,0,2 */
li a { } /* 0,0,2 */

تساوي في ال specificity، نحتكم للترتيب

box div { background-color: blue; } /* 1,0,1 */
div:hover { background-color: red; } /* 0,1,1 */

المثال ده مهم ولازم تاخد بالك منو، لون ال div في العادي أزرق وحتى تحت ال hover مش هيتغير، لأنو بعد كل حاجة ال hover ده pseudo-class بيخضع لقوانين ال specificity فلو هي أقل مش هيفوز وبالتالي ال style مش هيتطبق.

  main h2 {
    font-size: 60px;
  }
  @media (max-width: 300px) {
    h2 {
      font-size: 18px;
    }
  }

نفس الشيء، لازم ال specificity تبع ال selector داخل media  تكون أكبر عشان ال style يشتغل.

ملاحظات:

  • ال ()not: لا يضيف أي specificity ل selector بنفسه، لكن ما بين الأقواس بيضيف قيمة، مثلا قيمة ال specificity تبع (div:not(:first-child هي 0,1,1 مش 0,2,1، كيف؟ ال div هياخد 0,0,1 وال first-child هياخد 0,1,0 أما ال not فلا يضيف أي قيمة.
  • علامة * الخاصة بجميع elements ايضا لا تضيف أي specificity ل selector مثلا * li تساوي 0,0,1

في الختام

هذا كان الجزء الأول من كلامنا عن ال cascade، تكلمنا فيه عن ال specificity و order، في الجزء الثاني بإذن الله هنشوف هل في ما هو أقوى من ال specificity وهنتكلم عن محبوبة الملايين ال important! وإزاي بتقلب الموازين.