Миксины

Миксины (они же примеси) - это куски CSS кода, которые могут быть повторно использованы в любом месте CSS-документа. Они способны принимать аргументы, делая тем самым повторное их использование более гибким.

Для объявления миксинов используется директива @mixin. Объявление миксина представлено ниже.

Scss - файл, назовем его к примеру _mixins.scss
1 2 3 4 5 6 7 8 9

@mixin clearfix {

&::after {

content: ".";

display: block;

height: 0;

clear: both;

visibility: hidden;

}

}

Так сложилось, что в именах миксинов символы нижнего подчеркивания и дефисы взаимозаменяемы. К примеру миксин text-style можно подключить как text_style и наоборот.

Для того, чтобы вызвать миксин используется директива @include. Данная директива принимает имя миксина и передаваемые в него аргументы. Передачу аргументов в миксины мы рассмотрим чуть позже.

SCSS - файл
1

// Сперва импортируем наш миксин если он лежит в другом файле

2 3 4 5

@import "_mixins.scss";

.wrapper {

@include clearfix;

}

CSS - файл
1 2 3 4 5 6 7

.wrapper::after {

content: ".";

display: block;

height: 0;

clear: both;

visibility: hidden;

}

До этого моменты мы рассматривали применение миксинов в CSS-селекторах, но их можно применять и в корне документа, при условии, что они не используют ссылку на родителя и не определяют каких либо стилей. Давайте рассмотрим пример ниже.

SCSS - файл
1 2 3 4 5 6 7 8 9 10 11

@mixin headers {

.h1 {

color: blue

font-size: 24px

}

.h2 {

color: blue

font-size: 20px

}

}

@include headers;

CSS - файл
1 2 3 4 5 6 7 8

.h1 {

color: blue

font-size: 24px

}

.h2 {

color: blue

font-size: 20px

}

Как видно из примера, миксин headers вставляет заголовки в выходной CSS.

Аргументы в миксинах

В миксины возможно передавать аргументы. Аргументы передаются в круглых скобках, сразу после названия миксина и разделяются между собой запятыми.

Первоначально когда вводилась новая спецификация, для CSS3 создавались миксины с разными префиксами. Были даже целые библиотеки которые создавали кроссбраузерные свойства (к примеру compass). Сейчас необходимость в этом отпала. Давайте рассмотрим старый-старый миксин для свойства border-radius.

SCSS - файл
1

@mixin borderRadius($value) {

2

-moz-border-radius: $value; /* Firefox */

3

-webkit-border-radius: $value; /* Safari, Chrome */

4

-khtml-border-radius: $value; /* KHTML */

5

border-radius: $value; /* CSS3 */

6 7 8 9 10 11

}

.btn {

@include borderRadius(10px);

display: inline-block;

text-decoration: none;

}

CSS - файл
1

.btn {

2

-moz-border-radius: 10px;

3

-webkit-border-radius: 10px;

4

-khtml-border-radius: 10px;

5 6 7 8

border-radius: 10px;

display: inline-block;

text-decoration: none;

}

В миксинах так-же возможно задавать значения аргументов по умолчанию. Аргументы по умолчанию определяются так-же как и переменные. Давайте рассмотрим следующий пример.

SCSS - файл
1

@mixin borderRadius($value: 10px) {

2

-moz-border-radius: $value; /* Firefox */

3

-webkit-border-radius: $value; /* Safari, Chrome */

4

-khtml-border-radius: $value; /* KHTML */

5

border-radius: $value; /* CSS3 */

6 7 8 9 10 11

}

.btn {

@include borderRadius();

display: inline-block;

text-decoration: none;

}

CSS - файл
1

.btn {

2

-moz-border-radius: 10px;

3

-webkit-border-radius: 10px;

4

-khtml-border-radius: 10px;

5 6 7 8

border-radius: 10px;

display: inline-block;

text-decoration: none;

}

