المخاليط (Mixins) في Sass

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث

تتيحُ المخاليط تعريف الأنماط التي يمكن إعادة استخدامها في ملف الأنماط دون اللجوء إلى الأصناف غير الدلاليَّة مثلِ ‎.float-left. يمكن أن تحوي المخاليط أيضًا جميع قواعد CSS وأيَّ شيء آخر يُسمح باستعماله في ملفات Sass. يمكن أيضًا أن يُمرَّر لها معاملات (arguments) وبذلك يمكن إنتاج مجموعة واسعة من الأنماط بعدد قليل من المخاليط.

تعريف المخلوط (Defining a Mixin):‏ ‎@mixin

تعرَّف المخاليط (Mixins) بوساطة التعليمة ‎@mixin متبوعةً باسم المخلوط، ويمكن اختياريًا إضافة معاملات له، ثمّ كتلة من الأنماط تتضمّن محتويات المخلوط. يُعرّف مثلًا المخلوط large-text على النحو التالي:

@mixin large-text {
  font: {
    family: Arial;
    size: 20px;
    weight: bold;
  }
  color: #ff0000;
}

قد تحتوي المخاليط أيضًا على مُحدّدات، وعلى خاصِّيَّات أحيانًا. بل يمكن أن تحتوي المُحدّدات على مؤشرات أبوية (parent references). انظر الشيفرة التالية مثلًا:

@mixin clearfix {
  display: inline-block;
  &:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
  }
  * html & { height: 1px }
}

يمكن أن تحتوي أسماء المخاليط (وجميع مُعرّفات Sass الأخرى)، لأسباب تاريخيَّة، على الشرطات العاديَّة (hyphens) والشرطات السفليَّة (underscores) دون فرقٍ بينها. على سبيل المثال، إن عرّفت مخلوطًا باسم add-column، فيمكنك الإشارة إليه أيضًا بالاسم add_column، والعكس بالعكس.

تضمين المخاليط: ‎@include

تُضمّن المخاليط في الملف عبر التعليمة ‎@include. تأخذ هذه التعليمة اسم مخلوطٍ ما ومعامل اختياري إن وجد، وتضمِّن الأنماط التي يُعرّفها المخلوط في القاعدة الحاليَّة. انظر مثلًا الشيفرة التالية:

.page-title {
  @include large-text;
  padding: 4px;
  margin-top: 10px;
}

ستُصرّف إلى:

.page-title {
  font-family: Arial;
  font-size: 20px;
  font-weight: bold;
  color: #ff0000;
  padding: 4px;
  margin-top: 10px; }

يُمكن أيضًا أن تُدرج المخاليط خارج كل القواعد (أي على مستوى جذر المستند) طالما أنّها لا تُعرِّف مباشرةً أيَّ خاصِّيَّات أو تستخدم أيَّ مؤشّرات أبوية مثل:

@mixin silly-links {
  a {
    color: blue;
    background-color: red;
  }
}

@include silly-links;

ستُصرّف الشيفرة السابقة إلى:

a {
  color: blue;
  background-color: red; }

يمكن تضمين مخاليط أخرى عند تعريف المخلوط مثل:

@mixin compound {
  @include highlighted-background;
  @include header-text;
}

