معالج SASS/SCSS

الدوال: الدوال المدمجة

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

الدوال المدمجة في SASS

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

نظرة عامة على وحدات الدوال المدمجة في SASS

الدوال المدمجة في SASS منظمة في عدة فئات:

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

دوال الألوان

دوال الألوان هي من بين أكثر دوال SASS فائدة. تتيح لك إنشاء تنويعات ألوان وأنظمة موضوعات ولوحات ألوان ديناميكية دون حساب قيم الألوان يدوياً.

lighten() و darken()

تقوم هذه الدوال بضبط سطوع اللون بنسبة مئوية.

تفتيح وتغميق الألوان

$primary-color: #3498db;

.light-button {
  background-color: lighten($primary-color, 10%);
  // النتيجة: #5DADE2 (أزرق أفتح)
}

.lighter-button {
  background-color: lighten($primary-color, 20%);
  // النتيجة: #85C1E9 (أفتح أكثر)
}

.dark-button {
  background-color: darken($primary-color, 10%);
  // النتيجة: #217DBB (أزرق أغمق)
}

.darker-button {
  background-color: darken($primary-color, 20%);
  // النتيجة: #1A5490 (أغمق أكثر)
}

// استخدام عملي: حالات التمرير
.button {
  background-color: $primary-color;

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

  &:active {
    background-color: darken($primary-color, 10%);
  }
}

saturate() و desaturate()

تقوم هذه الدوال بضبط التشبع (كثافة اللون) للون.

معالجة التشبع

$base-color: #7fb3d5;

.vibrant {
  color: saturate($base-color, 30%);
  // لون أكثر كثافة وحيوية
}

.muted {
  color: desaturate($base-color, 30%);
  // لون أكثر رمادية وهدوءاً
}

// إنشاء لوحة ألوان هادئة
$brand-blue: #2980b9;

.header {
  background: $brand-blue;
}

.sidebar {
  background: desaturate($brand-blue, 20%);
  // ينشئ مظهراً أكثر دقة واحترافية
}

.footer {
  background: desaturate($brand-blue, 40%);
  // أكثر هدوءاً لعناصر الخلفية
}

adjust-hue()

تقوم هذه الدالة بتدوير درجة اللون حول عجلة الألوان بعدد محدد من الدرجات.

تدوير درجة اللون

$base-color: #ff0000; // أحمر

.complementary {
  color: adjust-hue($base-color, 180deg);
  // النتيجة: #00FFFF (سماوي - معاكس على عجلة الألوان)
}

.analogous-1 {
  color: adjust-hue($base-color, 30deg);
  // النتيجة: #FF8000 (برتقالي محمر)
}

.analogous-2 {
  color: adjust-hue($base-color, -30deg);
  // النتيجة: #FF0080 (وردي محمر)
}

// إنشاء نظام ألوان ثلاثي
$primary: #e74c3c; // أحمر

.primary {
  background: $primary;
}

.secondary {
  background: adjust-hue($primary, 120deg);
  // أخضر
}

.tertiary {
  background: adjust-hue($primary, 240deg);
  // أزرق
}

mix()

تمزج دالة mix() بين لونين معاً. يمكنك تحديد الوزن (النسبة المئوية) للون الأول.

مزج الألوان

$color1: #ff0000; // أحمر
$color2: #0000ff; // أزرق

.mixed-equal {
  background: mix($color1, $color2);
  // النتيجة: #800080 (بنفسجي - مزيج 50/50)
}

.mixed-more-red {
  background: mix($color1, $color2, 75%);
  // النتيجة: #BF0040 (75% أحمر، 25% أزرق)
}

.mixed-more-blue {
  background: mix($color1, $color2, 25%);
  // النتيجة: #4000BF (25% أحمر، 75% أزرق)
}

// استخدام عملي: إنشاء درجات وظلال
$brand-color: #3498db;

.tint-light {
  background: mix(white, $brand-color, 80%);
  // درجة فاتحة جداً
}

.tint-medium {
  background: mix(white, $brand-color, 50%);
  // درجة متوسطة
}

.shade-dark {
  background: mix(black, $brand-color, 50%);
  // ظل داكن
}

rgba() و complement() و invert()

