Условные конструкции

Если вы изучали любой язык программирования, то знаете, что одним из самых распространённых элементов в них является условная конструкция if/else. Что же эта конструкция позволяет делать? Условная конструкция позволяет выполнять тот или иной участок кода в зависимости от того, является ли истинным условие внутри этой конструкции.

Перед тем, как пойти дальше разберёмся с понятиями, которые были введены выше:

  • Условная конструкция — конструкция, которая направляет работу скрипта по одному из нескольких путей, в зависимости от того, истинно ли условие внутри конструкции.
  • Условие — любое выражение, которое можно свести либо к истинности, либо ко лжи. Например выражение 2 + 2 = 4 истинно, а 2 + 5 = 1 нет.

Разберём простой пример с миксинами. Пускай дизайнер прислал нам макет с двумя разными цветовыми схемами: светлой и тёмной. В зависимости от того, что указано в настройках проекта нам надо использовать или одну или другую цветовую схему.

Опишем в миксине card обе цветовые схемы, которые прислал дизайнер. Попробуем сделать две схемы с теми знаниями, которые мы имеем сейчас:

@mixin card {
  // Цвета для светлой темы
  $primary-color: #f9f9f9;
  $text-color: #424242;

  // Цвета для тёмной темы
  $primary-color-dark: #161625;
  $text-color-dark: #e1e1ff;

  .card {
    .card-body {
      &.light {
        background: $primary-color;
        color: $text-color;
      }

      &.dark {
        background-color: $primary-color-dark;
        color: $text-color-dark;
      }
    }
  }
}

Получилась достаточно грубая конструкция. Выбор цветовой схемы мы возлагаем на классы light и dark. Получается, что для всех элементов придётся использовать такие конструкции и добавлять классы. Это приведёт к ужасной путанице и постоянным проблемам в виде забывчивости проставления класса для элемента. Подход полностью рабочий, но создаст дополнительные проблемы. Возможно ещё ввести более глобальные классы light-theme или dark-theme для body, но таким образом мы получим большие участки кода с разными оформлениями, за которыми так же тяжело следить.

Как здесь может помочь SASS? Мы можем использовать условные конструкции и объявить изначальную настройку темы проекта в виде отдельной переменной заранее. В дальнейшем эта настройка будет влиять на весь проект целиком. Согласитесь, что удобнее управлять выбором теме изменением всего одной переменной. Как же этого добиться?

Для этого введём переменную $dark-mode со значением true. Как мы помним, это булевый тип данных, который может принимать одно из двух значений. В данном случае значение true обозначает истинность. Значит мы хотим использовать тёмную тему.

$dark-mode: true;

Теперь нам поможет конструкция @if у которой, в скобках, мы поставим условие на истинность переменной $dark-mode. Это можно сделать с помощью оператора ==. Все такие операторы будут рассмотрены чуть ниже. Вернём наш миксин и добавим условие.

$dark-mode: true;

@mixin card {
  // Цвета для светлой темы
  $primary-color: #f9f9f9;
  $text-color: #424242;

  @if ($dark-mode == true) {
    // Если условие сработает, то мы просто перезапишем значения переменных.
    $primary-color: #161625;
    $text-color: #e1e1ff;
  }

  .card {
    .card-body {
      background: $primary-color;
      color: $text-color;
    }
  }
}

Что здесь произошло? В самом начале миксина мы определили базовые цвета «по умолчанию». Это были настройки светлой темы. Ниже появилась условная конструкция if в которой мы проверяем равно ли значение переменной $dark-mode true. Так как мы установили это значение в самом начале нашего кода, то переменные $primary-color и $text-color внутри миксина card перезапишутся на те, которые указаны в теле условия.

При использовании оператора @if получается одно из двух значений:

  • true — выражение внутри оператора истинно и тогда мы заходим в тело конструкции if.
  • false — выражение внутри оператора ложно и тогда мы игнорируем всё, что находится внутри конструкции if.

Результат компиляции файла SASS:

.card .card-body {
  background: #161625;
  color: #e1e1ff;
}

Операторы сравнения

В прошлом примере мы увидели один из операторов сравнения ==. Он указывается на равенство левой и правой части выражения. Если они равны, то возвращается true и компилятор заходит в тело конструкции внутри @if.

Помимо этого существуют ещё несколько операторов сравнения, которые важно знать:

  • != — не равно. Результат полностью противоположен оператору ==. Если левая и правая часть выражения не равны, то результат будет true.
  • > — левая часть выражения больше правой.
  • >= — левая часть выражения больше, либо равна правой.
  • < — левая часть выражения меньше правой.
  • <= — левая часть выражения меньше, либо равна правой.

Где нам могут понадобиться такие выражения? Предположим, что у нас есть некоторое значение font-size, которое, при ширине viewport меньше 768px должно стать в полтора раза больше при условии, что оно меньше 16 пикселей.

$main-font-size: 14px;

html {
  font-size: $main-font-size;
}

body {
  padding: 1rem 3rem;
}

@media (max-width: 768px) {
  @if ($main-font-size < 16px) {
    html {
      font-size: $main-font-size * 1.5;
    }
  }
}

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

