معالج SASS/SCSS

العوامل والتعبيرات

15 دقيقة الدرس 18 من 30

مقدمة إلى عوامل SASS

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

لماذا نستخدم العوامل؟

توفر العوامل في SASS عدة فوائد:

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

عوامل الحساب

الجمع (+)

جمع الأرقام معاً. يجب أن تكون الوحدات متوافقة أو يجب أن يكون أحد المعاملات بدون وحدة:

أمثلة على الجمع

$base-padding: 1rem;
$extra-padding: 0.5rem;

.element {
  padding: $base-padding + $extra-padding; // 1.5rem
  margin: 10px + 5px;                      // 15px
  width: 50% + 10%;                        // 60%
}

// ربط السلاسل النصية باستخدام +
$family: "Helvetica";
$fallback: "Arial";
$font-stack: $family + ", " + $fallback; // "Helvetica, Arial"

// إضافة بدون وحدة إلى وحدة
.box {
  width: 100px + 20; // 120px (بدون وحدة تُعامل كنفس الوحدة)
}
تحذير: لا يمكنك جمع وحدات غير متوافقة. 10px + 5rem سيسبب خطأ في التجميع. قم بتحويل الوحدات أولاً أو استخدم calc() للحسابات على مستوى CSS.

الطرح (-)

طرح رقم من آخر:

أمثلة على الطرح

$container-width: 1200px;
$sidebar-width: 300px;

.content {
  width: $container-width - $sidebar-width; // 900px
}

// القيم السالبة
$spacing: 20px;
.element {
  margin-top: -$spacing; // -20px
}

// حسابات النسبة المئوية
.column {
  width: 100% - 20%; // 80%
}

الضرب (*)

ضرب الأرقام. يمكن أن يكون لمعامل واحد فقط وحدة على الأكثر:

أمثلة على الضرب

$base-size: 16px;
$multiplier: 1.5;

.heading {
  font-size: $base-size * $multiplier; // 24px
}

// إنشاء المقاييس
$spacing-unit: 8px;
.mt-1 { margin-top: $spacing-unit * 1; }  // 8px
.mt-2 { margin-top: $spacing-unit * 2; }  // 16px
.mt-3 { margin-top: $spacing-unit * 3; }  // 24px

// حسابات الشبكة
$columns: 12;
$column-width: 100% / $columns;
.col-3 { width: $column-width * 3; } // 25%
ملاحظة: عند الضرب، يمكن أن يكون لرقم واحد فقط وحدة. 10px * 2px غير صالح لأنه سينتج عنه px²، وهي ليست وحدة CSS صالحة.

القسمة (/) - النهج الحديث

في SASS الحديث (Dart SASS)، لم يعد عامل / يقوم بالقسمة لأن CSS يستخدم / لاختصار الخط وخصائص أخرى. استخدم math.div() بدلاً من ذلك:

القسمة الحديثة باستخدام math.div()

@use "sass:math";

$container-width: 1200px;
$columns: 12;

.column {
  width: math.div($container-width, $columns); // 100px
}

// حسابات النسبة المئوية
.half-width {
  width: math.div(100%, 2); // 50%
}

// حسابات معقدة
$spacing-base: 32px;
.element {
  margin: math.div($spacing-base, 4);        // 8px
  padding: math.div($spacing-base, 2);       // 16px
}

سلوك القسمة القديم

في إصدارات SASS القديمة، كان / يؤدي القسمة في سياقات معينة:

القسمة القديمة (تجنبها في الكود الجديد)

// الطريقة القديمة (مهجورة)
.element {
  width: (100px / 2);        // 50px (مع الأقواس)
  width: $width / 2;         // 50px (مع متغير)
  width: 100px / 2px;        // 100px / 2px (محفوظة كـ CSS)
}

// المكافئ الحديث
@use "sass:math";

.element {
  width: math.div(100px, 2);  // 50px
  width: math.div($width, 2); // 50px
}
نصيحة: استخدم دائماً @use "sass:math" و math.div() للقسمة في مشاريع SASS الجديدة. هذا يجعل الكود الخاص بك مقاوماً للمستقبل وصريحاً حول نواياك.

