---
title: "نحو كود CSS أسهل في الصيانة"
description: "استخدام SCSS للحفاظ على كود CSS مرتبًا ونظيفًا."
canonical: https://oozou.com/ar/blog/towards-a-more-maintainable-css-19
locale: ar
date: 2015-03-03
author: "OOZOU Team"
---

# نحو كود CSS أسهل في الصيانة

> استخدام SCSS للحفاظ على كود CSS مرتبًا ونظيفًا.

Published: 2015-03-03 · Author: OOZOU Team (Engineering) · 10 min read

أطلقنا مؤخرًا الموقع الإلكتروني الجديد لـ Oozou. وبعد أن عملت على مشاريع (مشاريعي ومشاريع غيري، داخل Oozou وخارجها) فيها كود CSS ليس سهل الصيانة، أردت هذه المرة أن أجد طرقًا لكتابة CSS بأسلوب أسهل في الصيانة وأكثر قابلية للتوقع.

**مشكلة سهولة الصيانة**

لغة CSS مرنة جدًا، فهي لا تفرض عليكم طريقة معيّنة لتنظيم القواعد، لكن توزيع القواعد في أماكن مختلفة قد يجعل ملف الأنماط أقل قابلية للتوقع. وقد تنشأ مشكلات الصيانة حين تتداخل محددات CSS (selectors) وتتسلسل. وينطبق هذا أيضًا على معالجات CSS الأخرى مثل LESS وSass.

في بعض المشاريع، يتبع كود Sass بنية الـ DOM نفسها. فمثلًا، لبنية HTML هذه:

```
<div class="navbar">
  <ul>
    <li><a href="#">...</a></li>
  </ul>
</div>
lang-html
```

تأتي بنية SCSS هذه:

```
div.navbar {
  > ul {
    > li {
      > a {
        // ...
      }
    }
  }
}
lang-css
```

