Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос нашим менторам. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Миксины как функции

Второй, и наверное главной особенностью миксинов является то, что они могут принимать аргументы, которые могут быть использованы внутри. В программировании такие участки кода называются функциями. Они призваны облегчить переиспользование кода. Как же нам использовать это в SASS? Возьмём простой класс mx-10, который делает отступы слева и справа на 10 пикселей.

.mx-10 {
  margin-right: 10px;
  margin-left: 10px;
}

Что делать, если мы захотим добавить больше таких классов? Например .mx-5, mx-10, mx-15, mx-20 и так далее. Конечно можно руками прописать все нужные нам классы и задать им свойства. Но это достаточно монотонный и долгий процесс. Попробуем для начала вынести свойства margin-left и margin-right в миксин, чтобы не было необходимости каждый раз их указывать.

@mixin margin-x {
  margin-right: 10px;
  margin-left: 10px;
}

.mx-10 {
  @include margin-x;
}

Кажется, что мало того, что ничего особо не поменялось, так мы ещё и добавили лишний код. Как нам это поможет в выносе дублирующего кода? Тут на сцену и выходит особенность миксинов принимать аргументы. Аргумент — некая переменная, от которой зависит результат выполнения функции. Аргументы указываются в круглых скобках и могут иметь любое имя. Каждый аргумент указывается с ключевым символом $. Если аргументов несколько, то они перечисляются через запятую. Добавим два аргумента в наш миксин. Первый аргумент будет указывать на значение свойства margin-right, а второй аргумент на значение свойства margin-left.

@mixin margin-x($mr, $ml) {
  margin-right: 10px;
  margin-left: 10px;
}

.mx-10 {
  @include margin-x;
}

Вторым шагом по превращению простого миксина в функцию является подстановка аргументов в свойства внутри миксина. Для этого вместо значений свойств подставим нужные нам аргументы.

@mixin margin-x($mr, $ml) {
  margin-right: $mr;
  margin-left: $ml;
}

.mx-10 {
  @include margin-x;
}

Если попробовать сейчас скомпилировать этот код, то получим следующую ошибку:

Error: Missing argument $mr.
  ╷
7 │   @include margin-x;
  │   ^^^^^^^^^^^^^^^^^^^
  ╵

Препроцессор сообщает нам, что отсутствует аргумент $mr. Это значит, что как только мы в миксин добавляем аргументы, то вызов без них невозможен. Даже если сами аргументы не будут использованы в миксине. Поправим ошибку и добавим 2 аргумента при вызове миксина. Аргументы также указываются в круглых скобках и туда мы помещаем то значение, которое ожидаем. В данном случае 10px.

@mixin margin-x($mr, $ml) {
  margin-right: $mr;
  margin-left: $ml;
}

.mx-10 {
  @include margin-x(10px, 10px);
}

После компиляции мы получим именно тот код, который и хотели получить с самого начала:

.mx-10 {
  margin-right: 10px;
  margin-left: 10px;
}

Разница теперь в том, что мы можем удобно писать новые классы без постоянного дублирования свойств.

@mixin margin-x($mr, $ml) {
  margin-right: $mr;
  margin-left: $ml;
}

.mx-10 {
  @include margin-x(10px, 10px);
}

.mx-15 {
  @include margin-x(15px, 15px);
}

.mx-20 {
  @include margin-x(20px, 20px);
}

.mx-25 {
  @include margin-x(25px, 25px);
}

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

@mixin margin-x($margin) {
  margin-right: $margin;
  margin-left: $margin;
}

.mx-10 {
  @include margin-x(10px);
}

.mx-15 {
  @include margin-x(15px);
}

.mx-20 {
  @include margin-x(20px);
}

.mx-25 {
  @include margin-x(25px);
}

Это хорошая практика, если свойства «родственны» друг другу. Использовать один аргумент для передачи, например, свойства height и margin-top не очень хорошая идея, даже если они и имеют одно значение. Так вы внесёте путаницу в код и уменьшите собственные возможности по кастомизации селекторов.