دوال ألوان مفيدة أخرى

$brand-color: #3498db;

// rgba() - إضافة شفافية لأي لون
.overlay {
  background: rgba($brand-color, 0.8);
  // عتامة 80%
}

.subtle-overlay {
  background: rgba($brand-color, 0.2);
  // عتامة 20%
}

// complement() - الحصول على اللون المكمل (المعاكس)
.accent {
  color: complement($brand-color);
  // يعيد اللون المعاكس تماماً على عجلة الألوان
}

// invert() - عكس جميع قنوات الألوان
$dark-bg: #2c3e50;

.inverted-theme {
  background: invert($dark-bg);
  // ينشئ خلفية فاتحة بالعكس
}

// دمج الدوال لتأثيرات قوية
.gradient-button {
  background: linear-gradient(
    to bottom,
    lighten($brand-color, 5%),
    darken($brand-color, 5%)
  );

  &:hover {
    background: linear-gradient(
      to bottom,
      lighten($brand-color, 10%),
      $brand-color
    );
  }
}
نصيحة: توفر SASS الحديثة أيضاً دوال ألوان أكثر تقدماً مثل scale-color() و adjust-color() و change-color() التي تمنحك تحكماً دقيقاً في قنوات الألوان الفردية (الأحمر، الأخضر، الأزرق، الدرجة، التشبع، السطوع، ألفا).

دوال السلاسل النصية

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

دوال السلاسل النصية الشائعة

// quote() و unquote()
$font-name: Arial;

.with-quotes {
  font-family: quote($font-name);
  // النتيجة: font-family: "Arial";
}

$quoted-font: "Helvetica Neue";

.without-quotes {
  font-family: unquote($quoted-font);
  // النتيجة: font-family: Helvetica Neue;
}

// str-length() - الحصول على طول السلسلة النصية
$text: "Hello World";

.debug {
  // الطول: 11 حرفاً
  content: str-length($text);
}

// to-upper-case() و to-lower-case()
$brand: "Acme Corp";

.uppercase {
  content: to-upper-case($brand);
  // النتيجة: "ACME CORP"
}

.lowercase {
  content: to-lower-case($brand);
  // النتيجة: "acme corp"
}

// str-insert() - إدراج سلسلة نصية في موضع محدد
$base: "Hello";

.inserted {
  content: str-insert($base, " World", 6);
  // النتيجة: "Hello World"
}

// str-index() - البحث عن موضع سلسلة فرعية
$text: "Hello World";

.index {
  // يعيد: 7 (موضع "World")
  content: str-index($text, "World");
}

// مثال عملي: إنشاء فئات خدمية
$sizes: small, medium, large;

@each $size in $sizes {
  .btn-#{$size} {
    $uppercase-size: to-upper-case($size);
    padding: if($size == small, 8px, if($size == medium, 12px, 16px));

    &::before {
      content: "#{$uppercase-size} BUTTON";
    }
  }
}

دوال الأرقام

تقوم دوال الأرقام بإجراء عمليات رياضية وتحويلات على القيم الرقمية.

دوال الأرقام الرياضية

// percentage() - تحويل رقم بدون وحدة إلى نسبة مئوية
.width-half {
  width: percentage(0.5);
  // النتيجة: 50%
}

.width-third {
  width: percentage(1/3);
  // النتيجة: 33.33333%
}

// round() و ceil() و floor()
$value: 12.7px;

.rounded {
  width: round($value);
  // النتيجة: 13px
}

.ceiling {
  width: ceil($value);
  // النتيجة: 13px (يقرب للأعلى دائماً)
}

.floor {
  width: floor($value);
  // النتيجة: 12px (يقرب للأسفل دائماً)
}

// abs() - القيمة المطلقة
$negative: -15px;

.absolute {
  margin: abs($negative);
  // النتيجة: 15px
}

// min() و max()
.responsive-width {
  width: min(100%, 600px);
  // يأخذ القيمة الأصغر
}

.responsive-padding {
  padding: max(20px, 2vw);
  // يأخذ القيمة الأكبر
}

// random() - توليد رقم عشوائي
.random-color {
  // توليد قيم RGB عشوائية
  color: rgb(
    random(255),
    random(255),
    random(255)
  );
}