Из примера видно, что при вызове миксина, мы не передали в него аргумент, как следствие компилятор SASS применил значение по умолчанию, это значение в примере равно 10px. Если вы передаете в миксин несколько аргументов, то аргументы которые используют значения по умолчанию, должны следовать после аргументов которые значения по умолчанию не используют. В JS применяется то-же правило.

SCSS - файл
1

@mixin styledBlock($value, $bgColor: blue, $color: #fff) {

2

-moz-border-radius: $value; /* Firefox */

3

-webkit-border-radius: $value; /* Safari, Chrome */

4

-khtml-border-radius: $value; /* KHTML */

5

border-radius: $value; /* CSS3 */

6

background-color: $bgColor;

7

color: $color;

8 9 10 11

}

.styled-block {

@include styledBlock(10px, #000);

}

CSS - файл
1

.styled-block {

2

-moz-border-radius: 10px;

3

-webkit-border-radius: 10px;

4

-khtml-border-radius: 10px;

5 6 7 8

border-radius: 10px;

background-color: #000;

color: #fff;

}

Как видно из примера выше, в нашем миксине мы не задаем значение по умолчанию для свойства border-radius, а для свойств background-color и color, мы значения по умолчанию задаем, у нас синий фон и белый текст на нем. Пусть по умолчанию будет так. Вызвав наш миксин с 2 параметрами, мы тем самым задали значение для свойства border-radius, переопределили значение для свойства background-color. Так как третье свойство мы не задали, то оно у нас взялось по умолчанию. В итоге мы получили блок с черным фоном и белым текстом на нем. Впринципе так можно делать, но вообще лучше использовать именованные аргументы, так наш код будет более гибким. Давайте посмотрим как это можно сделать.

SCSS - файл
1

@mixin styledBlock($value: 10px, $bgColor: blue, $color: #fff) {

2

-moz-border-radius: $value; /* Firefox */

3

-webkit-border-radius: $value; /* Safari, Chrome */

4

-khtml-border-radius: $value; /* KHTML */

5

border-radius: $value; /* CSS3 */

6

background-color: $bgColor;

7

color: $color;

8 9 10 11

}

.styled-block {

@include styledBlock($color: #000);

}

CSS - файл
1

.styled-block {

2

-moz-border-radius: 10px;

3

-webkit-border-radius: 10px;

4

-khtml-border-radius: 10px;

5 6 7 8

border-radius: 10px;

background-color: blue;

color: #000;

}

В примере выше мы задали значения по умолчанию для всех трех свойств. Если мы применим наш миксин без аргументов, то у нас должен получиться блок с синим фоном, белым текстом, и значение border-radius будет равно 10px, это по умолчанию. При вызове нашего миксина мы переопределили только цвет текста ($color: #000), соответственно только это свойство у нас и переопределилось. В итоге мы получаем синий блок с черным текстом и значение border-radius будет равно 10px. Что тут можно сказать, последний способ более длинный, но зато он и более понятный. По опыту могу сказать, что если вы передаете более 3 параметров, и для разных блоков разные параметры меняются, то лучше использовать именованные аргументы, и вызывать миксины с именами переопределяемых свойств.

Переменные аргументов

Иногда мы не можем знать сколько аргументов будет передано в миксин. Для этого можно воспользоваться следующим приемом.

SCSS - файл
1 2 3 4 5 6 7

@mixin box-shadow($borderColor, $shadows...) {

border-color: $borderColor;

-moz-box-shadow: $shadows;

-webkit-box-shadow: $shadows;

box-shadow: $shadows;

}

.shadows {

8
@include box-shadow(#000, 0px 4px 5px #666, 2px 6px 10px #999);
9
}
CSS - файл
1

.shadows {

2

border-color: #000;

3

-moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;

4

-webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;

5

box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;

6

}

В примере выше, мы передали последний аргумент в наш миксин следующим образом $shadows..., если дословно переводить официальную документацию, то это называется "переменные аргументов". Если называть это своими словами, то переменные аргументов должны передаваться последними в миксин. Они получают все остальные параметры и упаковывают их в список. Они выглядят как обычные, но после них ставится многоточие (правильнее сказать 3 точки). В нашем примере, первая переменная определит border-color, а все, что мы введем дальше пойдет в переменную $shadow. Так я думаю будет понятнее. Если вы знаете JS, то наверное увидели аналог со spread оператором, только три точки ставятся не в начале, а в конце аргумента. Давайте рассмотрим следующий пример.

SCSS - файл
1

@mixin styleFont($fontSize, $fontWeight, $fontStyle) {

2

font: $fontStyle $fontWeight #{$fontSize}px/120% Arial, sans-serif;

3 4 5 6 7

}

$val: 12, bold, italic;

.blog {

@include styleFont($val...);

}

8

$val-map: (fontSize: 14, fontWeight: bold, fontStyle: italic);

9 10 11

.news {

@include styleFont($val-map...);

}

CSS - файл
1

.blog {

2

font: italic bold 12px/120% Arial, sans-serif;

3 4

}

.news {

5

font: italic bold 14px/120% Arial, sans-serif;

6

}

В данном примере мы добавляем через миксин значения для шрифта. В переменной $val, мы перечислили данные значения. При помощи переменных аргументов мы применили их при вызове миксина в блоке .blog. Сделали мы это так-же через оператор многоточия после переменной. Во втором примере мы передали карту значений $val-map, мы так же применили их через оператор многоточия. Какой вариант лучше применять, смотрите сами, можно и так, и так.

Возможна передача блока стилей в миксин. Давайте посмотрим как это делается.

SASS - файл
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

@mixin keyframes ($name) {

@-webkit-keyframes #{$name} {

@content;

}

@-moz-keyframes #{$name} {

@content;

}

@-ms-keyframes #{$name} {

@content;

}

@keyframes #{$name} {

@content;

}

}

