Полный цикл в digital

Полный гайд по SCSS/SASS

В гайде будут разобраны препроцессоры:

  1. Sass
  2. SCSS

Концептуально разница между ними не велика, будем считать, что это одно и тоже. Вы поймёте различия по мере изучения темы. Отмечу, что SCSS сейчас наиболее популярна, вероятно потому, что является наиболее поздней версией оригинального Sass.

Всего существует 5 препроцессоров: Sass, SCSS, Less, Stylus и PostCSS.

Почему стоит выберать препроцессоры

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

Что есть в Sass/SCSS, чего нет в стандартном CSS

  1. Переменные — в стандартном CSS тоже есть понятие переменных, но в SASS с ними можно работать немного по-другому. Например, повторять их через директиву @for. Или генерировать свойства динамически, подробнее
  2. ВложенностьSCSS позволяет вкладывать правила CSS друг в друга. Вложенные правила применяются только для элементов, соответствующих внешним селекторам, а если речь идёт о SASS, то там и без скобок всё красиво и интуитивно понятно, подробнее
  3. Улучшенные математические операции — можно складывать, вычитать, умножать и делить значения CSS. В отличие от стандартного CSS, SASS/SCSS позволяют обойтись без calc(), подробнее
  4. ТригонометрияSCSS позволяет писать собственные синусоидальные и косинусоидальные функции, используя только синтаксис SASS/SCSS, подобно тому, как это можно делать в других языках вроде JavaScript
  5. Директивы - @for, @while и выражение @if-else — можно писать CSS код, используя знакомые элементы из других языков. Но не обольщайтесь — в итоге на выходе будет обычный CSS, подробнее
  6. Миксины (примеси) — можно один раз создать набор CSS свойств и работать с ними повторно или смешивать с другими значениями. Миксины можно использовать для создания отдельных тем одного макета. Примеси также могут содержать целые CSS правила или что-либо другое, разрешённое в SASS документе. Они даже могут принимать аргументы, что позволяет создавать большое разнообразие стилей при помощи небольшого количества миксинов, подробнее
  7. Функции — можно создавать определения CSS в виде функций для многократного использования, подробнее

Конвертация в командной строке

Расширения .sass и .scss похожи, но всё-таки не одинаковы. Ниже представлен способ конвертации SASS в SCSS и наоборот:

# конвертация Sass в SCSS
sass-convert style.sass style.scss
# конвертация SCSS в Sass
sass-convert style.scss style.sass

Переменные

В SASS и SCSS есть переменные, и они отличаются от переменных в CSS. В CSS переменные начинаются с двух тире --color: #9c27b0. В SCSS переменная обозначается знаком доллара $color: #9c27b0.

stule.scss$number: 1;
$color: #FF0000;
$text: "Test";
$text: "Test 2" !default;
$nothing: null;

Можно перезаписать имя переменной или задать для неё значение по умолчанию. Для этого добавьте метку !default к переменной, и если её значение не изменится в дальнейшем и не будет пустым, то будет использоваться заданное значение по умолчанию.

В примере выше, окончательным значением переменной $text будет Test, а не Test 2, потому что переменная не пуста.

Переменные можно назначить любому свойству:

stule.scss#container {
    content: $text;
}

Результат:

stule.css#container {
	content: "Test";
}

Вложенные правила

В стандартном CSS, вложенность достигается путём расстановки пробелов:

stule.css#a {
    color: red;
}

#a #b {
    color: green;
}

С помощью SCSS этот код можно записать так:

stule.scss#a {
    color: red;
    #b {
        color: green;
    }
}

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

Оператор &

В SCSS есть оператор &, который указывает на родителя:

stule.scss#p {
    color: black;
    a {
        &:hover {
            color: red;
        }
    }
}

Результат:

stule.css#p {
	color: black;
}

#p a:hover {
	color: red;
}

Вместо символа &, подставляется имя родительского элемента, a:hover.

Миксины или примиси

Миксины объявляются директивой @mixin. После неё должно стоять имя миксина и, опционально, его параметры, а также блок, содержащий тело миксина. Давайте создадим миксин, который определяет поведение элемента как Flex и далее будет включён в класс elements:

stule.scss@mixin flex() {
    display: flex;
}

.elements {
    @include flex();
    border: 1px solid #000;
}

Результат:

stule.css.elements {
	display: flex;
	border: 1px solid #000;
}

В миксины можно передавать аргументы, как если бы это была функция, а затем присваивать их свойствам CSS:

stule.scss@mixin flex($a) {
    display: flex;
    border: $a solid #000;
}

.elements {
    @include flex(1px);
}

Результат:

