معالج SASS/SCSS

الخرائط: الإنشاء والعمليات المتقدمة

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

مقدمة إلى خرائط SASS

خرائط SASS هي واحدة من أقوى هياكل البيانات في SASS. تتيح لك تخزين أزواج من المفاتيح والقيم، مشابهة للكائنات في JavaScript أو القواميس في Python. الخرائط مفيدة جداً لتنظيم البيانات المرتبطة وإنشاء أنظمة قابلة للتطوير للألوان ونقاط التوقف والمسافات وغيرها.

ما هي خرائط SASS؟

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

صيغة الخريطة الأساسية

$colors: (
  primary: #3498db,
  secondary: #2ecc71,
  danger: #e74c3c,
  warning: #f39c12,
  info: #16a085
);

$breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
);
ملاحظة: يجب أن تكون الخرائط محاطة بأقواس. الصيغة هي $map-name: (key1: value1, key2: value2). يمكنك استخدام أي نوع من البيانات كقيم، بما في ذلك النصوص والأرقام والألوان والقوائم وحتى خرائط أخرى.

لماذا نستخدم الخرائط؟

توفر الخرائط عدة مزايا على المتغيرات التقليدية:

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

الوصول إلى قيم الخريطة

استخدام دالة map-get()

تسترجع دالة map-get() قيمة من خريطة باستخدام مفتاحها:

الوصول إلى قيم الخريطة

$colors: (
  primary: #3498db,
  secondary: #2ecc71,
  danger: #e74c3c
);

.button {
  background-color: map-get($colors, primary); // #3498db

  &:hover {
    background-color: darken(map-get($colors, primary), 10%);
  }
}

.alert-danger {
  color: map-get($colors, danger); // #e74c3c
  border-color: map-get($colors, danger);
}

صيغة map.get() الحديثة

مع نظام الوحدات في SASS، يمكنك استخدام map.get() من وحدة الخريطة:

استخدام map.get() مع @use

@use "sass:map";

$colors: (
  primary: #3498db,
  secondary: #2ecc71
);

.card {
  background: map.get($colors, primary);
  border: 1px solid map.get($colors, secondary);
}
نصيحة: صيغة map.get() هي الطريقة الحديثة القائمة على الوحدات. إذا كنت تستخدم قاعدة @use، فضّل map.get() على map-get().

التحقق من المفاتيح

دالة map-has-key()

قبل الوصول إلى قيمة خريطة، قد ترغب في التحقق من وجود المفتاح:

التحقق من وجود المفتاح

$theme: (
  primary: #3498db,
  secondary: #2ecc71
);

@if map-has-key($theme, primary) {
  .btn-primary {
    background: map-get($theme, primary);
  }
}

@if not map-has-key($theme, tertiary) {
  @warn "Tertiary color is not defined in theme";
}

نمط الوصول الآمن

إنشاء دالة جلب آمنة تُرجع قيمة احتياطية:

دالة الوصول الآمن للخريطة

@function get-color($key, $fallback: #000) {
  $colors: (
    primary: #3498db,
    secondary: #2ecc71
  );

  @if map-has-key($colors, $key) {
    @return map-get($colors, $key);
  }

  @warn "Color '#{$key}' not found. Using fallback.";
  @return $fallback;
}