.random-position {
  left: percentage(random(100) / 100);
  // نسبة مئوية عشوائية من 0% إلى 100%
}

// مثال عملي: طباعة استجابية مع الرياضيات
$base-font-size: 16px;
$scale-ratio: 1.25;

h1 {
  font-size: $base-font-size * $scale-ratio * $scale-ratio * $scale-ratio;
  // النتيجة: 31.25px
}

h2 {
  font-size: round($base-font-size * $scale-ratio * $scale-ratio);
  // النتيجة: 25px (مقربة)
}

h3 {
  font-size: $base-font-size * $scale-ratio;
  // النتيجة: 20px
}
ملاحظة: تدعم SASS أيضاً العوامل الرياضية القياسية (+، -، *، /، %) مباشرة في أوراق الأنماط الخاصة بك. دوال الأرقام أكثر فائدة عندما تحتاج إلى سلوك تقريب محدد أو تحتاج إلى العمل مع النسب المئوية.

دوال القوائم

القوائم في SASS هي مجموعات من القيم مفصولة بفواصل أو مسافات. تتيح لك دوال القوائم معالجة هذه المجموعات والاستعلام عنها.

العمل مع القوائم

$colors: red, green, blue, yellow;
$spacing: 10px 20px 30px 40px;

// length() - الحصول على عدد العناصر
.total-colors {
  content: length($colors);
  // النتيجة: 4
}

// nth() - الحصول على عنصر في موضع محدد (الفهرس يبدأ من 1)
.first-color {
  color: nth($colors, 1);
  // النتيجة: red
}

.last-color {
  color: nth($colors, length($colors));
  // النتيجة: yellow
}

// append() - إضافة عنصر إلى نهاية القائمة
$extended-colors: append($colors, purple);
// النتيجة: red, green, blue, yellow, purple

.new-length {
  content: length($extended-colors);
  // النتيجة: 5
}

// join() - دمج قائمتين
$primary-colors: red, blue, yellow;
$secondary-colors: green, orange, purple;

$all-colors: join($primary-colors, $secondary-colors);
// النتيجة: red, blue, yellow, green, orange, purple

// index() - البحث عن موضع عنصر في القائمة
$sizes: small, medium, large, x-large;

.position {
  content: index($sizes, large);
  // النتيجة: 3
}

// zip() - دمج عدة قوائم في قوائم متداخلة
$names: primary, secondary, accent;
$colors: #007bff, #6c757d, #ffc107;

$theme: zip($names, $colors);
// النتيجة: (primary #007bff), (secondary #6c757d), (accent #ffc107)

// مثال عملي: إنشاء خدمات التباعد
$spacings: 0, 4, 8, 12, 16, 20, 24, 32, 40, 48;

@each $space in $spacings {
  .m-#{$space} {
    margin: #{$space}px;
  }

  .p-#{$space} {
    padding: #{$space}px;
  }
}

// النتيجة: .m-0, .m-4, .m-8, .p-0, .p-4, .p-8, إلخ.

استخدام متقدم للقوائم

معالجة قوائم معقدة

// إنشاء نظام نقاط توقف استجابية
$breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px,
  xxl: 1400px
);

// المرور عبر نقاط التوقف (يستخدم دوال الخرائط)
@each $name, $value in $breakpoints {
  @if $value > 0 {
    @media (min-width: $value) {
      .container-#{$name} {
        max-width: $value - 20px;
      }
    }
  }
}

// معالجة قوائم متعددة القيم
$font-stack: (
  -apple-system,
  BlinkMacSystemFont,
  "Segoe UI",
  Roboto,
  "Helvetica Neue",
  Arial,
  sans-serif
);

body {
  font-family: $font-stack;
}

// التحقق من وجود قيمة في قائمة
$supported-positions: top, right, bottom, left;

@mixin position-check($pos) {
  @if index($supported-positions, $pos) {
    position: absolute;
    #{$pos}: 0;
  } @else {
    @error "الموضع #{$pos} غير مدعوم. استخدم: #{$supported-positions}";
  }
}

.top-element {
  @include position-check(top);
}

دوال الخرائط