stule.css.elements {
	display: flex;
	border: 1px solid #000;
}

Арифметические операции

Как и в стандартном CSS, вам доступны операции сложения, вычитания, умножения и деления, но в отличии от классического CSS синтаксиса, вам необязательно использовать функцию calc().

Сложение

Как и в реальной жизни, вы не можете работать с числами, у которых несовместимы типы данных, например сложение рх и em. Главное, что-бы оба значения соответствуют одному формату:

stule.scssp {
    // error
    // font-size: 10px + 2em;

    font-size: 10px + 2px;
    font-size: 10px + 2;
}

Результат:

stule.cssp {
	font-size: 12px;
	font-size: 12px;
}

Вычитание

Главное, что-бы оба значения соответствуют одному формату:

stule.scssp {
    font-size: 10px - 2px;
}

Результат:

stule.cssp {
	font-size: 8px;
}

Умножение

Выполняется точно так же, как в CSS, с помощью calc(a * b), но без calc и круглых скобок. Кроме того, можно ещё отделять знак умножения пробелами от чисел 5*6 == 5 * 6.

Нельзя умножать пиксели между собой. То есть, 10px * 10px != 100px. 10px * 10 == 100px.

stule.scssp {
    // error
    // font-size: 10px * 10px;
    // font-size: 10px * (2px + 5px);

    font-size: 10px * 2;
    font-size: 10px * 2 + 5px;
    font-size: 10px + (10px / 2) * 3;

Результат:

stule.cssp {
	font-size: 20px;
	font-size: 25px;
	font-size: 25px;
}

Деление

В стандартном CSS, символ деления зарезервирован для других целей, например font: 24/32px определяет размер шрифта font-size: 25px и line-height: 32px.

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

stule.scssp {
    top: (16px / 16px);
}

Результат:

stule.cssp {
	top: 1;
}

Есть три помощника, которые намекнут на возможность деления:

  1. Значение (или любая его часть) хранится в переменной или возвращается функцией
  2. Значения заключены в круглые скобки
  3. Значение используется как часть другого арифметического выражения
stule.scss$var1: 20;
$var2: 4;

p {
    // отображается без изменений в стандартном CSS
    top: 16px / 24px;
    // производится деление (но только при использовании скобок)
    top: (20px / 5px);
    // выводится как обычный CSS-код, деление не выполняется
    top: #{$var1} / #{$var2};
    // деление выполняется
    top: $var1 / $var2;
    // деление выполняется (если использовать в паре с функцией)
    top: random(4) / 5;
    // деление выполняется, если добавлена ещё одно арифметическое действие
    top: 2px / 4px + 3px;
}

Результат:

stule.cssp {
  top: 16px / 24px;
  top: 4;
  top: 20 / 4;
  top: 5;
  top: 0.6;
  top: 3.5px;
}

Остаток

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

stule.scss@mixin zebra() {
    @for $i from 1 through 7 {
        @if ($i % 2 == 1) {
            .sprite-#{$i} {
                background-color: black;
                color: white;
            }
        }
    }
}

@include zebra();

Результат:

stule.scss.sprite-1 {
	background-color: black;
	color: white;
}

.sprite-3 {
	background-color: black;
	color: white;
}

.sprite-5 {
	background-color: black;
	color: white;
}

.sprite-7 {
	background-color: black;
	color: white;
}

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

  • x==y возвращает true, если x и y равны
  • x!=y возвращает true, если x и y не равны
  • x>y возвращает true, если x больше, чем y
  • x<y возвращает true, если x меньше, чем y
  • x>=y возвращает true, если x больше или равно y
  • x<=y возвращает true, если x меньше или равно y

Чтобы показать, как операторы сравнения работают на практике, создадим миксин, который будет применять свойство padding, если его значение больше значения margin:

stule.scss@mixin spacing($padding, $margin) {
        @if ($padding > $margin) {
            padding: $padding;
        } @else {
            margin: $margin;
        }
}

.container {
   @include spacing(10px, 20px);
}

Результат:

stule.css.container {
	padding: 20px;
}

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

  • x and y возвращает true, если x и y равны true
  • x or y возвращает true, если x или y равны true
  • not x возвращает true, если x не равен true

Создадим кнопки, у которой будет меняться фон в зависимости от ширины:

stule.scss@mixin button-color($height, $width) {
        @if (($height < $width) and ($width >= 35px)) {
            background-color: blue;
        } @else {
            background-color: green;
        }
}

.button {
   @include button-color(20px, 30px);
}

Результат:

stule.css.button {
	background-color: green;
}

Строки