В прошлом примере было показано, что случится, если не указать аргумент при вызове миксина. На самом деле это не всегда вызовет ошибку, так как миксины могут принимать аргументы по умолчанию. Если при вызове миксина не было указано никаких аргументов, то препроцессор будет пользоваться именно ими. Эти аргументы указываются непосредственно при создании миксина и перечислении аргументов. Всё, что нам нужно — указать значения, как у простой переменной. Это схоже с тем, как у переменной устанавливался флаг !default.

@mixin margin-x($margin: 10px) {
  margin-right: $margin;
  margin-left: $margin;
}

.mx-10 {
  @include margin-x();
}

Так как мы не указали аргументы при вызове миксина, то компилятор заберёт значение по умолчанию, которое было указано при создании миксина. После компиляции получится следующий CSS-код:

.mx-10 {
  margin-right: 10px;
  margin-left: 10px;
}

Использовать возможность миксинов принимать аргументы сильно помогает при создании шаблонов свойств с вендорными префиксами. В прошлом уроке мы посмотрели, как сделать миксин со свойством box-shadow и его вендорными префиксами. Использовав возможность указывать аргументы, мы можем сильно сократить наш код при повторном использовании с другими значениями.

@mixin box-shadow-prefix ($value) {
  -webkit-box-shadow: $value;
  -moz-box-shadow: $value;
  box-shadow: $value;
}

.box-shadow-small {
  @include box-shadow-prefix (3px 3px 3px 0px rgba(204,204,204,1));
}

.box-shadow-medium {
  @include box-shadow-prefix (7px 7px 3px 0px rgba(204,204,204,1));
}

.box-shadow-big {
  @include box-shadow-prefix (10px 10px 3px 0px rgba(204,204,204,1));
}

После компиляции мы получим следующий CSS:

.box-shadow-small {
  -webkit-box-shadow: 3px 3px 3px 0px #cccccc;
  -moz-box-shadow: 3px 3px 3px 0px #cccccc;
  box-shadow: 3px 3px 3px 0px #cccccc;
}

.box-shadow-medium {
  -webkit-box-shadow: 7px 7px 3px 0px #cccccc;
  -moz-box-shadow: 7px 7px 3px 0px #cccccc;
  box-shadow: 7px 7px 3px 0px #cccccc;
}

.box-shadow-big {
  -webkit-box-shadow: 10px 10px 3px 0px #cccccc;
  -moz-box-shadow: 10px 10px 3px 0px #cccccc;
  box-shadow: 10px 10px 3px 0px #cccccc;
}

Передача свойств в миксин

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

Передать контент в миксин можно следующим образом:

@include mixin-name($arg1, $arg2) {
  // Контент, который будет передан в миксин.
}

Получить этот контент внутри миксина можно с помощью конструкции @content, которая возьмёт всё тело из вызова миксина и добавит его туда, где была указана конструкция @content.

@mixin btn {
  display: block;
  padding: 20px;

  font-weight: bold;
  font-size: 0.8em;
  color: #333;

  @content;
}

.btn {
  @include btn() {
    &.btn-blue {
      background: #42a5f5;
      color: #fff;
    }
  }
}

После компиляции мы получим следующий CSS код:

.btn {
  display: block;
  padding: 20px;
  font-weight: bold;
  font-size: 0.8em;
  color: #333;
}

.btn.btn-blue {
  background: #42a5f5;
  color: #fff;
}

<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят менторы из команды Хекслета или другие студенты.

Для полного доступа к курсу нужна профессиональная подписка

Профессиональная подписка откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, даст возможность обращаться за помощью к менторам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
115
курсов
892
упражнения
2241
час теории
3196
тестов

Зарегистрироваться

или войти в аккаунт

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 115 курсов, 2000+ часов теории
  • 800 практических заданий в браузере
  • 250 000 студентов

Нажимая кнопку «Зарегистрироваться», вы даёте своё согласие на обработку персональных данных в соответствии с «Политикой конфиденциальности» и соглашаетесь с «Условиями оказания услуг». Защита от спама reCAPTCHA «Конфиденциальность» и «Условия использования».

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Нажимая кнопку «Зарегистрироваться», вы даёте своё согласие на обработку персональных данных в соответствии с «Политикой конфиденциальности» и соглашаетесь с «Условиями оказания услуг». Защита от спама reCAPTCHA «Конфиденциальность» и «Условия использования».