Статьи

Sass 3.4 вышел!

Только через пару месяцев после Sass 3.3 версия 3.4 уже поставляется под кодовым названием «Селективный Стив». Довольно странное имя, но мы увидим, что оно довольно точное, поскольку большинство новых функций связано с селекторами.

Родительский селектор & в SassScript

«В SassScr что?» — спросите вы. Вы можете думать о SassScript как о языке Sass. Sass — это экосистема, препроцессор, а SassScript — это то, что делает Sass, ну … Sass, под капотом. Или, как выразилась Натали Вайзенбаум :

«SassScript» — это то, что мы называем мини-языком Sass для переменных, значений свойств и т. Д. В основном это просто значения CSS, но он также поддерживает пользовательские функции, арифметику и так далее.

До Sass 3.4 вы не могли ничего сделать с родительским селектором (хотя я ненавижу это имя, поскольку это не родительский селектор, а ссылка на текущий селектор, который совершенно другой, но неважно), кроме таких вещей, как:

 .selector { .no-svg & { // Stuff } &:hover { // (H)o(v|th)er stuff (see what I did there?) } } 

Ну, теперь мы можем сделать гораздо больше. Сначала предполагалось, что эта новая функция будет поставляться с Sass 3.3, но она задерживается из-за технических проблем.

По сути, теперь вы можете манипулировать & как вы можете любой другой переменной. Он всегда содержит список списков, как и следовало ожидать.

Например, если у вас есть селектор типа .foo .bar, .baz , тогда верхний список для & будет содержать 2 элемента: .foo .bar и .baz , оба из которых являются списками. Затем первый также содержит 2 элемента ( .foo и .bar ), а второй содержит только один .baz ( .baz ).

Помните, что SassScript-представление селектора, состоящего из одной детали , все еще представляет собой двухуровневый глубокий список. Например .item будет ((item,),) . Поэтому, если вы хотите получить .item из & , вам нужно выполнить nth(nth(&, 1), 1) (первый элемент первого элемента & ).

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

 // This doesn't work in 3.3. // This doesn't work in 3.4. .selector { color: blue; a& { color: red; } } 

Типичный сценарий: я хочу квалифицировать селектор на лету . В нашем примере у нас есть .selector к которому мы хотим применить пользовательские стили, если это якорь ( a ).

Это все еще не так просто, но, по крайней мере, мы можем сделать это сейчас:

 // This doesn't work in 3.3. // This does work in 3.4. .selector { color: blue; @at-root #{a + &} { color: red; } } 

Во-первых, нам нужно вывести его на корневом уровне, благодаря @at-root , или мы получим что-то вроде .selector a.selector что не то, что нам нужно. Тогда нам просто нужно все это интерполировать.

Теперь мы могли бы сделать вещи немного более модульными, сделав для этого функцию. Как насчет этого:

 // This doesn't work in 3.3. // This does work in 3.4. @mixin qualify($selector) { @at-root #{$selector + &} { @content; } } 

А потом:

 .selector { color: blue; @include qualify(a) { color: red; } } 

Довольно круто, не правда ли? Насколько мне известно, это один из немногих простых вариантов использования & в SassScript. Вероятно, существует множество других сценариев, но они обычно включают в себя гораздо более сложный контекст (платформы Sass и т. Д.).

Функции выбора

Если вы согласитесь с этой совершенно новой игрушкой, которая является родительским селектором SassScripted, и еще немного привязитесь к имени Селективного Стива , вам будет приятно узнать, что в Sass 3.4 появилось несколько новых функций, позволяющих играть с селекторами.

Я не буду слишком углубляться в эти функции, поскольку они будут бесполезны для большинства разработчиков (включая меня). Действительно, эта функция специально предназначена для разработчиков фреймворков (это было подтверждено Натали в Твиттере, хотя я не могу найти твит, потому что поиск в Твиттере хромает как ад).

По сути, у вас есть функция делать все, что вы хотите; будь то добавление селектора к другому селектору, вложение селектора под другим селектором, замена селектора внутри другого селектора, объединение селекторов и многое другое.

Тем не менее, я хотел бы поговорить о двух из этих функций: selector-extend и selector-replace .

Во-первых, стоит отметить, что selector-extend работает точно так же, как директива @extend . На самом деле, я подозреваю, что именно это используется директивой под капотом.

Во-вторых, функция selector-replace самом деле намного эффективнее, чем можно было бы подумать. Предупреждение! Это не функция замены строк. На самом деле он использует @extend директивы @extend для замены селекторов, не нарушая логику, поставленную там на первом месте.

То есть — и здесь я беззастенчиво selector-replace(".foo.bar.baz", ".foo.baz", ".qux") пример Натали — selector-replace(".foo.bar.baz", ".foo.baz", ".qux") (заменяя .foo.baz на .qux в .foo.bar.baz ) возвращает .bar.qux . Обычная функция замены строк ничего бы не возвращала, поскольку .foo.bar не существует как строка в .foor.bar.baz . Это где Sass селекторные функции начинают действовать.

В любом случае, если вы спросите меня, большинство из этих функций практически бесполезны в любом разумном проекте. Некоторые люди, например, находили варианты использования ( Марк Минтел здесь и Мика Годболт ), но, насколько мне известно, они не решают много, а когда они делают, это добавляет слишком большую сложность кода. Keep Sass Simple !

Обработка ошибок с помощью @error

Хорошо, хватит уже с селекторами! Если есть одна вещь, которую я ожидал в Sass 3.4, это директива @error . На самом деле, как разработчик фреймворка, я почти два года ждал такой возможности!

Дни @warn "..."; @return null; @warn "..."; @return null; закончились, друзья мои Да здравствует @error ! До сих пор у Sass не было чистого способа обработки ошибок. Если вы давно читали мои статьи, вам может быть знаком такой шаблон:

 @function rainbow($unicorn) { @if type-of($unicorn) != "unicorn" { @warn "What?! `#{$unicorn}` is not a unicorn? Are you serious?!"; @return null; } // Proceed with the code. } 

В общем, нам нужно было проверить все, что мы хотели проверить, предупредить пользователя через @warn , вернуть null (или false или что-то еще), а затем разобраться с этим во всей логике, которую мы могли иметь.

Давайте перепишем наш код с волшебством Sass 3.4:

 @function rainbow($unicorn) { @if type-of($unicorn) != "unicorn" { @error "What?! `#{$unicorn}` is not a unicorn? Are you serious?!"; } // Proceed with the code. } 

Boom. Если синтаксический анализатор достигает директивы @error , он просто @error и выведет сообщение об ошибке в консоли, как если бы у вас была синтаксическая ошибка или что-то еще. Код просто останавливается. Это круто!

Некоторые улучшения в цветах

Сначала был добавлен новый цвет rebeccapurple (# 663399), который теперь обрабатывается как любой другой цвет в Sass. Это как дань (CSS Legend) дочери Эрика А. Мейера, чей любимый цвет был фиолетовый, и который недавно скончался в возрасте 6 лет.

Кроме того, было немного крошечных, но приятных улучшений в том, как Sass обрабатывает цвета. Например, Sass попытается сохранить способ создания цветов, когда это возможно, за исключением сжатого режима, где он попытается найти наиболее компактный способ представления цветов.

Кроме того, функции rgb() , rgba() , hsl() и hsla() теперь ограничивают свои значения минимальными / максимальными разрешенными значениями вместо того, чтобы hsla() ошибку. Это изменение было сделано для того, чтобы придерживаться официальных спецификаций CSS из CSS Colors Level 4 .

Наконец, и поскольку было много жалоб по этому поводу, Sass теперь будет отображать предупреждение, когда в интерполяции используется цвет ( #{} ). По сути, некоторые разработчики выражали свое недовольство результатом такого кода:

 @each $color in darkolivegreen, firebrick, blanchedalmond { .item-#{$color} { color: $color; } } 

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

 .selector-#556b2f{color:#556b2f}.selector-#b22222{color:#b22222}.selector-#ffebcd{color:#ffebcd} 

Как видите, имена цветов были заменены их шестнадцатеричными эквивалентами, потому что они короче, что может сэкономить несколько байтов. Решение состоит в том, чтобы процитировать цвета в списке ( "darkolivegreen", "firebrick", "blanchedalmond" ), но, чтобы предотвратить дальнейшую путаницу, Sass предупредит об этом прямо в консоли.

Тебе скучно?!

Вы развлечены?

Если всего этого вам недостаточно, не волнуйтесь, мой друг, потому что есть еще много информации о Селективном Стиве (например, Sass 3.4).

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

  • Теперь вы можете удалить несколько ключей одновременно с помощью функции map-remove . Это теперь согласуется с map-merge , которое также принимает несколько пар.
  • Директива @extend теперь корректно работает с псевдоклассами, чего не было до 3.4.
  • Исходные карты были значительно улучшены.

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