@mixin highlighted-background { background-color: #fc0; }
@mixin header-text { font-size: 20px; }

قد تستطيع المخاليط تضمين نفسَها إلا أنَّ هذا مُخالفٌ لسلوك الإصدارات السابقة للإصدار Sass 3.3، إذ كانت المخاليط التعاوديَّة (mixin recursion) ممنوعةً.

المخاليط التي لا تعرّف إلّا المحدَّدات المنحدرة (descendant selectors) يمكن أن تُخلط بأمانٍ في المستوى الأعلى من المستند.

المعاملات (Arguments)

يُمكن أن تأخذ المخاليط قيم SassScript كمعاملات والتي تمرَّر إليها عند تضمين المخلوط، إذ تُتاح داخل المخلوط بوصفها متغيراتٍ.

عند تعريف مخلوطٍ ما، تُكتب المعاملات كأسماء متغيرات مفصولةٍ بفواصل وموضوعةٍ كلّها بين قوسين بعد الاسم ثمَّ تُمرَّر قيم تلك المعاملات عند تضمين المخلوط بنفس الطريقة. انظر المثال التالي:

@mixin beautiful-border($color, $width) {
  border: {
    color: $color;
    width: $width;
    style: dashed;
  }
}

p { @include beautiful-border(blue, 1in); }

سيصرّف إلى:

p {
  border-color: blue;
  border-width: 1in;
  border-style: dashed; }

يمكن للمخاليط أيضًا تعيين قيم افتراضيَّة للمعاملات وذلك باستخدام الصياغة العاديَّة لتعيين المتغيرات. إذا لم يُمرّر المعامل حينئذٍ عند تضمين المخلوط، فستُستخدم تلك القيمة الافتراضيَّة. انظر مثلًا الشيفرة التالية:

@mixin beautiful-border($color, $width: 1in) {
  border: {
    color: $color;
    width: $width;
    style: dashed;
  }
}
p { @include beautiful-border(blue); }
h1 { @include beautiful-border(blue, 2in); }

ستُصرّف إلى:

p {
  border-color: blue;
  border-width: 1in;
  border-style: dashed; }

h1 {
  border-color: blue;
  border-width: 2in;
  border-style: dashed; }

الوسائط المُسمّاة (Keyword Arguments)

يمكن أيضًا استخدام الوسائط المُسمّاة صراحةً عند تضمين المخاليط. يمكن أن يُكتب المثال السابق مثلًا على النحو التالي:

p { @include beautiful-border($color: blue); }
h1 { @include beautiful-border($color: blue, $width: 2in); }

في حين أنّ هذا قد يكون أقل إيجازًا إلّا أنه سيجعل ملف الأنماط أسهل للقراءة، وسيسمح للدوال بتقديم واجهاتٍ أكثر مرونةً لتوفير العديد من الوسائط دون أن تكون هناك صعوبةٌ في استدعائها.

يمكن تمرير الوسائط المسماة وفق أيِّ ترتيبٍ، كما يجوز حذف الوسائط ذات القيم الافتراضيَّة. لمّا كانت الوسائطُ المسمّاة هي أسماءُ متغيراتٍ، فلا فرق بين استخدام الشرطات العاديَّة والشرطات السفليّة.

الفاصلة الزائدة (Trailing Commas)

إذا كان الوسيط الأخير لمخلوطٍ أو دالةٍ وسيطًا موضعيًا (positional) أو مُسمًّى، فيُمكن أن يعقُب ذلك الوسيط فاصلةٌ زائدةٌ. يُفضّل البعض هذا الأسلوب في البرمجة لأنَّه يمكن أن يؤدي إلى تقليل الاختلافات والأخطاء في الصياغة عند تصريف الملف.

المعاملات المتغيرة (Variable Arguments)

يفضل أحيانًا ألّا يُحدَّد عدد معاملات المخلوط أو الدالة. على سبيل المثال، قد يأخذ مخلوطٌ مُخصّصٌ لإنشاء ظلال المربعات أيَّ عددٍ من الظلال كمعاملات. تدعم Sass في تلك الحالات "المعاملات المتغيرة"، وهي المعاملات الموجودة في تصريح مخلوطٍ أو دالةٍ التي تأخذ كلَّ المعاملات الإضافية المتبقيَّة وتجمعها في قائمة. تبدو هذه المعاملات مثل المعاملات العاديَّة ولكنّها متبوعةٌ بثلاث نقاط (…). يوضح المثال التالي ذلك:

@mixin box-shadow($shadows...) {
  -moz-box-shadow: $shadows;
  -webkit-box-shadow: $shadows;
  box-shadow: $shadows;
}

.shadows {
  @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}

سيصرّف إلى:

.shadows {
  -moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  -webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
}

تحتوي المعاملات المتغيرة أيضًا على كلِّ الوسائط المسمّاة المُمرّرةِ إلى المخلوط أو الدالة، ويمكن الوصول إليها باستعمال الدالة keywords($args)‎ التي تُعيدها كخرائط (maps) إذ تربط أسماء المعاملات (بدون $) بقيمها. يمكن أيضًا أن تُستخدم المعاملات المتغيرة عند استدعاء المخلوط. يمكنك استخدام نفس الصياغة لتوسيع قائمةٍ مكوّنةٍ من قيم بحيث تُمرّر كل قيمة كمعامل منفصل، أو لتوسيع خريطة (map) مكوّنة من قيم بحيث يُعامَل كل زوجٍ وكأنّه معامل مُسمّى. انظر مثلًا الشيفرة التالية:

@mixin colors($text, $background, $border) {
  color: $text;
  background-color: $background;
  border-color: $border;
}

$values: #ff0000, #00ff00, #0000ff;
.primary {
  @include colors($values...);
}

$value-map: (text: #00ff00, background: #0000ff, border: #ff0000);
.secondary {
  @include colors($value-map...);
}

ستُصرّف إلى:

.primary {
  color: #ff0000;
  background-color: #00ff00;
  border-color: #0000ff;
}

.secondary {
  color: #00ff00;
  background-color: #0000ff;
  border-color: #ff0000;
}

يمكنك أن تُمرّر قائمةً وخريطة من المعاملات في آن واحد شرط أن تُمرَّر القائمة قبل الخريطة، مثل ‎@include colors($values..., $map...)‎. يمكنك استخدام المعاملات المتغيرة لتغليف (wrap) المخلوط وإضافة أنماط إضافيَّةٍ دون تغيير شكل معاملات المخلوط. إن فعلت ذلك، فستُمرّر الوسائط المُسمّاة مباشرةً إلى المخلوط المُغلَّف (wrapped mixin) مثل:

@mixin wrapped-stylish-mixin($args...) {
  font-weight: bold;
  @include stylish-mixin($args...);
}

.stylish {
  // سيُمرَّر الوسيط
  // $width
  // كوسيط إلى المخلوط
  // stylish-mixin
  @include wrapped-stylish-mixin(#00ff00, $width: 100px);
}

تمرير كتل الأنماط إلى المخلوط

من الممكن تمرير كتلةٍ من الأنماط إلى المخلوط لوضعها داخل الأنماط المُدرجة في المخلوط. ستظهر الأنماط في مكان التعليمة ‎@content الموجودة داخل المخلوط، وهذا سيجعل من الممكن تحديد أشكال مُجرّدةٍ متعلقة بإنشاء المُحدّدات والتعليمات. انظر مثلًا إلى المثال التالي:

@mixin apply-to-ie6-only {
  * html {
    @content;
  }
}
@include apply-to-ie6-only {
  #logo {
    background-image: url(/logo.gif);
  }
}

سيصرّف إلى:

* html #logo {
  background-image: url(/logo.gif);
}

يمكن إنشاء نفس المخاليط باستخدام الصياغة المختصرة الخاصَّة بملفات ‎.sass مثل:

=apply-to-ie6-only
  * html
    @content

+apply-to-ie6-only
  #logo
    background-image: url(/logo.gif)

ملاحظة: عندما تتواجد التعليمة ‎@content أكثر من مرة واحدة أو تُستعمل في حلقة (loop)، فستُكرّر حينئذٍ كتلة الأنماط عند كل استدعاء.

قد تتطلب بعض المخاليط أن تُمرّر إليها كتلةٌ من الأنماط وإلّا ستسلك سلوكًا مختلفًا. ستُعيد الدالة content_exists()‎ القيمة TRUE في حالة تمرير كتلة من الأنماط إلى المخلوط الحالي، ويمكن استخدامها لمعرفة السلوك المنفَّذ آنذاك.

نطاقات المتغيرات وكتل الأنماط (Variable Scope and Content Blocks)

تُحدَّد قيمة كتل الأنماط التي مُرِّرت إلى المخلوط داخل النطاق حيث عُرِّفت الكتلة وليس في نطاق المخلوط. هذا يعني أنّ المتغيرات المحليَّة في المخلوط لا يمكن استخدامها داخل كتلة الأنماط التي مُرِّرت وستُحال المتغيرات إلى القيمة الكليّة (global value).

$color: white;
@mixin colors($color: blue) {
  background-color: $color;
  @content;
  border-color: $color;
}
.colors {
  @include colors { color: $color; }
}

ستُصرّف الشيفرة السابقة إلى:

.colors {
  background-color: blue;
  color: white;
  border-color: blue;
}

إضافةً إلى ذلك، هذا يجعل من الواضح أنّ المتغيرات والمخاليط المُستخدمة داخل كتلة الأنماط المُمرّرة تتعلق بالأنماط الأخرى المُجاورة حيثُ عُرِّفت الكتلة مثل:

#sidebar {
  $sidebar-width: 300px;
  width: $sidebar-width;
  @include smartphone {
    width: $sidebar-width / 3;
  }
}

مصادر