معالج SASS/SCSS

بناء نظام شبكي باستخدام SASS

25 دقيقة الدرس 21 من 30

بناء نظام شبكي باستخدام SASS

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

لماذا نبني نظام شبكي مخصص؟

قبل الغوص في التطبيق، دعونا نفهم لماذا قد ترغب في بناء نظام شبكي خاص بك:

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

أساسيات النظام الشبكي

يتكون كل نظام شبكي من ثلاثة مكونات أساسية:

1. الحاوية (Container)

الحاوية تقوم بتوسيط وتقييد الحد الأقصى لعرض التخطيط:

الحاوية الأساسية

// متغيرات الشبكة
$container-max-width: 1200px;
$container-padding: 15px;

// فئة الحاوية
.container {
    width: 100%;
    max-width: $container-max-width;
    margin-left: auto;
    margin-right: auto;
    padding-left: $container-padding;
    padding-right: $container-padding;
}

// حاوية مرنة (بعرض كامل)
.container-fluid {
    width: 100%;
    padding-left: $container-padding;
    padding-right: $container-padding;
}

2. الصف (Row)

الصفوف تحتوي على الأعمدة وتستخدم هوامش سالبة لموازنة الحشو في الحاوية:

صف مع Flexbox

$gutter: 30px;

.row {
    display: flex;
    flex-wrap: wrap;
    margin-left: -($gutter / 2);
    margin-right: -($gutter / 2);
}

// نسخة بدون مسافات
.row-no-gutters {
    margin-left: 0;
    margin-right: 0;

    > [class*="col-"] {
        padding-left: 0;
        padding-right: 0;
    }
}

3. الأعمدة (Columns)

الأعمدة هي الوحدات البنائية التي تحدد عرض المحتوى:

أنماط الأعمدة الأساسية

// جميع الأعمدة تشترك في هذه الأنماط الأساسية
[class*="col-"] {
    position: relative;
    width: 100%;
    padding-left: ($gutter / 2);
    padding-right: ($gutter / 2);
}

توليد فئات الأعمدة باستخدام @for

بدلاً من كتابة 12 فئة عمود منفصلة يدوياً، نستخدم حلقة @for في SASS لتوليدها تلقائياً:

شبكة من 12 عمود أساسية

$columns: 12;

// توليد .col-1 حتى .col-12
@for $i from 1 through $columns {
    .col-#{$i} {
        flex: 0 0 percentage($i / $columns);
        max-width: percentage($i / $columns);
    }
}
نصيحة: دالة percentage() هي دالة مدمجة في SASS تحول الأرقام العشرية إلى نسب مئوية. على سبيل المثال، percentage(1/12) تخرج 8.33333%.

هذا يولد CSS مثل:

ناتج CSS المولد

.col-1 {
    flex: 0 0 8.33333%;
    max-width: 8.33333%;
}

.col-2 {
    flex: 0 0 16.66667%;
    max-width: 16.66667%;
}

/* ... يستمر حتى col-12 ... */

.col-12 {
    flex: 0 0 100%;
    max-width: 100%;
}

شبكة متجاوبة مع Mixins نقاط الانقطاع

الشبكات الواقعية تحتاج للاستجابة لأحجام الشاشات المختلفة. دعونا نبني نظام شبكي متجاوب:

تكوين نقاط الانقطاع

// حدد نقاط الانقطاع
$breakpoints: (
    xs: 0,
    sm: 576px,
    md: 768px,
    lg: 992px,
    xl: 1200px,
    xxl: 1400px
);

// Mixin لتوليد استعلامات الوسائط
@mixin respond-above($breakpoint) {
    @if map-has-key($breakpoints, $breakpoint) {
        $breakpoint-value: map-get($breakpoints, $breakpoint);
        @media (min-width: $breakpoint-value) {
            @content;
        }
    } @else {
        @warn "نقطة انقطاع غير صالحة: #{$breakpoint}.";
    }
}

توليد أعمدة متجاوبة