الخرائط هي أزواج مفتاح-قيمة في SASS، مماثلة للكائنات في JavaScript أو القواميس في Python. تتيح لك دوال الخرائط العمل مع هياكل البيانات هذه بكفاءة.

دوال الخرائط الأساسية

// تعريف خريطة موضوع الألوان
$theme-colors: (
  primary: #007bff,
  secondary: #6c757d,
  success: #28a745,
  danger: #dc3545,
  warning: #ffc107,
  info: #17a2b8,
  light: #f8f9fa,
  dark: #343a40
);

// map-get() - الحصول على قيمة بواسطة المفتاح
.primary-button {
  background-color: map-get($theme-colors, primary);
  // النتيجة: #007bff
}

.danger-alert {
  border-color: map-get($theme-colors, danger);
  // النتيجة: #dc3545
}

// map-has-key() - التحقق من وجود المفتاح
@function get-theme-color($key) {
  @if map-has-key($theme-colors, $key) {
    @return map-get($theme-colors, $key);
  } @else {
    @warn "اللون #{$key} غير موجود في الموضوع!";
    @return #000;
  }
}

.custom {
  color: get-theme-color(primary);
  // يعمل: يعيد #007bff
}

// map-keys() - الحصول على جميع المفاتيح
$all-theme-names: map-keys($theme-colors);
// النتيجة: primary, secondary, success, danger, warning, info, light, dark

// map-values() - الحصول على جميع القيم
$all-theme-colors: map-values($theme-colors);
// النتيجة: #007bff, #6c757d, #28a745, ...

// map-merge() - دمج خريطتين
$additional-colors: (
  purple: #6f42c1,
  pink: #e83e8c,
  orange: #fd7e14
);

$extended-theme: map-merge($theme-colors, $additional-colors);

// map-remove() - إزالة مفتاح من الخريطة
$no-danger: map-remove($theme-colors, danger, warning);
// النتيجة: خريطة بدون مفاتيح danger و warning

استخدام عملي للخرائط

بناء نظام موضوع كامل

// تكوين موضوع شامل
$theme: (
  colors: (
    primary: #007bff,
    secondary: #6c757d,
    success: #28a745,
    danger: #dc3545
  ),
  spacing: (
    xs: 4px,
    sm: 8px,
    md: 16px,
    lg: 24px,
    xl: 32px
  ),
  typography: (
    base-size: 16px,
    line-height: 1.5,
    font-family: ('Inter', sans-serif)
  ),
  borders: (
    radius: 4px,
    width: 1px,
    style: solid
  )
);

// دالة مساعدة للحصول على قيم الخرائط المتداخلة
@function theme-get($keys...) {
  $value: $theme;

  @each $key in $keys {
    @if type-of($value) == "map" {
      $value: map-get($value, $key);
    } @else {
      @warn "المفتاح #{$key} غير موجود في هيكل الموضوع";
      @return null;
    }
  }

  @return $value;
}

// استخدام قيم الموضوع المتداخلة
.card {
  padding: theme-get(spacing, md);
  border-radius: theme-get(borders, radius);
  border: theme-get(borders, width) theme-get(borders, style) #ccc;
}

.primary-button {
  background: theme-get(colors, primary);
  padding: theme-get(spacing, sm) theme-get(spacing, md);
}

// إنشاء فئات خدمية من الخريطة
@each $name, $color in map-get($theme, colors) {
  .bg-#{$name} {
    background-color: $color;
  }

  .text-#{$name} {
    color: $color;
  }

  .border-#{$name} {
    border-color: $color;
  }
}

// النتيجة: .bg-primary, .text-primary, .border-primary, إلخ.

// إنشاء خدمات التباعد
@each $size, $value in map-get($theme, spacing) {
  .m-#{$size} {
    margin: $value;
  }

  .p-#{$size} {
    padding: $value;
  }

  .gap-#{$size} {
    gap: $value;
  }
}

// النتيجة: .m-xs, .m-sm, .p-xs, .p-sm, .gap-xs, إلخ.
نصيحة: الخرائط قوية للغاية لتنظيم بيانات التكوين وأنظمة الموضوعات. ضع في اعتبارك استخدام خرائط متداخلة لإنشاء مصدر واحد للحقيقة لرموز التصميم الخاصة بك، مما يجعل أوراق الأنماط الخاصة بك أسهل في الصيانة والتحديث.

