Все статьи | Блог студента

Склеиваем всё что попало, любуемся результатом

Статья написана студентом Хекслета. Мнение автора может не совпадать с позицией редакции
Склеиваем всё что попало, любуемся результатом главное изображение

Затем берём микроскоп и отправляемся читать документацию.

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

Предупреждение 1. Прочитала только часть документации и на один из вопросов всё ещё ответить не могу. Интернет тоже затаился и на эту тему общаться со мной не хочет ... Но я его со временем разговорю :-)

Предупреждение 2. Цитата из Hexlet: «Пишите о том, в чём вы разбираетесь, с чем работаете, на чём съели собаку».

Я как-то ни собак, ни недожаренных китайских летучих мышей в принципе не ем :-)

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

Постановка вопроса

Вячеслав: Вопрос по интерполяции и конкатенации.

Я обнаружил, что если в примере

width: #{$size}px

вместо _px _поставить %, компилятор будет ругаться и выдавать ошибку. Почему? Процент для него не система исчисления?

Дальше ещё интереснее, в поисках правильной записи, я обнаружил, что:

width: $size + "%" - компилируется в  
width: "32%"; height: "32%";

width: #{$size} + "%" - компилируется в  
width: 32%; height: 32%;

Следовательно последняя запись дает мне правильное значение по итогу. Но почему без интерполяции всё выражение помещается под "", если изначально в выражении только % в кавычках?

Начинаем разбираться в теме

$size: 32;  
width: #{$size}px; // width: 32px;  
Получили то, что хотели. 
Но способом, от которого отговаривают в документации.

Quote

You should especially avoid using interpolation like #{$number}px. This doesn’t actually create a number! It creates an unquoted string that looks like a number, but won’t work with any number operations or functions. Try to make your math unit-clean so that $number already has the unit px, or write $number * 1px.
https://sass-lang.com/documentation/operators/numeric

Quote end

Ну да. В Sass строка (string) может стоять без кавычек, в одинарных или в двойных кавычках. Например 5 – это ещё число или уже строка? По природе вещей - число. Но если его нечаянно преобразовать в string (а в Sass это происходит слишком легко и этого можно не заметить) - то неприятностей не оберёшься.

Предположим, у нас есть 5 и 2. И это почему-то уже не числа. Где-то мы их по ходу дела незаметно для себя преобразовали в string. Мы хотим их сложить (5 + 2) и получить 7. А не получается. Ответ - 52. Можно, конечно, перепроверить тип. А можно и голову сломать ...

Чтобы не рисковать головой, можно написать так:

$size: 32;  
width: $size * 1%; // 32%;

Или так:

$size: 32;  
width: $size + 0%; // 32%;

Интересно, какой способ лучше?
(Своего мнения по этому поводу пока нет, так как ещё не было практики.)

  • https://css-tricks.com/snippets/sass/correctly-adding-unit-number/
    Здесь есть вдобавок к методу замечание, что умножение для компьютера сложнее, чем сложение. Поэтому рекомендуют сложение с нулём.

  • Где-то встретилось замечание, что употребление нуля нежелательно оттого, что при чтении кода могут возникнуть затруднения с пониманием. Согласна. 0% выглядит странно и такой код хочется почистить.

  • В документации советуют умножение.

Кстати, 5px, например - это в Sass тоже number по определению.
То есть можно было бы написать и так:

$size: 32%;  
width: $size; // 32%;

Quote

Numbers in Sass have two components: the number itself, and its units. For example, in 16px the number is 16 and the unit is px. Numbers can have no units, and they can have complex units.
https://sass-lang.com/documentation/values/numbers

Quote end

К первому вопросу:

Компилятор выдаёт ошибку в случае width: #{$size}%

Причина
% такой же оператор, как + - / *
% выдаёт остаток деления.

Пример:

width: 32 % 16; // Делим 32 на 16 и получаем в остатке 0
width: 32 % 10; // Делим 32 на 10 и получаем в остатке 2