.element {
  color: get-color(primary); // #3498db
  background: get-color(tertiary, #ccc); // #ccc مع تحذير
}

الحصول على المفاتيح والقيم

دالة map-keys()

استخراج جميع المفاتيح من خريطة كقائمة:

استخراج مفاتيح الخريطة

$spacing: (
  xs: 0.25rem,
  sm: 0.5rem,
  md: 1rem,
  lg: 1.5rem,
  xl: 3rem
);

$spacing-keys: map-keys($spacing);
// النتيجة: (xs, sm, md, lg, xl)

@debug $spacing-keys; // الإخراج في وحدة التحكم

دالة map-values()

استخراج جميع القيم من خريطة كقائمة:

استخراج قيم الخريطة

$font-sizes: (
  small: 0.875rem,
  normal: 1rem,
  large: 1.25rem
);

$sizes: map-values($font-sizes);
// النتيجة: (0.875rem, 1rem, 1.25rem)

// إيجاد أصغر حجم خط
$min-size: min($sizes...);

دمج الخرائط

دالة map-merge()

دمج خريطتين في خريطة جديدة. إذا تداخلت المفاتيح، تأخذ قيم الخريطة الثانية الأسبقية:

دمج الخرائط

$default-colors: (
  primary: #3498db,
  secondary: #2ecc71,
  text: #333
);

$custom-colors: (
  primary: #e74c3c,    // استبدال
  accent: #9b59b6      // مفتاح جديد
);

$theme: map-merge($default-colors, $custom-colors);
// النتيجة:
// (
//   primary: #e74c3c,     // تم الاستبدال
//   secondary: #2ecc71,
//   text: #333,
//   accent: #9b59b6       // تمت الإضافة
// )

.app {
  background: map-get($theme, primary); // #e74c3c
}

دمج خرائط متعددة

تسلسل استدعاءات map-merge() لدمج خرائط متعددة:

تسلسل عمليات الدمج

$base: (
  primary: blue
);

$theme-light: (
  bg: white,
  text: black
);

$theme-dark: (
  bg: black,
  text: white
);

$final-light: map-merge(map-merge($base, $theme-light), (
  accent: yellow
));
// النتيجة: (primary: blue, bg: white, text: black, accent: yellow)

إزالة المفاتيح

دالة map-remove()

إنشاء خريطة جديدة مع إزالة مفاتيح محددة:

إزالة مفاتيح الخريطة

$all-colors: (
  primary: #3498db,
  secondary: #2ecc71,
  danger: #e74c3c,
  warning: #f39c12,
  deprecated-color: #ccc
);

$active-colors: map-remove($all-colors, deprecated-color);
// النتيجة: خريطة بدون deprecated-color

// إزالة مفاتيح متعددة
$main-colors: map-remove($all-colors, warning, deprecated-color);
تحذير: دوال الخريطة مثل map-remove() و map-merge() لا تعدل الخريطة الأصلية. إنها تُرجع خريطة جديدة. الخرائط في SASS غير قابلة للتغيير.

الخرائط المتداخلة

إنشاء هياكل خرائط متداخلة

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

مثال على الخرائط المتداخلة

$theme: (
  colors: (
    primary: #3498db,
    secondary: #2ecc71,
    shades: (
      light: #5dade2,
      dark: #2874a6
    )
  ),
  typography: (
    font-family: "Inter, sans-serif",
    sizes: (
      small: 0.875rem,
      normal: 1rem,
      large: 1.25rem
    )
  ),
  spacing: (
    xs: 0.25rem,
    sm: 0.5rem,
    md: 1rem
  )
);

الوصول إلى قيم الخرائط المتداخلة

الوصول إلى القيم المتداخلة عن طريق تسلسل استدعاءات map-get():

الوصول إلى القيم المتداخلة

$theme: (
  colors: (
    primary: #3498db,
    shades: (
      light: #5dade2,
      dark: #2874a6
    )
  )
);

// الوصول إلى قيمة متداخلة
$primary-light: map-get(map-get(map-get($theme, colors), shades), light);

// إنشاء دالة مساعدة للوصول الأسهل
@function theme-get($keys...) {
  $value: $theme;
  @each $key in $keys {
    $value: map-get($value, $key);
  }
  @return $value;
}

.button {
  background: theme-get(colors, primary); // #3498db

  &:hover {
    background: theme-get(colors, shades, dark); // #2874a6
  }
}
نصيحة: للخرائط المتداخلة بعمق، أنشئ دوال مساعدة لتبسيط الوصول. هذا يجعل الكود الخاص بك أكثر قابلية للقراءة والصيانة.

التكرار عبر الخرائط

استخدام @each مع الخرائط

المرور عبر إدخالات الخريطة لتوليد CSS ديناميكياً:

التكرار الأساسي للخريطة

$colors: (
  primary: #3498db,
  success: #2ecc71,
  danger: #e74c3c,
  warning: #f39c12
);

@each $name, $color in $colors {
  .btn-#{$name} {
    background-color: $color;
    border-color: darken($color, 10%);

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

// CSS المولّد:
// .btn-primary { background-color: #3498db; ... }
// .btn-success { background-color: #2ecc71; ... }
// .btn-danger { background-color: #e74c3c; ... }
// .btn-warning { background-color: #f39c12; ... }

أمثلة تكرار متقدمة

توليد فئات الأدوات المساعدة

$spacing-scale: (
  0: 0,
  1: 0.25rem,
  2: 0.5rem,
  3: 0.75rem,
  4: 1rem,
  5: 1.5rem,
  6: 2rem
);

$sides: (
  t: top,
  r: right,
  b: bottom,
  l: left
);

// توليد أدوات الهامش
@each $key, $value in $spacing-scale {
  .m-#{$key} { margin: $value; }
  .p-#{$key} { padding: $value; }

  @each $side-key, $side-value in $sides {
    .m#{$side-key}-#{$key} { margin-#{$side-value}: $value; }
    .p#{$side-key}-#{$key} { padding-#{$side-value}: $value; }
  }
}

// التوليد: .m-0, .m-1, .mt-2, .pr-3, إلخ.

حالات الاستخدام الواقعية

1. نظام ألوان السمة

نظام سمة كامل

$theme-colors: (
  primary: (
    base: #3498db,
    light: #5dade2,
    dark: #2874a6,
    contrast: #fff
  ),
  secondary: (
    base: #2ecc71,
    light: #58d68d,
    dark: #229954,
    contrast: #fff
  ),
  neutral: (
    base: #95a5a6,
    light: #d5dbdb,
    dark: #566573,
    contrast: #fff
  )
);

@function theme-color($color-name, $variant: base) {
  @return map-get(map-get($theme-colors, $color-name), $variant);
}

.btn-primary {
  background: theme-color(primary);
  color: theme-color(primary, contrast);

  &:hover {
    background: theme-color(primary, dark);
  }
}

2. نقاط التوقف المتجاوبة

نظام نقاط التوقف

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

@function breakpoint($name) {
  @if map-has-key($breakpoints, $name) {
    @return map-get($breakpoints, $name);
  }
  @warn "Breakpoint '#{$name}' not found";
  @return null;
}

@mixin respond-above($name) {
  $breakpoint: breakpoint($name);
  @if $breakpoint {
    @media (min-width: $breakpoint) {
      @content;
    }
  }
}

.container {
  width: 100%;

  @include respond-above(md) {
    max-width: 720px;
  }

  @include respond-above(lg) {
    max-width: 960px;
  }

  @include respond-above(xl) {
    max-width: 1140px;
  }
}

3. مقياس Z-Index

إدارة Z-Index

$z-layers: (
  base: 1,
  dropdown: 100,
  sticky: 200,
  fixed: 300,
  modal-backdrop: 400,
  modal: 500,
  popover: 600,
  tooltip: 700,
  toast: 800
);

@function z($layer) {
  @if map-has-key($z-layers, $layer) {
    @return map-get($z-layers, $layer);
  }
  @warn "Z-index layer '#{$layer}' not found";
  @return 1;
}

.dropdown-menu {
  z-index: z(dropdown);
}

.modal {
  z-index: z(modal);
}

.tooltip {
  z-index: z(tooltip);
}

4. نظام المسافات

مسافات متسقة

$spacing: (
  none: 0,
  xs: 0.25rem,
  sm: 0.5rem,
  md: 1rem,
  lg: 1.5rem,
  xl: 2rem,
  xxl: 3rem,
  xxxl: 4rem
);

@each $name, $value in $spacing {
  .gap-#{$name} { gap: $value; }
  .space-x-#{$name} > * + * { margin-left: $value; }
  .space-y-#{$name} > * + * { margin-top: $value; }
}

// دالة مسافات مخصصة
@function space($size) {
  @return map-get($spacing, $size);
}

.card {
  padding: space(md);
  margin-bottom: space(lg);
}

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

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

  1. عرّف خريطة $colors بألوان: primary، secondary، success، danger، warning، وinfo
  2. يجب أن يحتوي كل لون على خريطة متداخلة بقيم: base، light، lighter، dark، darker
  3. أنشئ دالة color() تقبل اسم اللون والمتغير
  4. ولّد فئات أزرار لكل لون باستخدام @each
  5. يجب أن يحتوي كل زر على حالات تمرير باستخدام المتغير الداكن

تمرين 2: طباعة متجاوبة

ابنِ نظام طباعة متجاوب:

  1. أنشئ خريطة $font-sizes بمستويات العناوين (h1-h6) ونص الجسم
  2. يجب أن يحتوي كل مفتاح على خريطة متداخلة بأحجام للهاتف المحمول والجهاز اللوحي وسطح المكتب
  3. أنشئ mixin يولّد أحجام خطوط متجاوبة باستخدام استعلامات @media
  4. طبّق mixin لتوليد أنماط لجميع عناصر العناوين
  5. أضف line-height و font-weight إلى هيكل الخريطة المتداخلة

تمرين 3: نظام الشبكة مع الخرائط

أنشئ نظام شبكة مرن باستخدام الخرائط:

  1. عرّف خريطة $grid-columns بأعداد الأعمدة: 1، 2، 3، 4، 6، 12
  2. أنشئ خريطة $grid-breakpoints (xs، sm، md، lg، xl)
  3. ولّد فئات الأعمدة: .col-1، .col-2، إلخ.
  4. ولّد فئات متجاوبة: .col-md-6، .col-lg-4، إلخ.
  5. أضف أدوات الفجوة باستخدام خريطة $grid-gaps

الملخص

في هذا الدرس، تعلمت:

  • كيفية إنشاء واستخدام خرائط SASS لتنظيم البيانات
  • الوصول إلى قيم الخريطة باستخدام map-get() و map.get()
  • التحقق من المفاتيح باستخدام map-has-key()
  • استخراج المفاتيح والقيم باستخدام map-keys() و map-values()
  • دمج الخرائط باستخدام map-merge() لأنظمة التكوين
  • إزالة المفاتيح باستخدام map-remove()
  • إنشاء والوصول إلى الخرائط المتداخلة للبيانات المعقدة
  • التكرار عبر الخرائط باستخدام @each لتوليد CSS
  • التطبيقات الواقعية: أنظمة السمات، نقاط التوقف، مقاييس z-index، المسافات

الخرائط ضرورية لبناء معماريات SASS قابلة للتطوير والصيانة. تمكّنك من إنشاء أنظمة تصميم متطورة، وإدارة تكوينات معقدة، وتوليد أنماط CSS متكررة بكفاءة. أتقن الخرائط وستفتح القوة الكاملة لـ SASS للمشاريع واسعة النطاق.