دمج الدوال لتأثيرات قوية

مثال من العالم الواقعي: مولد أزرار ديناميكي

$button-colors: (
  primary: #007bff,
  success: #28a745,
  danger: #dc3545,
  warning: #ffc107
);

@mixin generate-button($color-name, $base-color) {
  .btn-#{$color-name} {
    background-color: $base-color;
    border-color: darken($base-color, 5%);
    color: if(lightness($base-color) > 50%, #000, #fff);

    &:hover {
      background-color: darken($base-color, 7.5%);
      border-color: darken($base-color, 10%);
    }

    &:active {
      background-color: darken($base-color, 10%);
      border-color: darken($base-color, 12.5%);
    }

    &:disabled {
      background-color: desaturate($base-color, 40%);
      opacity: 0.65;
    }

    // إنشاء متغير الحدود
    &-outline {
      background-color: transparent;
      border-color: $base-color;
      color: $base-color;

      &:hover {
        background-color: $base-color;
        color: if(lightness($base-color) > 50%, #000, #fff);
      }
    }

    // إنشاء متغير فاتح
    &-light {
      background-color: mix(white, $base-color, 85%);
      border-color: mix(white, $base-color, 70%);
      color: darken($base-color, 10%);

      &:hover {
        background-color: mix(white, $base-color, 75%);
      }
    }
  }
}

// إنشاء جميع متغيرات الأزرار
@each $name, $color in $button-colors {
  @include generate-button($name, $color);
}

// النتائج في:
// .btn-primary, .btn-primary:hover, .btn-primary-outline, .btn-primary-light
// .btn-success, .btn-success:hover, .btn-success-outline, .btn-success-light
// ... وهكذا لجميع الألوان

تمرين 1: مولد لوحة الألوان

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

  1. ابدأ بمتغير لون أساسي
  2. استخدم lighten() لإنشاء 5 درجات أفتح (10%، 20%، 30%، 40%، 50%)
  3. استخدم darken() لإنشاء 5 ظلال أغمق (10%، 20%، 30%، 40%، 50%)
  4. أنشئ فئات CSS من .tint-1 إلى .tint-5 ومن .shade-1 إلى .shade-5
  5. أضف لوناً مكملاً باستخدام complement() وأنشئ درجاته وظلاله

تمرين 2: بناء نظام التباعد

قم ببناء نظام خدمات تباعد شامل باستخدام دوال القوائم والأرقام:

  1. أنشئ وحدة تباعد أساسية (مثل 8px)
  2. أنشئ قائمة بالمضاعفات: 0، 0.5، 1، 1.5، 2، 2.5، 3، 4، 5، 6، 8
  3. استخدم دوال القوائم لإنشاء خدمات الهامش والحشو لجميع الجوانب (أعلى، يمين، أسفل، يسار، المحور س، المحور ص، الكل)
  4. استخدم دالة percentage() لإنشاء خدمات العرض (25%، 50%، 75%، 100%)
  5. استخدم round() للتأكد من أن جميع القيم المُنشأة هي بكسلات كاملة

تمرين 3: نظام تكوين الموضوع

أنشئ نظام موضوع باستخدام دوال الخرائط:

  1. أنشئ خريطة متداخلة مع تكوين الموضوع بما في ذلك الألوان والطباعة والتباعد
  2. اكتب دالة مخصصة لاسترجاع قيم الخرائط المتداخلة بأمان
  3. استخدم map-keys() و @each لإنشاء فئات خدمية لجميع ألوان الموضوع
  4. أنشئ mixin يقبل اسم لون وينشئ نمط مكون كامل باستخدام map-get()
  5. أضف معالجة الأخطاء مع @warn لأسماء الألوان غير الصالحة
ملاحظة: الدوال المدمجة في SASS هي الأساس لإنشاء أوراق أنماط ديناميكية وقابلة للصيانة. إتقان هذه الدوال يتيح لك كتابة كود أقل مع تحقيق أنظمة تنسيق أكثر تطوراً.