В CSS определено 2 типа строк, с кавычками и без. SASS распознаёт и то, и другое. В итоге вы получите в CSS тот тип строк, который использовали в SASS.

В некоторых случаях можно добавить строки в допустимые значения CSS без кавычек, но только если добавленная строка является завершающим элементом:

stule.scssp {
    font: 50px Ari + "al";
}

Результат:

stule.cssp {
	font: 50px Arial;
}

Следующий пример приводит к строке ненужного типа:

stule.scssp {
    font: "50pxArial";
}

Можете складывать строки, соторые нужно взять в кавычки:

stule.scssp:after {
	content: "Привет " + "мир!";
}

Результат:

stule.cssp:after {
  content: "Привет мир!";
}

Операторы управления потоками

Подобно JavaScript, SCSS позволяет работать со стандартным набором операторов управления потоками.

Функция if() и директива @if

В SCSS есть функции fucntion() и директивы @directive, их ещё называю правилами. Отличительные особенности функций и директив:

  1. if() функция, есть скобки которые ставятся сразу после её имени
  2. @if дириктива, есть знак @ который ставится перед её именим

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

stule.scssh2 {
   color: if( 1 + 1 == 2 , green , red);
}

Результат:

stule.cssh2 {
	color: green;
}

Директива использующаяся для разветвления на основе условия:

stule.scssp {
    @if 1 + 1 == 2 { border: 1px solid;  }
    @if 7 < 5      { border: 2px dotted; }
    @if null       { border: 3px double;  }
}

Результат:

stule.cssp {
	border: 1px solid;
}

Ниже показано комбинация разветвлений с добавлением директивы @else:

stule.scss$type: river;

div {
    @if $type == river {
        color: blue;
    }
}

p {
    @if $type == tree {
        color: green;
    } @else if $type == river {
        color: blue;
    } @else if $type == dirt {
        color: brown;
    }
}

Результат:

stule.cssdiv {
	color: blue;
}

p {
	color: blue;
}

Директива @for

Директива @for выводит набор стилей заданное число раз. Для каждого повторения используется переменная-счётчик $i для изменения вывода. from начальная цифра от которой идет отсчет у цикла, through конечная цифра до которой идет отсчет:

stule.scss@for $i from 1 through 5 {
    .definition-#{$i} { width: 10px * $i; }
}

Результат:

stule.css.definition-1 {
	width: 10px;
}

.definition-2 {
	width: 20px;
}

.definition-3 {
	width: 30px;
}

.definition-4 {
	width: 40px;
}

.definition-5 {
	width: 50px;
}

Директива @each

Директива @each устанавливает $var в каждое из значений списка или словаря и выводит содержащиеся в ней стили, используя соответствующее значение $var:

stule.scss@each $var in platypus, lion, sheep, dove {
    .#{$var}-icon {
        background-image: url("/images/#{$var}.png")
    }
}

Результат:

stule.css.platypus-icon {
  background-image: url("/images/platypus.png");
}

.lion-icon {
  background-image: url("/images/lion.png");
}

.sheep-icon {
  background-image: url("/images/sheep.png");
}

.dove-icon {
  background-image: url("/images/dove.png");
}

Директива @while

Директива @while принимает выражение и циклично выводит вложенные в неё стили, пока выражение вычисляется как true. Она может быть использована для создания более сложных циклов, чем таких, для которых подходит @for, хотя она бывает необходима довольно редко:

stule.scss$index: 5;
@while $index > 0 {
    .element-#{$index} { width: 10px * $index; }
    $index: $index - 1;
}

Результат:

stule.css.element-5 { width: 50px; }
.element-4 { width: 40px; }
.element-3 { width: 30px; }
.element-2 { width: 20px; }
.element-1 { width: 10px; }

Функции

Используя SASS и SCSS можно использовать функции так же, как и в других языках. Создадим функцию three-hundred-px(), возвращающую 300px:

stule.scss@function three-hundred-px() {
    @return 300px;
}

.name {
    width: three-hundred-px();
    border: 1px solid gray;
    display: block;
    position: absolute;
}

Результат:

stule.css.name {
	width: 300px;
	border: 1px solid gray;
	display: block;
	position: absolute;
}

Функции могут возвращать любое корректное значение CSS и могут быть назначены любому свойству. Они даже могут быть рассчитаны на основе переданного аргумента:

stule.scss@function three-hundred-px($width) {
    @return $width * 2px;
}

.name {
    width: three-hundred-px(150);
    border: 1px solid gray;
    display: block;
    position: absolute;
}

Результат:

stule.css.name {
  width: 300px;
  border: 1px solid gray;
  display: block;
  position: absolute;
}
Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!
Эйч Маркетинг