// توليد أعمدة لكل نقطة انقطاع
@each $breakpoint, $value in $breakpoints {
    @if $breakpoint == xs {
        // الجوال أولاً: فئات xs ليس لها بادئة
        @for $i from 1 through $columns {
            .col-#{$i} {
                flex: 0 0 percentage($i / $columns);
                max-width: percentage($i / $columns);
            }
        }
    } @else {
        // نقاط الانقطاع الأكبر تحصل على فئات بادئة
        @include respond-above($breakpoint) {
            @for $i from 1 through $columns {
                .col-#{$breakpoint}-#{$i} {
                    flex: 0 0 percentage($i / $columns);
                    max-width: percentage($i / $columns);
                }
            }
        }
    }
}

هذا يولد فئات مثل .col-6, .col-md-4, .col-lg-3, إلخ.

فئات الإزاحة (Offset)

فئات الإزاحة تدفع الأعمدة إلى اليمين بإضافة هامش أيسر:

توليد فئات الإزاحة

// توليد فئات الإزاحة لكل نقطة انقطاع
@each $breakpoint, $value in $breakpoints {
    @if $breakpoint == xs {
        @for $i from 0 through ($columns - 1) {
            .offset-#{$i} {
                margin-left: if($i > 0, percentage($i / $columns), 0);
            }
        }
    } @else {
        @include respond-above($breakpoint) {
            @for $i from 0 through ($columns - 1) {
                .offset-#{$breakpoint}-#{$i} {
                    margin-left: if($i > 0, percentage($i / $columns), 0);
                }
            }
        }
    }
}

// مثال على الاستخدام:
// <div class="col-6 offset-3">محتوى في المنتصف</div>

فئات الترتيب (Push and Pull)

فئات الترتيب تسمح لك بإعادة ترتيب الأعمدة بصرياً دون تغيير ترتيب HTML:

فئات ترتيب Flexbox

// توليد فئات الترتيب
@each $breakpoint, $value in $breakpoints {
    @if $breakpoint == xs {
        @for $i from 1 through $columns {
            .order-#{$i} {
                order: $i;
            }
        }

        .order-first {
            order: -1;
        }

        .order-last {
            order: $columns + 1;
        }
    } @else {
        @include respond-above($breakpoint) {
            @for $i from 1 through $columns {
                .order-#{$breakpoint}-#{$i} {
                    order: $i;
                }
            }

            .order-#{$breakpoint}-first {
                order: -1;
            }

            .order-#{$breakpoint}-last {
                order: $columns + 1;
            }
        }
    }
}

الشبكات المتداخلة

يمكن تداخل الشبكات داخل الأعمدة. المفتاح هو أن كل صف جديد يعيد تعيين سياق الأعمدة:

مثال على شبكة متداخلة

<div class="container">
    <div class="row">
        <div class="col-8">
            <!-- شبكة متداخلة داخل عمود -->
            <div class="row">
                <div class="col-6">عمود متداخل (50% من الوالد)</div>
                <div class="col-6">عمود متداخل (50% من الوالد)</div>
            </div>
        </div>
        <div class="col-4">الشريط الجانبي</div>
    </div>
</div>
ملاحظة: الصفوف المتداخلة تتعامل تلقائياً مع المسافات بشكل صحيح لأن الهوامش السالبة في الصف تعوض الحشو في العمود الوالد.

نظام شبكي قائم على Flexbox (كامل)

دعونا نجمع كل شيء معاً في نظام شبكي كامل قائم على flexbox:

نظام شبكي كامل بـ SCSS

// grid.scss - نظام شبكي كامل قائم على Flexbox

// التكوين
$columns: 12;
$gutter: 30px;
$container-max-width: 1200px;
$container-padding: 15px;

$breakpoints: (
    xs: 0,
    sm: 576px,
    md: 768px,
    lg: 992px,
    xl: 1200px,
    xxl: 1400px
);

// Mixin لاستعلامات الوسائط
@mixin respond-above($breakpoint) {
    @if map-has-key($breakpoints, $breakpoint) {
        $breakpoint-value: map-get($breakpoints, $breakpoint);
        @media (min-width: $breakpoint-value) {
            @content;
        }
    } @else {
        @warn "نقطة انقطاع غير صالحة: #{$breakpoint}.";
    }
}

// الحاوية
.container {
    width: 100%;
    max-width: $container-max-width;
    margin-left: auto;
    margin-right: auto;
    padding-left: $container-padding;
    padding-right: $container-padding;
}