المعامل (%)

الحصول على باقي القسمة:

أمثلة على المعامل

// التحقق مما إذا كان الرقم زوجياً أو فردياً
@function is-even($number) {
  @return $number % 2 == 0;
}

// ألوان صفوف بديلة
@for $i from 1 through 10 {
  .row-#{$i} {
    @if $i % 2 == 0 {
      background: #f0f0f0; // صفوف زوجية
    } @else {
      background: white;    // صفوف فردية
    }
  }
}

// فهرسة دائرية
$colors: red, green, blue;
@for $i from 1 through 10 {
  $index: $i % length($colors);
  @if $index == 0 { $index: length($colors); }

  .item-#{$i} {
    color: nth($colors, $index);
  }
}

ربط السلاسل النصية

دمج السلاسل النصية باستخدام +

ربط السلاسل النصية معاً باستخدام عامل الجمع:

ربط السلاسل النصية

$prefix: "mobile";
$suffix: "menu";
$class-name: $prefix + "-" + $suffix; // "mobile-menu"

// معالجة علامات الاقتباس
$quoted: "hello" + " world";   // "hello world" (مقتبس)
$unquoted: hello + " world";   // hello world (غير مقتبس)

// الاستخدام العملي
$image-path: "/images/";
$image-name: "logo.png";

.logo {
  background-image: url($image-path + $image-name);
  // النتيجة: url(/images/logo.png)
}
ملاحظة: يتطابق نمط علامات الاقتباس للنتيجة مع المعامل الأول. إذا كانت السلسلة الأولى مقتبسة، فستكون النتيجة مقتبسة. استخدم الاستيفاء #{} عندما تحتاج إلى مزيد من التحكم في الاقتباس.

عمليات حسابية على الألوان

العمليات الرياضية على الألوان

تسمح SASS بعمليات حسابية على الألوان، تعمل على كل قناة RGB بشكل منفصل:

عمليات حسابية على الألوان

// الجمع
$color1: #102030;
$color2: #010101;
$result: $color1 + $color2; // #112131

// الطرح
$color: #123456;
$adjusted: $color - #001111; // #112345

// الضرب (استخدم بحذر)
$base-color: #222222;
$brighter: $base-color * 2; // #444444

// القسمة (قديمة - تجنبها)
// استخدم دوال الألوان بدلاً من ذلك!
تحذير: يمكن أن تنتج العمليات الحسابية على الألوان نتائج غير متوقعة وهي محبطة بشكل عام. استخدم دوال ألوان SASS مثل lighten()، darken()، saturate()، adjust-color() بدلاً من ذلك للحصول على نتائج يمكن التنبؤ بها ودقيقة إدراكياً.

عوامل المقارنة

المساواة وعدم المساواة

مقارنة القيم للمساواة:

عوامل المساواة

// المساواة (==)
$size: 16px;

@if $size == 16px {
  .text { font-size: $size; }
}

// عدم المساواة (!=)
$theme: "dark";