html {
  font-size: 14px;
}

body {
  padding: 1rem 3rem;
}

@media (max-width: 768px) {
  html {
    font-size: 21px;
  }
}

Теперь предположим, что где-то в проекте мы перезаписывали значение $main-font-size и установили его значение равное 16px:

$main-font-size: 14px;

html {
  font-size: $main-font-size;
}

body {
  padding: 1rem 3rem;
}

// 1000 строчек кода спустя

$main-font-size: 16px;

// И ещё десяток строчек спустя

@media (max-width: 768px) {
  @if ($main-font-size < 16px) {
    html {
      font-size: $main-font-size * 1.5;
    }
  }
}

Скомпилируем этот код и получим следующий CSS код:

html {
  font-size: 14px;
}

body {
  padding: 1rem 3rem;
}

Теперь условие $main-font-size < 16px вернуло false и компилятор не зашёл в тело условной конструкции, поэтому код внутри условной конструкции не был обработан.

Логические операторы

Помимо операторов сравнения в SASS так же существуют и логические операторы. Их намного меньше, не пугайтесь :) Логические операторы позволяют объединять несколько условий в одно большое выражение.

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

$dark-mode: true;
$device: 'mobile';

@mixin card {
  // Цвета для светлой темы
  $primary-color: #f9f9f9;
  $text-color: #424242;

  @if ($dark-mode == true) {
    // Если условие сработает, то мы просто перезапишем значения переменных.
    $primary-color: #161625;
    $text-color: #e1e1ff;
  }

  .card {
    .card-body {
      background: $primary-color;
      color: $text-color;
    }
  }
}

Каким образом нам проверить, что оба условия для выбора тёмной темы истины? Можно создать условную конструкцию внутри условной конструкции (привет фильму «Начало»).

$dark-mode: true;
$device: 'mobile';

@mixin card {
  // Цвета для светлой темы
  $primary-color: #f9f9f9;
  $text-color: #424242;

  @if ($dark-mode == true) {
    @if ($device == 'mobile') {
      // Если условия сработают, то мы просто перезапишем значения переменных.
      $primary-color: #161625;
      $text-color: #e1e1ff;
    }
  }

  .card {
    .card-body {
      background: $primary-color;
      color: $text-color;
    }
  }
}

Осторожно: не увлекайтесь вложенными условными конструкциями. Такие «лесенки» могут быть очень трудны для чтения. К тому же в них очень просто допустить ошибку при добавлении или удалении условия.

Избавиться от этой лесенки нам поможет логический оператор and. Он объединит оба условия и вернёт true при условии, что оба выражения вернут true. Нам достаточно добавить ключевое слово and между двумя выражениями следующим образом:

$dark-mode: true;
$device: 'mobile';

@mixin card {
  // Цвета для светлой темы
  $primary-color: #f9f9f9;
  $text-color: #424242;

  @if ($dark-mode == true and $device == 'mobile') {
    // Если условия сработают, то мы просто перезапишем значения переменных.
    $primary-color: #161625;
    $text-color: #e1e1ff;
  }

  .card {
    .card-body {
      background: $primary-color;
      color: $text-color;
    }
  }
}

Всего в SASS существует три логических оператора:

  • and ­— логический оператор «И». Вернёт true, если оба выражения истины.
  • or — логический оператор «ИЛИ». Вернёт true, если хотя бы одно выражение истинно.
  • not — логический оператор отрицания «НЕ». Вернёт true, если выражение ложно.

Оператор else

В самом начале урока говорилось, что мы изучаем условную конструкцию if/else. С if мы разобрались, теперь остался один вопрос: а что такое else? На самом деле всё проще, чем может показаться на первый взгляд. Блок кода внутри else выполнится, если выражение в if ложно. Всё что нам нужно — добавить конструкцию @else после блока с if. На примере с цветовыми схемами мы можем переписать код следующим образом:

$dark-mode: true;
$device: 'mobile';

@mixin card {
  @if ($dark-mode == true and $device == 'mobile') {
    // Если условия сработают, то мы просто перезапишем значения переменных.
    $primary-color: #161625;
    $text-color: #e1e1ff;
  } @else {
    // Цвета для светлой темы
    $primary-color: #f9f9f9;
    $text-color: #424242;
  }

  .card {
    .card-body {
      background: $primary-color;
      color: $text-color;
    }
  }
}

Вот и вся хитрость. Таким образом мы можем выбирать тот блок кода, который будет выполнен в зависимости от условия внутри оператора if. При этом обратите внимание, что зачастую можно обойтись без оператора else. Во всех примерах, кроме последнего мы перезаписывали значение переменной, если была выбрана тёмная тема. Это правильный подход, так как таким образом мы уверены в том, что по умолчанию будут установлены какие-то цвета и мы банально пишем меньше кода.

Мы учим программированию с нуля до стажировки и работы. Попробуйте наш бесплатный курс «Введение в программирование» или полные программы обучения по Javascript, PHP, Python и Java.

Хекслет

Подробнее о том, почему наше обучение работает →