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

من موسوعة حسوب
مراجعة 05:32، 10 أبريل 2018 بواسطة عبد اللطيف ايمش (نقاش | مساهمات) (إضافة عنوان الصفحة والتصنيفات)

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

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

تُعرّف المخاليط (Mixins) بواسطة الموجّه ‎@mixin، متبوعًا باسم المخلوط، ويمكن اختياريًا إضافة وسائط (arguments)، ثمّ كتلةٌ من الأنماط تتضمّن محتويات المخلوط. على سبيل المثال، يُعرّف المخلوط 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; }

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

@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) ممنوعةً.

المخاليط التي لا تعرّف إلّا المحددات المُنحدرة (descendent 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)‎، التي تُعيدها كقواميس تربط سلاسل نصّية (أسماء الوسائط بدون $) بقيمٍ (الوسائط). ويمكن أيضًا أن تُستخدم الوسائط المتغيرة عند استدعاء المخلوط. فباستخدام نفس الصياغة، يمكنك توسيع قائمةٍ مكوّنةٍ من قيم بحيث تُمرّر كل قيمة كوسيط منفصل، أو توسيع قاموسٍ مكوّن من قيم بحيث يُعامَل كل زوجٍ وكأنّه وسيطٌ مُسمّى. على سبيل المثال:

@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;
  }
}

مصادر