@if $theme != "light" {
  body { background: #333; }
}

// النوع مهم
@debug 1 == 1px;      // false (وحدات مختلفة)
@debug "10" == 10;    // false (سلسلة نصية مقابل رقم)
@debug true == true;  // true

عوامل العلاقة

مقارنة القيم العددية:

المقارنات العلائقية

$breakpoint: 768px;
$screen-width: 1024px;

// أقل من (<)
@if $screen-width < 1200px {
  .container { max-width: 960px; }
}

// أكبر من (>)
@if $breakpoint > 600px {
  .sidebar { display: block; }
}

// أقل من أو يساوي (<=)
@if $screen-width <= 768px {
  .mobile-nav { display: flex; }
}

// أكبر من أو يساوي (>=)
@if $breakpoint >= 768px {
  .desktop-header { display: block; }
}

// mixin متجاوب عملي
@mixin respond-above($breakpoint) {
  @if $breakpoint > 0 {
    @media (min-width: $breakpoint) {
      @content;
    }
  }
}

العوامل المنطقية

عامل AND

يجب أن يكون كلا الشرطين صحيحين:

AND المنطقي

$is-mobile: true;
$has-touch: true;

@if $is-mobile and $has-touch {
  .app {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }
}

// شروط متعددة
$width: 320px;
$height: 568px;

@if $width >= 320px and $width <= 480px and $height < 600px {
  .container { padding: 10px; }
}

عامل OR

يجب أن يكون شرط واحد على الأقل صحيحاً:

OR المنطقي

$theme: "dark";
$high-contrast: false;

@if $theme == "dark" or $high-contrast {
  body {
    background: #000;
    color: #fff;
  }
}

// بدائل متعددة
$device: "tablet";

@if $device == "mobile" or $device == "tablet" {
  .layout { display: flex; flex-direction: column; }
}

عامل NOT

نفي قيمة منطقية:

NOT المنطقي

$is-production: false;

@if not $is-production {
  .debug-panel { display: block; }
}

// مع عوامل أخرى
$enable-animations: true;
$reduced-motion: false;

@if $enable-animations and not $reduced-motion {
  .element { transition: all 0.3s ease; }
}

تعبيرات منطقية معقدة

دمج العوامل المنطقية

$screen-width: 1024px;
$is-mobile: false;
$is-tablet: true;
$orientation: "landscape";

@if ($is-mobile or $is-tablet) and $screen-width > 768px {
  .navigation { display: flex; justify-content: space-between; }
}

@if not $is-mobile and ($orientation == "landscape" or $screen-width > 1200px) {
  .sidebar { width: 300px; }
}

// دالة التحقق
@function is-valid-breakpoint($bp) {
  @return $bp > 0 and $bp < 2000px and unit($bp) == "px";
}

استخدام calc() مع متغيرات SASS

دمج حسابات SASS وCSS

استخدم CSS calc() للحسابات التي تحتاج إلى الحدوث في وقت التشغيل أو تتضمن وحدات مختلطة:

تكامل calc()

$sidebar-width: 250px;
$gap: 20px;

.content {
  // لا يمكن لـ SASS دمج px والنسبة المئوية في وقت التجميع
  width: calc(100% - #{$sidebar-width} - #{$gap});
}

// مسافات متجاوبة
$base-spacing: 1rem;

.element {
  margin: calc(#{$base-spacing} + 2vw);
  padding: calc(#{$base-spacing} * 2);
}

// حسابات ديناميكية مع خصائص CSS المخصصة
:root {
  --sidebar-width: 250px;
}

.content {
  // CSS نقي
  width: calc(100% - var(--sidebar-width) - 20px);
}
نصيحة: استخدم عوامل SASS للحسابات في وقت التجميع مع القيم المعروفة. استخدم calc() للحسابات في وقت التشغيل، أو وحدات العرض، أو عند خلط وحدات غير متوافقة. استخدم استيفاء #{} لإدراج متغيرات SASS في calc().

ترتيب العمليات

أولوية العوامل

تتبع SASS ترتيب العمليات الرياضية القياسي:

قواعد الأولوية

// 1. الأقواس (أعلى أولوية)
$result: (10 + 5) * 2; // 30 (وليس 20)

// 2. الضرب، القسمة، المعامل
$result: 10 + 5 * 2;   // 20 (5*2 أولاً، ثم +10)

// 3. الجمع، الطرح
$result: 10 - 5 + 3;   // 8 (من اليسار إلى اليمين)

// مثال عملي
$base: 16px;
$scale: 1.5;
$spacing: 8px;

.element {
  // ترتيب واضح مع الأقواس
  font-size: $base * $scale;                    // 24px
  margin: ($base + $spacing) * 2;               // 48px
  padding: $base + $spacing * 2;                // 32px (spacing*2 أولاً)
}

معالجة الوحدات

العمل مع الوحدات

فهم كيفية معالجة SASS للوحدات في العمليات:

عمليات الوحدات

// نفس الوحدات
$a: 10px + 5px;    // 15px ✓
$b: 20% - 5%;      // 15% ✓

// بدون وحدة مع وحدة
$c: 100px + 10;    // 110px ✓ (10 تُعامل كـ px)
$d: 10 + 100px;    // 110px ✓

// وحدات مختلفة (خطأ)
// $e: 10px + 5rem; // ✗ خطأ في التجميع!

// الضرب (يمكن لواحد فقط أن يكون له وحدة)
$f: 10px * 2;      // 20px ✓
$g: 2 * 10px;      // 20px ✓
// $h: 10px * 2px; // ✗ خطأ! سيكون px²

// القسمة
@use "sass:math";
$i: math.div(20px, 2);    // 10px ✓
$j: math.div(20px, 5px);  // 4 (بدون وحدة) ✓

دوال تحويل الوحدات

التحويل بين الوحدات

@use "sass:math";

// إزالة الوحدات
@function strip-unit($number) {
  @if math.is-unitless($number) {
    @return $number;
  }
  @return math.div($number, $number * 0 + 1);
}

$value: strip-unit(16px); // 16

// إضافة وحدة
@function add-unit($number, $unit) {
  $unitless: strip-unit($number);
  @return $unitless * 1#{$unit};
}

// تحويل rem إلى px (يفترض قاعدة 16px)
@function rem-to-px($rem) {
  @return strip-unit($rem) * 16px;
}

$px-value: rem-to-px(1.5rem); // 24px

تمرين 1: نظام طباعة سائل

أنشئ حاسبة طباعة سائلة باستخدام العوامل:

  1. عرّف أحجام خطوط دنيا وقصوى (مثل 16px إلى 24px)
  2. عرّف عروض إطارات عرض دنيا وقصوى (مثل 320px إلى 1200px)
  3. أنشئ دالة تحسب معدل التغيير
  4. ولّد تعبير calc() للقياس السائل
  5. أنشئ mixins لـ h1-h6 بنطاقات دنيا/قصوى مختلفة
  6. اختبر مع سيناريوهات إطارات عرض مختلفة

تمرين 2: حاسبة الشبكة

ابنِ نظام شبكة مرن بحسابات قائمة على العوامل:

  1. عرّف عرض الحاوية، وعدد الأعمدة، وحجم الفجوة
  2. احسب عرض العمود باستخدام القسمة: (container - gutters) / columns
  3. أنشئ دالة: column-width($span, $total-columns)
  4. تعامل مع أحجام فجوات مختلفة (داخلية، خارجية، بين)
  5. ولّد فئات لنطاقات الأعمدة (1-12)
  6. أضف حسابات متجاوبة لنقاط توقف مختلفة

تمرين 3: مولد درجات الألوان

أنشئ نظام درجات/صبغات باستخدام العوامل والشروط:

  1. عرّف لون أساسي
  2. أنشئ دالة تولّد درجات أفتح (1-5)
  3. أنشئ دالة تولّد درجات أغمق (1-5)
  4. استخدم عوامل المقارنة للتأكد من أن الدرجات تبقى ضمن النطاقات الصالحة
  5. ولّد خصائص CSS مخصصة لكل درجة
  6. أنشئ فئات أدوات: .bg-primary-light-1، .bg-primary-dark-2، إلخ.

الملخص

في هذا الدرس، أتقنت:

  • عوامل الحساب: +، -، *، /، % للحسابات الرياضية
  • القسمة الحديثة باستخدام math.div() من وحدة sass:math
  • ربط السلاسل النصية باستخدام عامل +
  • العمليات الحسابية على الألوان ولماذا يُفضل استخدام دوال الألوان
  • عوامل المقارنة: ==، !=، <، >، <=، >= للمنطق الشرطي
  • العوامل المنطقية: and، or، not للشروط المعقدة
  • دمج متغيرات SASS مع دالة CSS calc()
  • أولوية العوامل وترتيب العمليات
  • معالجة الوحدات والتوافق وتقنيات التحويل

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