معالج SASS/SCSS

بنية SASS: نمط 7-1

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

بنية SASS: نمط 7-1

مع نمو المشاريع في التعقيد، يصبح تنظيم ملفات SASS أمراً بالغ الأهمية لسهولة الصيانة وقابلية التوسع. نمط 7-1 هو واحد من أكثر الأساليب المعمارية شعبية لهيكلة مشاريع SASS واسعة النطاق. في هذا الدرس الشامل، سنستكشف كيفية تطبيق هذا النمط القوي بفعالية.

لماذا تهم البنية في المشاريع الكبيرة

بدون استراتيجية معمارية واضحة، تصبح مشاريع SASS غير قابلة للإدارة بسرعة:

  • فوضى الملفات: مئات الأنماط مخلوطة معاً في بضعة ملفات ضخمة
  • تعارضات التسمية: أسماء فئات مكررة تسبب تجاوزات أنماط غير متوقعة
  • كوابيس التصحيح: عدم القدرة على إيجاد حيث يتم تعريف أنماط معينة
  • ارتباك الفريق: المطورون غير متأكدين من أين يضيفون أنماط جديدة
  • مشاكل الأداء: تحميل CSS غير ضروري لكل صفحة
  • مشاكل قابلية التوسع: إضافة ميزات جديدة تكسر الأنماط الموجودة
ملاحظة: البنية الجيدة مثل المكتبة المنظمة جيداً. كل ملف له مكانه، مما يسهل العثور على ما تحتاجه ومعرفة أين تضيف محتوى جديد.

فوائد نمط 7-1

  • تنظيم واضح: كل ملف له غرض وموقع محدد
  • تنقل سهل: العثور على أي قاعدة أنماط بسرعة
  • صديق للفريق: يمكن لمطورين متعددين العمل في وقت واحد دون تعارضات
  • قابل للصيانة: التغييرات معزولة ويمكن التنبؤ بها
  • قابل للتوسع: سهل إضافة ميزات جديدة دون إعادة هيكلة
  • أفضل الممارسات: نهج معياري في الصناعة تستخدمه المشاريع الكبرى

بنية نمط 7-1

يأتي اسم "7-1" من وجود 7 مجلدات للملفات الجزئية وملف رئيسي واحد يستورد كل شيء:

بنية مجلد 7-1 الكاملة

scss/
├── abstracts/
│   ├── _variables.scss
│   ├── _functions.scss
│   ├── _mixins.scss
│   └── _placeholders.scss
├── base/
│   ├── _reset.scss
│   ├── _typography.scss
│   ├── _animations.scss
│   └── _utilities.scss
├── components/
│   ├── _buttons.scss
│   ├── _cards.scss
│   ├── _forms.scss
│   ├── _modals.scss
│   ├── _navigation.scss
│   ├── _dropdown.scss
│   ├── _tabs.scss
│   └── _carousel.scss
├── layout/
│   ├── _header.scss
│   ├── _footer.scss
│   ├── _sidebar.scss
│   ├── _grid.scss
│   └── _navigation.scss
├── pages/
│   ├── _home.scss
│   ├── _about.scss
│   ├── _contact.scss
│   └── _product.scss
├── themes/
│   ├── _light.scss
│   ├── _dark.scss
│   └── _admin.scss
├── vendors/
│   ├── _bootstrap.scss
│   ├── _normalize.scss
│   └── _jquery-ui.scss
└── main.scss  ← الملف الرئيسي الوحيد
نصيحة: جميع الملفات باستثناء main.scss تبدأ بشرطة سفلية (_). هذا يخبر SASS أن هذه "أجزاء" لا يجب تجميعها إلى ملفات CSS منفصلة.

المجلد 1: abstracts/

مجلد abstracts/ (يسمى أحياناً helpers/ أو utilities/) يحتوي على أدوات ومساعدات SASS التي لا تخرج أي CSS بذاتها.

_variables.scss

احفظ جميع متغيرات المشروع في مكان واحد:

abstracts/_variables.scss

// لوحة الألوان
$color-primary: #3498db;
$color-secondary: #2ecc71;
$color-accent: #e74c3c;
$color-text: #333;
$color-background: #fff;

// الطباعة
$font-family-base: "Helvetica Neue", Arial, sans-serif;
$font-family-heading: "Georgia", serif;
$font-size-base: 16px;
$line-height-base: 1.6;

// المسافات
$spacing-unit: 8px;
$spacing-xs: $spacing-unit;
$spacing-sm: $spacing-unit * 2;
$spacing-md: $spacing-unit * 3;
$spacing-lg: $spacing-unit * 4;
$spacing-xl: $spacing-unit * 6;