.container-fluid {
    width: 100%;
    padding-left: $container-padding;
    padding-right: $container-padding;
}

// الصف
.row {
    display: flex;
    flex-wrap: wrap;
    margin-left: -($gutter / 2);
    margin-right: -($gutter / 2);
}

.row-no-gutters {
    margin-left: 0;
    margin-right: 0;

    > [class*="col-"] {
        padding-left: 0;
        padding-right: 0;
    }
}

// أنماط الأعمدة الأساسية
[class*="col-"] {
    position: relative;
    width: 100%;
    padding-left: ($gutter / 2);
    padding-right: ($gutter / 2);
}

// توليد أعمدة لكل نقطة انقطاع
@each $breakpoint, $value in $breakpoints {
    @if $breakpoint == xs {
        @for $i from 1 through $columns {
            .col-#{$i} {
                flex: 0 0 percentage($i / $columns);
                max-width: percentage($i / $columns);
            }
        }

        .col {
            flex-grow: 1;
            flex-basis: 0;
            max-width: 100%;
        }

        .col-auto {
            flex: 0 0 auto;
            width: auto;
            max-width: 100%;
        }
    } @else {
        @include respond-above($breakpoint) {
            @for $i from 1 through $columns {
                .col-#{$breakpoint}-#{$i} {
                    flex: 0 0 percentage($i / $columns);
                    max-width: percentage($i / $columns);
                }
            }

            .col-#{$breakpoint} {
                flex-grow: 1;
                flex-basis: 0;
                max-width: 100%;
            }

            .col-#{$breakpoint}-auto {
                flex: 0 0 auto;
                width: auto;
                max-width: 100%;
            }
        }
    }
}

// توليد فئات الإزاحة
@each $breakpoint, $value in $breakpoints {
    @if $breakpoint == xs {
        @for $i from 0 through ($columns - 1) {
            .offset-#{$i} {
                margin-left: if($i > 0, percentage($i / $columns), 0);
            }
        }
    } @else {
        @include respond-above($breakpoint) {
            @for $i from 0 through ($columns - 1) {
                .offset-#{$breakpoint}-#{$i} {
                    margin-left: if($i > 0, percentage($i / $columns), 0);
                }
            }
        }
    }
}

// أدوات المحاذاة
.row-align-start {
    align-items: flex-start;
}

.row-align-center {
    align-items: center;
}

.row-align-end {
    align-items: flex-end;
}

.row-justify-start {
    justify-content: flex-start;
}

.row-justify-center {
    justify-content: center;
}

.row-justify-end {
    justify-content: flex-end;
}

.row-justify-between {
    justify-content: space-between;
}

.row-justify-around {
    justify-content: space-around;
}

تخطيط قائم على CSS Grid مع SASS

بينما Flexbox رائع للتخطيطات أحادية البعد، CSS Grid يتفوق في التخطيطات ثنائية البعد. دعونا نبني نظام CSS Grid مع SASS:

نظام CSS Grid

// css-grid.scss

$grid-columns: 12;
$grid-gap: 30px;

// حاوية باستخدام CSS Grid
.grid-container {
    display: grid;
    grid-template-columns: repeat($grid-columns, 1fr);
    gap: $grid-gap;
}

// توليد فئات امتداد الأعمدة
@for $i from 1 through $grid-columns {
    .grid-col-#{$i} {
        grid-column: span $i;
    }
}

// توليد فئات امتداد الصفوف
@for $i from 1 through 6 {
    .grid-row-#{$i} {
        grid-row: span $i;
    }
}

// فئات موضع البداية
@for $i from 1 through $grid-columns {
    .grid-col-start-#{$i} {
        grid-column-start: $i;
    }
}

// CSS Grid متجاوب
@each $breakpoint, $value in $breakpoints {
    @if $breakpoint != xs {
        @include respond-above($breakpoint) {
            @for $i from 1 through $grid-columns {
                .grid-col-#{$breakpoint}-#{$i} {
                    grid-column: span $i;
                }
            }
        }
    }
}

// أدوات محاذاة Grid
.grid-place-center {
    place-items: center;
}