هذا ما أسمّيه "selectorception"، ويسمّيه موقع The Sass Way [كابوس محددات CSS](http://thesassway.com/beginner/the-inception-rule). أي أن تكون بنية CSS مرتبطة ارتباطًا وثيقًا بالـ DOM.

ولا يقتصر الأمر على تضخّم حجم الملف الناتج، بل يجعل إعادة استخدام المكوّن شبه مستحيلة. فإذا نُقل شيء في الـ markup، فلا بد من تغيير قواعد CSS أيضًا.

[
الإفراط في استخدام محددات ID](http://screwlewse.com/2010/07/dont-use-id-selectors-in-css/) قد يسبب أيضًا مشكلة في الصيانة، إذ قد نميل إلى كتابة قواعد محددة أكثر من اللازم. وبما أن المعرّف نفسه لا يُستخدم إلا لعنصر واحد، فلا يمكن إعادة استخدام هذه القواعد.

ومن الأمور الأخرى التي أراها ملفات CSS تزداد طولًا باستمرار، وبعضها يتجاوز 1000 سطر.

**بعض الإرشادات معقدة أكثر من اللازم**

قرأت بعض المقالات والمواقع عن جعل كود CSS سهل الصيانة، وهي مليئة بالمصطلحات مثل Base وBlock وElement وLayout وModifier وModule وPartial وState وTheme وغيرها. وأرى أنه _لا داعي لكل هذا التعقيد_.

لذلك، أثناء تطوير الموقع، حاولت أيضًا كتابة إرشادات لتنظيم CSS في المشروع، تقوم على فكرة المكوّنات. وقد استلهمتها جزئيًا من [إرشادات CSS في Medium](https://medium.com/@fat/mediums-css-is-actually-pretty-fucking-good-b8e2a6c78b06)، وهي المفضّلة لديّ.

**التفكير بالمكوّنات**

في الموقع الجديد، حاولت تبنّي فكرة المكوّنات. إذ يمكننا النظر إلى صفحة الويب على أنها مكوّنة من عدة مكوّنات. لنأخذ مثلًا قسم "Expertise" لدينا.

يتكوّن هذا القسم من ثلاثة مكوّنات:

- **expertise** هو قسم الخبرات بالكامل.
- **container** حاوية عامة تضمن قدرًا من الـ padding وتحدّ من الحجم.
- **expertise-item** عنصر خبرة واحد.**

التنسيق مقابل التخطيط**

لتسهيل إعادة استخدام المكوّن في مكان آخر، وجعل تخطيط CSS سهل الإدارة، علينا أن نفرّق بين _التنسيق_ (styling) و _التخطيط_ (layouting).

**التنسيق** يعني تغيير الألوان والخطوط والحدود والـ padding. ويحدث كل ذلك داخل حدود المكوّن، دون أن يتدخل في تخطيط المكوّنات الأخرى (باستثناء عرض العنصر وارتفاعه). فمثلًا، كل ما يلي يُعدّ تنسيقًا:

- background
- border
- color
- font
- padding
- text-align

**التخطيط** يعني تحريك العناصر وتحديد أحجامها، وقد يؤثر في العناصر المجاورة في الصفحة. فمثلًا، ما يلي يُعدّ تخطيطًا:

- clear
- float
- margin
- position
- transform
- top, right, bottom, left
- width, height

**لا يخطّط المكوّن لنفسه**

وإليكم القاعدة:

> _على المكوّن أن ينسّق نفسه، وأن يترك مهمة التخطيط لعنصره الأب._

أي أن المكوّن لا ينبغي أن يحمل margins خاصة به، أو أن يطفو (float) من تلقاء نفسه، بل على المكوّن الأب أن يتولى تخطيط أبنائه.

لننظر مرة أخرى إلى قسم Expertise والـ markup الخاص به:

```
<section class="expertise">
  <div class="container">
    <h2>Expertise</h2>
    <div class="expertise--contents">
      <div class="expertise--item-container">
        <div class="expertise-item expertise-item-m-icon-uxui">
          <h3>UI &amp; UX Design</h3>
          <p>Our designers can perfect the user<br>
             experience and make it look great.</p>
        </div>
      </div>
      <!-- Repeated 6 times -->
    </div>
  </div>
</section>
lang-html
```

فمثلًا، لن أكتب:

```
.expertise-item {
  margin-top: 80px;
}
lang-css
```

بل سأترك ذلك لقسم .expertise:

```
.expertise {
  .expertise-item {
    margin-top: 80px;
  }
}
lang-css
```

تسهّل هذه القاعدة بناء واجهة متجاوبة (responsive)، لأنها تجعل التخطيط أكثر قابلية للتوقع. فلا داعي للقلق بشأن ما إذا كان مكوّنان سيبدوان جيدين معًا على حجم شاشة معيّن، بل يكفي التأكد من أن العنصر الأب يخطّط لأبنائه بشكل مناسب:

```
.expertise {
  &--item-container {
    @include media(720px) {
      float: left;
      width: 50%;
    }
    @include media(960px) {
      width: 33.33%;
    }
  }
}
lang-css
```

ويتولى كل _expertise-item_ ضبط المسافة بين العنوان والنص (إضافة إلى تنسيقه الخاص).

```
.expertise-item {
  h3 {
    font-weight: normal;
    font-size: $font-size-medium;
    padding-bottom: 60px;
    margin-bottom: 30px;
    background: bottom center no-repeat;
  }
  p {
    font-family: $sans-serif;
    font-size: $font-size-small;
  }
}
lang-css
```

**إبقاء المكوّنات بسيطة**

**التقسيم إلى مكوّنات يمنع ظاهرة selectorception.** فإذا بدأ المكوّن يحتوي على أسطر كثيرة جدًا، أحاول فصل جزء منه في مكوّن مستقل.

لكن إن فصلت _كل شيء_، فسأقع في مشكلة كثرة المكوّنات، وهي عبء على الصيانة أيضًا. ولهذا لدينا أيضًا **المكوّنات الفرعية**.

في هذا المشروع، نسمّي المكوّن الفرعي باسم المكوّن الأب، مع شرطتين بينهما:

```
<footer class="footer">
  <div class="container">
    <div class="footer--brand">
      <a href="/">Oozou</a>
    </div>
    <div class="footer--copyright">
      &copy; 2014 Oozou
    </div>
  </div>
</footer>
lang-html
```

وهذا يوضح أن "brand" و "copyright" مكوّنان فرعيان من "footer". كما تضمن هذه التسمية ألا تتعارض مع المكوّنات الرئيسية، وهو أمر يحدث كثيرًا بحسب تجربتي.

وبمساعدة Sass، لا نحتاج إلى تكرار اسم المكوّن في ملفات الأنماط:

```
.footer {
  &--brand a {
    // ...
  }
  &--copyright {
    // ...
  }
}
lang-css
```

ولا يُسمح بتداخل المكوّنات الفرعية. فإذا أصبح مكوّن فرعي معقدًا لدرجة أنه يحتاج إلى مكوّنات فرعية خاصة به، فربما ينبغي أن يصبح مكوّنًا رئيسيًا!

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

**معدِّلات المكوّنات**

نحتاج أحيانًا إلى إضافة بعض المعدِّلات (modifiers) إلى المكوّن. وفي مشروعنا، نفعل ذلك بإضافة اسم المعدِّل مباشرة إلى HTML markup.

إليكم أنماط الأزرار لدينا:

وللحصول على زر رفيع بإطار خارجي فقط، نستخدم هذا الـ markup:

```
<a class="button button-m-outline button-m-thin">Button</a>
lang-html
```

**وراثة المكوّنات**

كما في التصميم كائني التوجه، يكون بعض المكوّنات أحيانًا حالة خاصة من مكوّن آخر. وإضافة مجموعة من classes المعدِّلات إلى HTML markup ستجعله مليئًا بالتكرار، وغير ملائم لإعادة الهيكلة (refactoring).

وبمساعدة Sass، يمكننا استخدام @extend لتوسيع مكوّنات أخرى. فمثلًا، مكوّن "expertise" لدينا هو في الواقع حالة خاصة من قسم معكوس الألوان. ويبدو كود CSS كالتالي:

```
.expertise {
  @extend .section;
  @extend .section-m-inverted;
  // ...
}
lang-css
```

لن أخوض في الجدل حول استخدام @mixin أو @extend. فهنا نستخدم @extend تقريبًا لوراثة المكوّنات فقط، وأرى أنها حالة استخدام مشروعة. وأعتقد أنه لا بأس باستخدام أيٍّ منهما ما دام ذلك بطريقة منضبطة.

ومن عيوب @extend أنها لا تعمل عبر ملفات CSS المولّدة المختلفة، ولا يمكن التوسيع من داخل استعلام @media. لكن إن اضطررتم إلى ذلك، فربما عليكم إعادة التفكير في بنية CSS لديكم.

**بنية الملفات**

العمل على ملفات CSS طويلة جدًا ليس ممتعًا. وفي هذا المشروع الذي يضم مكوّنات كثيرة شديدة التخصص، قاعدتنا هي: **مكوّن رئيسي واحد لكل ملف**.

بعض المشاريع بسيطة لدرجة أنه يمكن وضع كل CSS في ملف واحد. وفي مشاريع أخرى، قد يكون من الأنسب التنظيم بحسب الـ controller (الإعداد الافتراضي في Rails).

المهم أن تعيدوا الهيكلة بمجرد أن يصبح الوضع مزعجًا.

**بنية المجلدات**

العمل في مجلد stylesheets يضم 100 ملف ليس ممتعًا أيضًا، لذا لا بد من بعض التجميع. ولا أعتقد أن هناك بنية مجلدات واحدة تناسب كل المشاريع.

في حالة موقعنا، كل صفحة فريدة إلى حد كبير، وكثير من المكوّنات لا يُستخدم إلا في صفحة واحدة. لذلك من المنطقي أن نفصل ملفات CSS بحسب الصفحة. وبناءً عليه، تبدو بنية المجلدات لدينا كالتالي:

- base
- يحتوي على ملفات الأنماط الأساسية مثل resets وscaffolding (نستخدم [Bitters](http://bitters.bourbon.io/)).
- common
- يحتوي على المكوّنات المستخدمة في عدة صفحات.
- index
- يحتوي على CSS الخاص بالصفحة الرئيسية.
- work
- يحتوي على CSS الخاص بصفحة الأعمال.
- …

مرة أخرى، عليكم إيجاد بنية المجلدات الأنسب لمشروعكم. فبعض المشاريع بسيطة بما يكفي لوضع كل CSS في مجلد واحد (الإعداد الافتراضي في Rails). وفي بعضها قد تنظّمونها بحسب النوع، وفي أخرى بحسب حجم الشاشة أو نوع الوسائط.

**من الـ Wireframe إلى التصميم، ومن التصميم عودةً إلى الـ Wireframe**

حين نتسلّم تصميمًا مرئيًا من المصمم، يكون من المفيد أحيانًا الرجوع ورسم wireframe. لماذا؟

- **نظرة شاملة**: مع wireframe صغير، يمكنكم رؤية الصفحة كلها بنظرة واحدة، فلا تنشغلون كثيرًا بالأجزاء الصغيرة منها.
- **تسمية وتقسيم أفضل للمكوّنات**: رؤية الصفحة كلها بنظرة واحدة تسهّل عليكم تسمية كل قسم.
- **البنية والتسلسل الهرمي**: يصبح تقسيم الصفحة إلى أقسام وأقسام فرعية أسهل حين يكون لديكم wireframe.
- **الهوامش** يتيح لكم الـ wireframe أيضًا التخطيط لاستخدام الـ margins والـ paddings بكفاءة أكبر.**

عن التصميم المتجاوب**

كنت أستخدم نقاط توقف (breakpoints) محددة مسبقًا للشاشات _الصغيرة_ و _المتوسطة_ و _الكبيرة_ (وهي تأتي مع [Bitters](http://bitters.bourbon.io/)). أما الآن، [فأنشئ نقاط التوقف بحسب المحتوى](http://responsivedesign.is/articles/why-you-dont-need-device-specific-breakpoints)، وهذا يضمن أن يبدو الموقع جيدًا على كل أحجام الشاشات.

ابدأوا من أكبر حجم شاشة (أو أصغره)، وغيّروا حجم النافذة ببطء. وكلما بدأ مكوّن ما يبدو غريبًا أو غير مريح، فكّروا في كيفية تحسين مظهره قليلًا، وأنشئوا نقطة توقف عند ذلك الحجم. وكرّروا ذلك حتى تصلوا إلى أصغر (أو أكبر) حجم شاشة تريدون دعمه (في حالتنا 320px).

**استخدام المحددات**

ينبغي أيضًا تحديد طريقة كتابة المحددات. وفي موقعنا نستخدم ما يشبه التالي:

- .component-name
- .component-name--subcomponent-name
- .component-name-m-modifier-name
- .u-clearfix (أداة مساعدة)
- .js-google-maps (لـ JavaScript)

**لكل قاعدة استثناء، وهذه القاعدة ليست استثناءً**

كما هو الحال مع كل أدلة الأسلوب، لا ينبغي اتباعها بشكل أعمى. فكثيرًا ما أخالف هذه القواعد بحسب كل حالة، وأحيانًا أغيّر القواعد نفسها لتبقى مناسبة للمشروع.

**الخلاصة**

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

علّمني العمل على الموقع الجديد للشركة كيف أكتب ملفات أنماط أسهل في الصيانة وأكثر قابلية للتوقع، من خلال:

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

---

Contact OOZOU: hello@oozou.com · +66 2544 0000 · https://oozou.com/ar/contact

More for AI agents: https://oozou.com/llms.txt · every page has a markdown twin at its URL plus ".md"
