В этой статье мы продолжаем освоение и закрепление синтаксиса Saas. Данная тема довольно объемна, но при этом достаточна проста. Большинству людей, знакомых с принципами верстки достаточно одного внимательного прочтения с разбором примеров, чтобы понять как все устроено.
Оболочка
Вы можете легко экспериментировать с SassScript с помощью интерактивной оболочки. Для запуска оболочки запустите Sass из командной строки с параметром -i
. В командной строке введите любое поддерживаемое SassScript выражение, чтобы оценить его работу, результат выведется для вас на экран:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ sass -i >> "Hello, Sassy World!" "Hello, Sassy World!" >> 1px + 1px + 1px 3px >> #777 + #777 #eeeeee >> #777 + #888 white |
Переменные
Самое простое, что поддерживает SassScript — это использование переменных. Переменные начинаются со знака доллара $
и задаются как свойства CSS:
1 |
$width: 5em; |
Вы можете обратиться к ним из свойств:
1 2 3 |
#main { width: $width; } |
Переменные доступны только в пределах того уровня вложенности селекторов, на котором они определены. Если они определяются вне каких-либо вложенных селекторов, они доступны глобально. Если вы хотите, чтобы объявленная на каком-либо уровне вложенности переменная также была доступна глобально, вы можете определить её со специальной меткой !global
. Например:
1 2 3 4 5 6 7 8 |
#main { $width: 5em !global; width: $width; } #sidebar { width: $width; } |
компилируется в
1 2 3 4 5 6 7 |
#main { width: 5em; } #sidebar { width: 5em; } |
По историческим причинам, в именах переменных (и прочих Sass идентификаторах) дефисы и подчеркивания взаимозаменяемы. Например, если вы определяете переменную $main-width
, вы можете получить к ней доступ, написав $main_width
, и наоборот.
Типы данных
SassScript поддерживает семь основных типов данных:
- числа (1.2, 13, 10px)
- текстовые строки, с кавычками и без них («foo», ‘bar’, baz)
- цвета (blue, #04a3f9, rgba(255, 0, 0, 0.5))
- булевы значения (true, false)
- null
- списки значений, с разделительными пробелами или запятыми (1.5em 1em 0 2em; Times New Roman, Arial, sans-serif)
- массивы(мапы) (key1: value1, key2: value2)
SassScript также поддерживает все другие виды данных CSS, такие как диапазоны Unicode и декларации!important
, однако для них не имеется специальных способов обращения, они используются точно также, как строки без кавычек.
Строки
CSS определяет два вида строк: будь то с кавычками, как «Lucida Grande» или ‘ Lucida Grande ‘, или же без них, как sans-serif или bold. SassScript признает оба вида строк и, в общем случае, какой тип строк вы используете в Sass документе, тот вы и получите в результирующем CSS. Существует одно исключение: когда используется #{} интерполяция, кавычки игнорируются. Это упрощает использование, скажем, имен селекторов в миксинах. Например:
1 2 3 4 5 6 7 |
@mixin firefox-message($selector) { body.firefox #{$selector}:before { content: "Hi, Firefox users!"; } } @include firefox-message(".header"); |
Списки
Списки в Sass представлены значениями CSS-деклараций вроде margin: 10px 15px 0 0
или font-face: Helvetica, Arial, sans-serif. Списки — это всего-навсего серия из нескольких однотипных значений, разделенных пробелами или запятыми. Фактически, индивидуальные значения также являются списками, просто это списки, которые состоят из одного элемента.
Сами по себе списки не делают ничего особенного, но список функций SassScript сделал их полезнее. Функцияnth
может получить доступ к элементам в списке, функция join
может объединить несколько списков вместе, а функция append
может добавлять элементы в список. Директива @each
также может добавлять стили для каждого элемента в списке.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Узнаем значение элемента списка по индексу: nth(10px 20px 30px, 1) => 10px nth((Helvetica, Arial, sans-serif), 3) => sans-serif nth((width: 10px, length: 20px), 2) => length, 20px // Объединяем списки в один: join(10px 20px, 30px 40px) => 10px 20px 30px 40px join((blue, red), (#abc, #def)) => blue, red, #abc, #def join(10px, 20px) => 10px 20px // Добавляем в список элементы: append(10px 20px, 30px) => 10px 20px 30px append((blue, red), green) => blue, red, green append(10px 20px, 30px 40px) => 10px 20px (30px 40px) |
Мапы (Ассоциативные массивы)
Мапы, или ассоциативные массивы, представляют собой связь между ключами и значениями, где ключи используются для поиска значений. Они позволяют легко собирать значения в именованные группы и получать доступ к этим группам динамически. Они не имеют прямого аналога в CSS, хотя они синтаксически похожи на media-запросы:
1 |
$map: (key1: value1, key2: value2, key3: value3); |
В отличие от списков, мапы всегда должны быть заключены в скобки и всегда должны быть разделены запятыми. И ключи и значения в мапах могут быть любыми объектами SassScript. Мап может иметь только одно сопоставление с заданным ключом (хотя это значение может быть списком). Значение ключа, конечно же, может быть сопоставлено многим значениям.
Как и со списками, манипуляции с мапами в основном происходят через функции SassScript. Функция map-getсмотрит значение в мапе, функция map-merge объединяет две мапы в одну новую. Директива @each может быть использована для добавления стилей для каждой пары ключ-значение в мапе. Порядок пар всегда остается неизменным с момента создания мапа.
Мапы можно использовать везде, где применимы списки. Если для манипуляции мапами используются функции для списков, то мапы будут рассматриваться как список пар. Например, (key1: value1, key2: value2) будет рассматриваться этими функциями как вложенный список key1 value1, key2 value2. Однако, обратное утверждение верно только для пустого списка ()
, в остальных случаях списки не могут рассматриваться как мапы. ()
представляет собой одновременно мапы без пар ключ-значение и список без элементов.
Заметьте, что ключами мапа может быть любой тип Sass данных (даже другой массив) и синтаксис для объявления мапа допускает произвольное применение SassScript-выражений, которые будут рассчитаны для определения ключа мапа.
Мапы не могут быть преобразованы в обычный CSS. Использование мапов в качестве значения переменной или аргумента CSS функции приведет к ошибке. Использование функций inspect($value)
для получения результирующей строки полезно для отладки мапов.
Например:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$status-colors: ( primary: #000, success: #27BA6C, info: #03a9f4, warning: #FF8833, danger: #ff1a1a ); .message { @each $status, $color in $status-colors { &--#{$status} { background: $color; } } } |
компилируется в
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
.message--primary { background: #000; } .message--success { background: #27ba6c; } .message--info { background: #03a9f4; } .message--warning { background: #f83; } .message--danger { background: #ff1a1a; } |
Цвета
Любое выражение цвета CSS возвращает значение цвета SassScript. В них входит большое количество именованных цветов, которые неотличимы от незаключенных в кавычки строк.
В режиме сжатия, Sass будет выводить наименьшее CSS представление такого цвета. Например, #FF0000
в сжатом режиме будет выводиться в CSS как red, но blanchedalmond выведет результат как #FFEBCD
.
Распространенная проблема, с которой сталкиваются пользователи именованных цветов, возникает из-за предпочтения Sass того же формата, который был напечатан в других режимах, использование названия цвета в имени селектора является недопустимым синтаксисом при сжатии. Чтобы избежать этого, всегда заключайте именованные цвета в кавычки, если они предназначены для использования в конструкции селектора.
Операции
Все типы данных поддерживают операции равенства ( ==
и !=
). Кроме того, каждый тип поддерживает собственные операции, применимые для конкретного типа данных.
Операции с числами
SassScript поддерживает стандартные арифметические операции над числами (сложение +
, вычитание -
, умножение *
, деление /
и остаток от деления по модулю %
). Математические функции Sass сохраняют значение промежуточных результатов в течение выполнения арифметических операций. Это означает, что, как и в реальной жизни, вы не можете работать с числами у которых несовместимы типы данных (например, складывание рх и em) и двух чисел одного типа, перемножение которых даст квадратные единицы ( 10px * 10px == 100px * px
).
Помните, что px * рх — это невалидный тип данных CSS, и вы получите сообщение об ошибке от Sass за попытку использовать недопустимые единицы в CSS.
Операторы сравнения ( <
, >
, <=
, >=
, ==
, !=
) также поддерживаются для чисел.
Давление — знак /
CSS использует символ /
как способ обособления численных данных наряду с пробелами и запятыми, а не для деления чисел. Поскольку SassScript является расширением синтаксиса CSS свойств, он должен поддерживать это, в то же время позволяя применять /
для деления чисел друг на друга. Это означает, что по-умолчанию, если два числа, разделены символом /
в SassScript, то они вместе с разделитилем окажутся в результирующем CSS.
Тем не менее, существует три ситуации, в которых символ /
будет интерпретироваться именно как деление. Они охватывают подавляющее большинство случаев, когда подразумевается именно деление:
- Если значение или любая его часть, хранится в переменной или возвращается функцией
- Если значения заключены в круглые скобки
- Если значение используется как часть другого арифметического выражения
Например:
1 2 3 4 5 6 7 8 |
p { font: 10px/8px; // Явный CSS, деление отсутствует $width: 1000px; width: $width/2; // Используется переменная, операция деления width: round(1.5)/2; // Используется функция, операция деления height: (500px/2); // Обособление скобками, операция деления margin-left: 5px + 8px/2px; // Используется +, операция деления } |
компилируется в
1 2 3 4 5 6 |
p { font: 10px/8px; width: 500px; width: 1; height: 250px; margin-left: 9px; } |
Если вы хотите использовать символ /
в переменной, в значении обычного CSS /
, вы можете заключить переменную в #{}
Операции с цветами
Все арифметические операции поддерживаются для значений цветов, в которых они могут быть применены для каждого цвета в отдельности. Это означает, что операция выполняется поочередно отдельно для красной, зеленой и синей составляющей цвета. Например:
1 2 3 |
p { color: #010203 + #040506; } |
вычислит 01 + 04 = 05, 02 + 05 = 07, и 03 + 06 = 09, в результате будет получен цвет:
1 2 |
p { color: #050709; } |
Часто полезнее использовать функции цвета, чем пытаться использовать арифметику, чтобы достичь того же эффекта. Арифметические операции между числами и цветами также работают поочередно для каждой составляющей. Например:
1 2 3 |
p { color: #010203 * 2; } |
вычислит 01 * 2 = 02, 02 * 2 = 04, 03 * 2 = 06 и преобразуется в:
1 2 |
p { color: #020406; } |
Обратите внимание, что цвета с альфа-каналом (те, которые создаются через rgba или hsla функции) должны иметь одинаковое значение прозрачности для того, чтобы проводить с ними арифметические операции, поскольку арифметика не влияет на значение альфа-канала.
Альфа-канал цвета можно регулировать с помощью функций opacify и transparentize. Например:
1 2 3 4 5 |
$translucent-red: rgba(255, 0, 0, 0.5); p { color: opacify($translucent-red, 0.3); background-color: transparentize($translucent-red, 0.25); } |
компилируется в
1 2 3 |
p { color: rgba(255, 0, 0, 0.8); background-color: rgba(255, 0, 0, 0.25); } |
IE фильтры требуют, чтобы все цвета включали в себя альфа-слой, и были в строгом формате #AABBCCDD. Вы можете легко конвертировать цвет с помощью функции ie_hex_str. Например:
1 2 3 4 5 |
$translucent-red: rgba(255, 0, 0, 0.5); $green: #00ff00; div { filter: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr='#{ie-hex-str($green)}', endColorstr='#{ie-hex-str($translucent-red)}'); } |
компилируется в
1 2 3 |
div { filter: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr=#FF00FF00, endColorstr=#80FF0000); } |
Операции со строками
Операция конкатенации строк осуществляется при помощи символа +
. Например:
1 2 3 |
p { cursor: e + -resize; } |
компилируется в
1 2 |
p { cursor: e-resize; } |
Обратите внимание, что, если мы к строке без кавычек добавляем строку в кавычках (строка без кавычек слева от знака +
), то результатом будет строка без кавычек. И, наоборот, если мы к строке в кавычках прибавляем строку без кавычек, результатом будет строка в кавычках.
По-умолчанию, если два значения находятся рядом друг с другом, они объединяются через пробел.
Возможно использование интерполяции #{}
для размещения динамических значений в строке:
1 2 3 |
p:before { content: "Я съел #{5 + 10} пирогов!"; } |
компилируется в
1 2 |
p:before { content: "Я съел 15 пирогов!"; } |
Значение null
обрабатывается как пустая строка в интерполяции:
1 2 3 4 |
$value: null; p:before { content: "Я съел #{$value} пирогов!"; } |
компилируется в
1 2 |
p:before { content: "Я съел пирогов!"; } |
Операции с логическими значениями
SassScript поддерживает операторы И, ИЛИ и НЕ (and, or, not) для логических значений. Например:
1 2 3 4 5 6 7 8 9 10 |
$menuOn: true; $menuDropDown: false; .menu li { color: #ff0000; text-decoration: underline; @if $menuOn == true and $menuDropDown == true { position:relative; } } |
компилируется в
1 2 3 4 |
.menu li { color: #ff0000; text-decoration: underline; } |
Функции списков в Saas
Списки не поддерживают каких-либо специальных операций. Для работы с ними существуют функции списков.
Круглые скобки
Скобки могут использоваться для определения порядка действий:
1 2 3 |
p { width: (1em + 2em) * 3; } |
компилируется в
1 2 |
p { width: 9em; } |
Функции
SassScript содержит некоторые полезные функции, которые можно вызвать, используя обычный синтаксис CSS
1 2 3 |
p { color: hsl(0, 100%, 50%); } |
компилируется в
1 2 |
p { color: #ff0000; } |
Вы можете увидеть весь список доступных функций на этой странице.
Именованные аргументы
В функции Sass можно передавать именованные аргументы используя карты. Предыдущий пример может быть записан следующим образом:
1 2 3 |
p { color: hsl($hue: 0, $saturation: 100%, $lightness: 50%); } |
Несмотря на то, что запись стала длиннее, такое выражение легче прочесть. Это также предоставляет более гибкий интерфейс для написания функций, в котором увеличение количества аргументов не увеличивает трудности.
Именованные аргументы можно передавать в любом порядке, а аргумент со значением по умолчанию может быть пропущен. Так как именованные аргументы являются переменными, знак подчеркивания и дефис являются взаимозаменяемыми.
Смотрите Sass::Script::Функции, чтобы ознакомиться со всеми функциями Sass и названиями их аргументов, а также инструкциями, описывающими как объявить собственные функции на Ruby.
Интерполяция
Вы также можете использовать переменные SassScript в селекторах и в названиях свойств используя синтаксис #{}
интерполяции:
1 2 3 4 5 |
$name: foo; $attr: border; p.#{$name} { #{$attr}-color: blue; } |
компилируется в
1 2 |
p.foo { border-color: blue; } |
Также можно использовать #{}
, чтобы вставить в SassScript значение свойств. В большинстве случаев это не лучше, чем любой другой способ, но использование #{}
означает, что любые операции в нем будут рассматриваться как запись CSS. Например:
1 2 3 4 5 |
p { $font-size: 12px; $line-height: 30px; font: #{$font-size}/#{$line-height}; } |
компилируется в
1 2 |
p { font: 12px/30px; } |
Символ «&» в SassScript
Также как и в объявлении ссылки на родителя, оператор &
в SassScript относится к текущему родительскому селектору. Это список, разделенный запятыми, состоящий из списков, разделенных пробелами. Например:
1 2 3 |
.foo.bar .baz.bang, .bip.qux { $selector: &; } |
В этом примере значением переменной $selector является ((«.foo.bar» «.baz.bang»), «.bip.qux»). Составные селекторы приведены, чтобы показать, что они строковые, хоть и указывались без кавычек. Даже если родительский селектор не содержит запятую или пробел, &
всегда будет иметь два уровня вложенности, поэтому он может быть доступен постоянно.
Если нет родительского селектора, значение &
будет нулевым. Это означает, что вы можете использовать его в миксинах, чтобы проверить наличие родительского селектора:
1 2 3 4 5 6 7 8 9 10 11 |
@mixin does-parent-exist { @if & { &:hover { color: red; } } @else { a { color: red; } } } |
Переменные по умолчанию
Вы можете присваивать значение по-умолчанию переменным, у которых еще нет значения, добавив метку!default
в конце значения. В таком случае, если переменная уже имела значение, то оно не изменится; если же переменная пуста, ей будет присвоено новое указанное значение.
Например:
1 2 3 4 5 6 7 8 |
$content: "Тестовый текст"; $content: "Новый тестовый текст?" !default; $new_content: "Как пройти в библиотеку?" !default; #main { content: $content; new-content: $new_content; } |
компилируется в
1 2 3 |
#main { content: "Тестовый текст"; new-content: "Как пройти в библиотеку?"; } |
Переменные, имеющие значение null
, рассматриваются меткой !default
как не имеющие значение.
Мы рассмотрели базовый синтаксис Saas, с которым вам предстоит работать повсеместно. Как видите, в нем нет ничего сложного. Следующий день изучения будет посвящен правилам и директивам Saas.