// نقاط الانقطاع
$breakpoint-mobile: 480px;
$breakpoint-tablet: 768px;
$breakpoint-desktop: 1024px;
$breakpoint-wide: 1280px;

// مقياس Z-index
$z-index-dropdown: 100;
$z-index-modal: 200;
$z-index-popover: 300;
$z-index-tooltip: 400;

// الانتقالات
$transition-speed: 0.3s;
$transition-easing: ease-in-out;

_mixins.scss

قطع أنماط قابلة لإعادة الاستخدام يمكن أن تقبل معاملات:

abstracts/_mixins.scss

// Mixin نقطة انقطاع متجاوبة
@mixin respond-to($breakpoint) {
    @if $breakpoint == mobile {
        @media (max-width: $breakpoint-mobile) { @content; }
    }
    @else if $breakpoint == tablet {
        @media (min-width: $breakpoint-tablet) { @content; }
    }
    @else if $breakpoint == desktop {
        @media (min-width: $breakpoint-desktop) { @content; }
    }
}

// Mixin توسيط Flexbox
@mixin flex-center {
    display: flex;
    justify-content: center;
    align-items: center;
}

// Mixin متغير الزر
@mixin button-variant($bg-color, $text-color) {
    background-color: $bg-color;
    color: $text-color;
    border: 1px solid darken($bg-color, 10%);

    &:hover {
        background-color: darken($bg-color, 8%);
    }

    &:active {
        background-color: darken($bg-color, 12%);
    }
}

// Mixin ظل البطاقة
@mixin card-shadow($level: 1) {
    @if $level == 1 {
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    } @else if $level == 2 {
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
    } @else if $level == 3 {
        box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
    }
}

// Mixin Clearfix
@mixin clearfix {
    &::after {
        content: "";
        display: table;
        clear: both;
    }
}

_functions.scss

دوال SASS مخصصة للحسابات والتحويلات:

abstracts/_functions.scss

// تحويل البكسلات إلى rem
@function px-to-rem($px, $base: $font-size-base) {
    @return ($px / $base) * 1rem;
}

// حساب المسافة بناءً على الوحدة
@function spacing($multiplier) {
    @return $spacing-unit * $multiplier;
}

// الحصول على لون من اللوحة مع صبغة/ظل
@function color-level($color, $level) {
    @if $level > 0 {
        @return lighten($color, $level * 10%);
    } @else if $level < 0 {
        @return darken($color, abs($level) * 10%);
    } @else {
        @return $color;
    }
}

// حساب لون النص الأمثل (فاتح أو غامق) بناءً على الخلفية
@function text-contrast($background-color) {
    $lightness: lightness($background-color);

    @if $lightness > 50% {
        @return #000;
    } @else {
        @return #fff;
    }
}

_placeholders.scss

أنماط قابلة لإعادة الاستخدام باستخدام @extend:

abstracts/_placeholders.scss

// مخفي بصرياً ولكن يمكن الوصول إليه بواسطة قارئات الشاشة
%visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    border: 0;
}

// إعادة تعيين أنماط القائمة
%list-reset {
    margin: 0;
    padding: 0;
    list-style: none;
}

// أنماط الزر الشائعة
%button-base {
    display: inline-block;
    padding: 0.5rem 1rem;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: all $transition-speed $transition-easing;
    text-decoration: none;
    text-align: center;
}

// أنماط البطاقة الأساسية
%card-base {
    background: $color-background;
    border-radius: 8px;
    padding: 1.5rem;
    @include card-shadow(1);
}

المجلد 2: base/

مجلد base/ يحتوي على أنماط القالب والأساسية التي تنطبق في جميع أنحاء الموقع.

_reset.scss

base/_reset.scss

// إعادة تعيين CSS حديثة
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    font-size: 100%;
    -webkit-text-size-adjust: 100%;
}

body {
    line-height: $line-height-base;
    font-family: $font-family-base;
    color: $color-text;
    background-color: $color-background;
}

img, picture, video, canvas, svg {
    display: block;
    max-width: 100%;
    height: auto;
}

a {
    color: inherit;
    text-decoration: none;
}

button {
    font: inherit;
}

_typography.scss

base/_typography.scss

// العناوين
h1, h2, h3, h4, h5, h6 {
    font-family: $font-family-heading;
    font-weight: 700;
    line-height: 1.2;
    margin-bottom: spacing(2);
}

h1 { font-size: px-to-rem(40px); }
h2 { font-size: px-to-rem(32px); }
h3 { font-size: px-to-rem(28px); }
h4 { font-size: px-to-rem(24px); }
h5 { font-size: px-to-rem(20px); }
h6 { font-size: px-to-rem(18px); }