.grid-place-start {
    place-items: start;
}

.grid-place-end {
    place-items: end;
}

// المحاذاة الذاتية
.grid-self-center {
    place-self: center;
}

.grid-self-start {
    place-self: start;
}

.grid-self-end {
    place-self: end;
}

مقارنة الشبكات المخصصة بشبكة Bootstrap

ملاحظة: فهم الاختلافات يساعدك على اختيار النهج الصحيح لمشروعك.

شبكة Bootstrap

  • الإيجابيات: مُختبرة في المعارك، وثائق شاملة، مجتمع كبير
  • الإيجابيات: تتضمن العديد من فئات الأدوات بخلاف الشبكة فقط
  • السلبيات: حجم ملف أكبر (يتضمن ميزات قد لا تستخدمها)
  • السلبيات: تسميات ثابتة (لا يمكن تخصيصها بسهولة)
  • السلبيات: يتطلب فهم نظام Bootstrap البيئي

شبكة SASS مخصصة

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

تحسين الأداء

إليك استراتيجيات لتحسين نظامك الشبكي المخصص:

التوليد الشرطي

// توليد نقاط الانقطاع التي تحتاجها فقط
$enabled-breakpoints: (sm, md, lg); // تخطي xs و xl

@each $breakpoint, $value in $breakpoints {
    @if index($enabled-breakpoints, $breakpoint) {
        @include respond-above($breakpoint) {
            // توليد الفئات...
        }
    }
}

// توليد أعداد أعمدة محددة فقط
$column-counts: (1, 2, 3, 4, 6, 12); // تخطي 5, 7, 8, 9, 10, 11

@each $count in $column-counts {
    .col-#{$count} {
        flex: 0 0 percentage($count / $columns);
        max-width: percentage($count / $columns);
    }
}
نصيحة: قم بتحليل تصاميمك أولاً. إذا كنت تستخدم مجموعات أعمدة معينة فقط، قم بتوليد تلك الفئات المحددة فقط لتقليل حجم ملف CSS.

تمرين 1: بناء نظام شبكي أساسي

أنشئ نظام شبكي بسيط من 12 عمود بالمتطلبات التالية:

  • حاوية بحد أقصى للعرض 1140px
  • مسافة 20px
  • توليد فئات الأعمدة من .col-1 إلى .col-12
  • تضمين فئة .row مع flexbox
  • اختبر مع تخطيط ثلاثة أعمدة

تمرين 2: إضافة نقاط انقطاع متجاوبة

قم بتوسيع نظامك الشبكي بميزات متجاوبة:

  • أضف نقاط انقطاع لـ sm (576px)، md (768px)، و lg (992px)
  • قم بتوليد فئات أعمدة متجاوبة (.col-sm-6, .col-md-4, إلخ.)
  • أنشئ تخطيط بعرض كامل على الجوال، عمودين على التابلت، و4 أعمدة على سطح المكتب
  • اختبر في أحجام شاشات مختلفة

تمرين 3: إضافة فئات الإزاحة والترتيب

عزز نظامك الشبكي بميزات متقدمة:

  • قم بتوليد فئات الإزاحة لجميع نقاط الانقطاع
  • أضف فئات الترتيب (order-1 حتى order-12)
  • أنشئ تخطيط حيث يظهر الشريط الجانبي أولاً على الجوال لكن أخيراً على سطح المكتب (باستخدام فئات الترتيب)
  • استخدم الإزاحة لتوسيط منطقة محتوى من 6 أعمدة

الخلاصة

في هذا الدرس، تعلمت كيفية بناء أنظمة شبكية احترافية مع SASS. أنت الآن تفهم:

  • المكونات الأساسية للأنظمة الشبكية (الحاويات، الصفوف، الأعمدة)
  • كيفية استخدام حلقات @for لتوليد فئات الأعمدة تلقائياً
  • بناء شبكات متجاوبة مع mixins نقاط الانقطاع
  • إنشاء فئات الإزاحة والترتيب للتخطيطات المتقدمة
  • تطبيق أنظمة قائمة على Flexbox و CSS Grid
  • تحسين الأنظمة الشبكية للأداء
  • متى تستخدم الشبكات المخصصة مقابل شبكات الأطر

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