@include keyframes(balloon) {

50% {

top: 172px;

height: 77px;

margin-left: 235px;

}

70% {

top: 180px;

margin-left: -281px;

}

100% {

top: 22px;

height: 50px;

margin-left: -1072px;

}

}

CSS - файл
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364

@-webkit-keyframes balloon {

50% {

top: 172px;

height: 77px;

margin-left: 235px;

}

70% {

top: 180px;

margin-left: -281px;

}

100% {

top: 22px;

height: 50px;

margin-left: -1072px;

}

}

@-moz-keyframes balloon {

50% {

top: 172px;

height: 77px;

margin-left: 235px;

}

70% {

top: 180px;

margin-left: -281px;

}

100% {

top: 22px;

height: 50px;

margin-left: -1072px;

}

}

@-ms-keyframes balloon {

50% {

top: 172px;

height: 77px;

margin-left: 235px;

}

70% {

top: 180px;

margin-left: -281px;

}

100% {

top: 22px;

height: 50px;

margin-left: -1072px;

}

}

@keyframes balloon {

50% {

top: 172px;

height: 77px;

margin-left: 235px;

}

70% {

top: 180px;

margin-left: -281px;

}

100% {

top: 22px;

height: 50px;

margin-left: -1072px;

}

}

Пример выше - это старый вывод миксина для свойства keyframes. С 1 по 14 строчку мы определяем миксин, с 15 по 30 строчку мы его вызываем. Обратите внимание на директиву @content, благодаря ей все, что будет написано в миксине между фигурными скобками, будет подставлено на место данной директивы при компиляции CSS-файла.

В принципе мы освоили миксины. Не трудно догадаться, что они очень широко применялись, когда только-только появился CSS3. Сейчас autoprefix-ер позволяет значительно сократить их использование. Если вы во время работы видите, что у каких-либо блоков есть похожие стили, я рекомендую вынести их в миксины. Раньше моим самым часто используемым миксином был clearfix, сейчас я в миксин вынес пару стилей для выравнивания элементов на flex. Что выносить в миксины вы поймете со временем, как говорится больше практики.