#{}+ Так писать код никто бы не стал, так как ошибка очевидна.
А с #{}% здесь всё то же самое и так же не работает:

width: #{$size}+; // error 
width: #{$size}%; // error

В этом месте Никита меня дополнил:

Quote

"Тут действительно основная проблема в использовании символа, который является математической операцией (а ещё и символом шаблонного селектора)".

Quote end

Конечное решение Вячеслава:

width: #{$size} + "%" - компилируется в
width: 32%; height: 32%; 

Этот пример объясняю себе таким образом: здесь происходит конкатенация двух строк. ("Interpolation returns unquoted strings …" https://sass-lang.com/documentation/interpolation).

Первая строка (слева, это важно) без кавычек, вторая в кавычках. В таком случае и результат будет без кавычек. То есть на выходе у нас снова строка, прикинувшаяся числом. За что нас уже ругали в документации.

Из документации:
При конкатенации двух строк обращаем внимание на ту, что стоит на первом месте, перед знаком +.

Если на первом месте строка без кавычек, то и результат будет без кавычек.

a + "b"; // ab  

Если на первом месте строка в кавычках, то и результат будет в кавычках.

"a" + b; // "ab"  

https://sass-scss.ru/documentation/sassscript/strokovie_operatsii/

Under constructions …

А вот по поводу основного вопроса с кавычками надо ещё дальше документацию смотреть. Там много неочевидных правил и все эти «мелочи» играют роль при преобразовании типов, расстановке кавычек и так далее ...

По поводу «мелочей». Копирую пример из документации:

$number: 2;  
@debug 1 -2 3; // 1 -2 3  
@debug 1 (-$number) 3; // 1 -2 3  
@debug 1 -$number 3; // -1 3  

https://sass-lang.com/documentation/operators/numeric

И это если только немножечко поскрести документацию. Там на самом деле ещё очень много забавных вещей. Они сами некоторые места так и помечают: "Fun fact".

К сожалению, добавить можно ещё то, что в разных версиях Sass конкатенация производится по разному. (И не только она ...)

Разная компиляция в разных версиях Sass

Меня сначала очень смутило то обстоятельство, что результат у Вячеслава и у меня различались в корне.

Пример, приведённый Вячеславом:

width: $size + "%"

Его результат:

width: "32%";

Мой (изначальный) результат:

width: 32 + "%";

Поняла, что у нас, вероятно, какие-то разные версии Sass. Кое-что перенастроила. Попробовала компилировать через разные версии - да, результаты отличаются. Так что спасибо Вячеславу за его эксперименты и вопросы - они мне помогли кое-что понять :-)

Кстати, тут тоже можно попробовать разные версии Sass (просто переключайтесь в третьем пункте меню с одной версии на другую): https://www.sassmeister.com/

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

Аватар пользователя Anna kra_
Anna kra_ 09 ноября 2020
Рекомендуемые программы

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

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
18 мая 10 месяцев
Иконка программы Python-разработчик
Профессия
Разработка веб-приложений на Django
18 мая 10 месяцев
Иконка программы PHP-разработчик
Профессия
Разработка веб-приложений на Laravel
18 мая 10 месяцев
Иконка программы Node.js-разработчик
Профессия
Разработка бэкенд-компонентов веб-приложений
18 мая 10 месяцев
Иконка программы Fullstack-разработчик
Профессия
Новый
Разработка фронтенд и бэкенд компонентов веб-приложений
18 мая 16 месяцев
Иконка программы Верстальщик
Профессия
Вёрстка с использованием последних стандартов CSS
в любое время 5 месяцев
Иконка программы Java-разработчик
Профессия
Разработка приложений на языке Java
18 мая 10 месяцев
Иконка программы Разработчик на Ruby on Rails
Профессия
Создает веб-приложения со скоростью света
18 мая 5 месяцев