// الفقرات
p {
    margin-bottom: spacing(2);

    &:last-child {
        margin-bottom: 0;
    }
}

// الروابط
a {
    color: $color-primary;
    transition: color $transition-speed;

    &:hover {
        color: darken($color-primary, 15%);
    }
}

// القوائم
ul, ol {
    margin-bottom: spacing(2);
    padding-left: spacing(3);
}

// التأكيد
strong, b {
    font-weight: 700;
}

em, i {
    font-style: italic;
}

المجلد 3: components/

مجلد components/ يحتوي على أنماط لمكونات واجهة المستخدم الفردية القابلة لإعادة الاستخدام.

components/_buttons.scss

.btn {
    @extend %button-base;

    &--primary {
        @include button-variant($color-primary, #fff);
    }

    &--secondary {
        @include button-variant($color-secondary, #fff);
    }

    &--outline {
        background: transparent;
        color: $color-primary;
        border: 2px solid $color-primary;

        &:hover {
            background: $color-primary;
            color: #fff;
        }
    }

    &--large {
        padding: 0.75rem 1.5rem;
        font-size: px-to-rem(18px);
    }

    &--small {
        padding: 0.25rem 0.5rem;
        font-size: px-to-rem(14px);
    }
}

components/_cards.scss

.card {
    @extend %card-base;

    &__header {
        padding-bottom: spacing(2);
        border-bottom: 1px solid #eee;
        margin-bottom: spacing(2);
    }

    &__title {
        font-size: px-to-rem(20px);
        margin-bottom: spacing(1);
    }

    &__body {
        margin-bottom: spacing(2);
    }

    &__footer {
        padding-top: spacing(2);
        border-top: 1px solid #eee;
    }

    &--featured {
        border: 2px solid $color-primary;
        @include card-shadow(2);
    }

    &--interactive {
        transition: transform $transition-speed, box-shadow $transition-speed;

        &:hover {
            transform: translateY(-4px);
            @include card-shadow(3);
        }
    }
}

المجلد 4: layout/

مجلد layout/ يحتوي على أنماط للمكونات الهيكلية الرئيسية للصفحة.

layout/_header.scss

.header {
    background: $color-primary;
    color: #fff;
    padding: spacing(2) 0;
    position: sticky;
    top: 0;
    z-index: $z-index-dropdown;

    &__container {
        max-width: $breakpoint-wide;
        margin: 0 auto;
        padding: 0 spacing(2);
        @include flex-center;
        justify-content: space-between;
    }

    &__logo {
        font-size: px-to-rem(24px);
        font-weight: bold;
    }

    &__nav {
        @extend %list-reset;
        display: flex;
        gap: spacing(3);
    }
}

layout/_grid.scss

.container {
    max-width: $breakpoint-wide;
    margin: 0 auto;
    padding: 0 spacing(2);

    &--fluid {
        max-width: none;
    }
}

.row {
    display: flex;
    flex-wrap: wrap;
    margin: 0 spacing(-1);
}

.col {
    flex: 1;
    padding: 0 spacing(1);

    @for $i from 1 through 12 {
        &--#{$i} {
            flex: 0 0 percentage($i / 12);
            max-width: percentage($i / 12);
        }
    }
}

المجلد 5: pages/

مجلد pages/ يحتوي على أنماط خاصة بالصفحات.

pages/_home.scss

.home {
    &__hero {
        background: linear-gradient(135deg, $color-primary, $color-secondary);
        color: #fff;
        padding: spacing(8) 0;
        text-align: center;

        h1 {
            font-size: px-to-rem(48px);
            margin-bottom: spacing(3);
        }
    }

    &__features {
        padding: spacing(6) 0;
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
        gap: spacing(4);
    }

    &__cta {
        background: $color-accent;
        color: #fff;
        padding: spacing(6) 0;
        text-align: center;
    }
}

المجلد 6: themes/

مجلد themes/ يحتوي على تنوعات الثيمات المختلفة.

themes/_dark.scss

.theme-dark {
    --color-text: #fff;
    --color-background: #1a1a1a;
    --color-surface: #2a2a2a;

    background: var(--color-background);
    color: var(--color-text);

    .card {
        background: var(--color-surface);
        color: var(--color-text);
    }

    a {
        color: lighten($color-primary, 20%);
    }
}

المجلد 7: vendors/

مجلد vendors/ يحتوي على CSS خاص بطرف ثالث وتجاوزات.

vendors/_normalize.scss

// استيراد normalize.css أو أنماط بائعين آخرين
@import "normalize.css/normalize";

// تجاوز أنماط البائعين إذا لزم الأمر
.third-party-widget {
    // تجاوزات مخصصة
}

الملف الرئيسي: main.scss

هذا هو الملف الوحيد الذي يستورد كل شيء بالترتيب الصحيح:

main.scss - ملف البيان

// التكوين والمساعدات
@use "abstracts/variables" as *;
@use "abstracts/functions" as *;
@use "abstracts/mixins" as *;
@use "abstracts/placeholders" as *;

// البائعون (أنماط الطرف الثالث)
@use "vendors/normalize";

// الأنماط الأساسية
@use "base/reset";
@use "base/typography";
@use "base/animations";

// أقسام متعلقة بالتخطيط
@use "layout/header";
@use "layout/footer";
@use "layout/sidebar";
@use "layout/grid";

// المكونات
@use "components/buttons";
@use "components/cards";
@use "components/forms";
@use "components/modals";
@use "components/navigation";

// أنماط خاصة بالصفحات
@use "pages/home";
@use "pages/about";
@use "pages/contact";

// الثيمات
@use "themes/light";
@use "themes/dark";
ملاحظة: الترتيب مهم! يجب أن تأتي المتغيرات والدوال أولاً، ثم الأنماط الأساسية، ثم المكونات. هذا يضمن أن كل شيء متاح عند الحاجة.

متى تستخدم 7-1 مقابل البنى الأبسط

استخدم 7-1 عندما:

  • يحتوي مشروعك على 50+ مكون
  • يعمل مطورون متعددون على قاعدة الكود
  • سيتم صيانة المشروع على المدى الطويل
  • تحتاج إلى ثيمات متعددة أو أنماط خاصة بالصفحات
  • التطبيق كبير ومعقد

استخدم بنية أبسط عندما:

  • مشاريع صغيرة (صفحات هبوط، مواقع بسيطة)
  • مشاريع مطور واحد
  • نماذج أولية أو MVPs
  • مشاريع بأقل من 20 مكون

بنية أبسط للمشاريع الصغيرة

scss/
├── _variables.scss
├── _mixins.scss
├── _base.scss
├── _components.scss
├── _layout.scss
└── main.scss

تمرين 1: إعداد بنية 7-1

أنشئ بنية مجلد 7-1 كاملة لموقع تجارة إلكترونية وهمي:

  • أنشئ جميع المجلدات السبعة بملفات مناسبة
  • أعد main.scss بالاستيرادات المناسبة
  • أنشئ متغيرات للألوان والمسافات ونقاط الانقطاع
  • اكتب 3 mixins على الأقل (متجاوب، flex-center، button-variant)
  • أنشئ مكونات لـ: الأزرار، بطاقات المنتج، والتنقل
  • أنشئ أنماط خاصة بالصفحة الرئيسية وصفحات المنتج

تمرين 2: إعادة هيكلة CSS موجود إلى 7-1

خذ ملف CSS موجود وأعد هيكلته باستخدام بنية 7-1:

  • حدد أي الأنماط تنتمي إلى أي مجلد
  • استخرج متغيرات قابلة لإعادة الاستخدام من القيم المرمزة
  • حول الأنماط المتكررة إلى mixins
  • افصل الأنماط الأساسية والمكونات والتخطيط
  • أنشئ بنية المجلد المناسبة وانقل الأنماط
  • اختبر أن كل شيء يترجم بشكل صحيح

تمرين 3: بناء نظام ثيمات

نفذ نظام ثيمات متعددة باستخدام بنية 7-1:

  • أنشئ ملفات ثيمات فاتحة وداكنة في themes/
  • استخدم خصائص CSS مخصصة لألوان الثيمات
  • أنشئ mixin أو دالة تبديل الثيمات
  • تأكد من أن جميع المكونات تحترم متغيرات الثيمات
  • اختبر التبديل بين الثيمات

الخلاصة

في هذا الدرس، أتقنت نمط 7-1 لبنية SASS. أنت الآن تفهم:

  • لماذا تهم البنية في المشاريع الكبيرة
  • البنية والغرض من كل من المجلدات السبعة
  • كيفية تنظيم التجريدات (المتغيرات، mixins، الدوال، العناصر النائبة)
  • دور الأنماط الأساسية والطباعة
  • كيفية هيكلة ملفات المكونات والتخطيط
  • متى تستخدم أنماط خاصة بالصفحات
  • كيفية تنفيذ الثيمات وإدارة البائعين
  • أهمية ملف البيان main.scss
  • متى تستخدم 7-1 مقابل البنى الأبسط

نمط 7-1 يوفر أساساً متيناً وقابلاً للتوسع لمشاريع SASS الكبيرة. إنه يجلب النظام إلى التعقيد ويجعل قاعدة الكود الخاصة بك قابلة للصيانة لسنوات قادمة.