16 советов по продвинутой верстке с языком SCSS

1
2445

Подборка крутых вещей от веб-разработчика из Хельсинки — Jarno Rantanen, 16 советов, которые сделают работу с SCSS интереснее, легче и быстрее.

Или 16 крутых вещей, о которых вы, возможно не знали. Конечно хотелось бы округлить это число, но к сожалению, ничего не вышло.

Я использую SCSS/SASS для большинства своих проектов начиная с 2009 года, и являюсь большим фанатом Compass. Он помог мне пройти через огромное количество разного кросс-браузерного хлама. И даже несмотря на то, что браузеры стали намного лучше ладить с CSS, появилась другая проблема: сложность управления в стилевых страницах становится только больше. SCSS – незаменимый инструмент для её решения.

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

  • вложенными селекторами,
  • переменными,
  • mixins,
  • и многим другим

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

1. Префиксация ссылок родительского селектора

Это ситуация будет вам знакома, если вы используете &:

Но & может также быть использован с префиксом:

Это может быть очень полезно, когда у вас много вложений в правилах, а вы хотите внести изменение в стиль элемента, основанный на совпадении селектора ближе к корню DOM. Флаги возможностей клиента, такие как no-touch класс Modernizr, часто применяются таким образом к <body> элементу. Таким образом, вам не нужно отказываться от своего гнездования, чтобы иметь возможность изменить свой <p> стиль на основе класса <body>.

2. Расширение переменных в селекторах

Переменные также могут быть расширены в селекторах:

… или почти в любом другом месте, как в случае с медиа-запросами или комментариями CSS:

Пример медиа-запроса особенно полезен, если переменная $breakpoint определена где-то в параметрах (скажем, _settings.scss), поэтому ,брейкпоинты всего приложения настраиваются из одного файла.

3. Значения переменных по умолчанию

Если ваш SCSS-модуль можно настроить с использованием глобальных переменных (которые, как правило, являются способом SCSS), вы можете объявить их со значением по умолчанию:

Но затем вы можете дополнительно переопределить значения модуля по умолчанию перед его включением:

То есть, присваивание с !default сработает только в том случае, если эта переменная не была инициализирована раньше (в отличие от стандартного присваивания, которое всегда будет перезаписывать возможное предыдущее значение).
Вот сколько модулей SCSS (включая большинство, которые поставляются вместе с Compass) могут быть настроены.

4. Контрольные директивы

SCSS поддерживает стандартный набор директив управления потоком, например, if:

Наличие таких флагов времени компиляции в стиле вашего проекта может помочь визуально отлаживать сложные вопросы компоновки, намного быстрее, чем если бы вы просто проверяли по странице за один раз. Также и @for, @eachи @while. Они хороши в случаях, когда вам необходимо множество повторений (S) CSS, например:

…и многое другое. Имейте в виду, что, если это нужно вам в повседневной работе, вы, вероятно, немного переусердствуете. Однако добавленная сложность обычно оправдана при создании настраиваемых модулей SCSS и т. д. Если вас это заинтересовало можете ознакомиться с полной документацией по директивам управления.

5. Тип данных — список

Как было показано в предыдущем примере, с помощью @each можно перебирать список. Списки на самом деле являются фундаментальной частью языка SCSS, но быстрая демонстрация их полезности может заключаться в настройке некоторого сгенерированного стиля:

Это демонстрирует две особенности типа данных списка, а именно nth() функцию доступа к списку , и более интересную неопределенность перечисления: в нотации JavaScript вышеупомянутое будет эквивалентно:

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

6. Определение пользовательских функций

Mixins — хорошо известная часть языка, но SCSS также позволяет вам определять пользовательские функции. Вопреки тому, что можно было бы ожидать, это также можно сделать в чистом SCSS вместо расширения SCSS в Ruby :

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

7. Аргументы по умолчанию

Mixins и функции поддерживают значения по умолчанию для аргументов; последний нулевой — N аргументы инициализировать не обязательно:

8. Ключевые аргументы

Если ваш mixin (или функция) принимает множество аргументов, есть аналогичный call-time синтаксис для выбора аргументов для переопределения:

Не имея возможности назвать аргументы во время вызова, сначала вам нужно будет указать $topPadding и $rightPadding. Теперь вместо этого вы можете переопределить только требуемый аргумент, оставив остальные значения по умолчанию.

Обратите внимание, что в тех случаях, когда множество аргументов предназначены для переопределения определенных свойств CSS (например, top-padding, bottom-padding и т. д.), лучше подойдет следующий способ «Перекрытие блока содержимого» (см. ниже).

9. Var-args для функций/mixin

Var-args работают так же, как и в других языках, поддерживающих эту функцию; Любые дополнительные аргументы вызова функции / mixin заворачиваются в список и назначаются аргументу с суффиксом … :

Вышеупомянутый помощник может использоваться для настройки цветов для шрифтов иконок например, шрифта Awesome , без необходимости повтора. Помощник работает, за счет передачи переменной количества аргументов (после первого, требуемого). Предполагается, что каждый из этих аргументов является кортежем из двух элементов (например, в нотации JavaScript [ «save», «green» ]).

Фактически, синтаксис … также работает во время вызова, где он расширяет список до отдельных аргументов для подачи в целевой mixin:

Лично мне еще предстоит найти случаи использования этого, но в документации есть хороший вариант для передачи текущих аргументов в другой mixin.

10. Аргументы контент-блока для mixin

Начиная с версии 3.2.0 , SCSS имеет неявный аргумент mixin, доступный через директиву @content. Он позволяет передавать весь контентный блок SCSS в качестве аргумента для mixin:

Это очень мощная языковая функция для авторов фреймворков, так как она позволяет вам проходить произвольные блоки стиля, которые вы можете выбрать, чтобы обернуть определенными селекторами, повторить в циклах, сделать условными с помощью @ifи т. д. Вы также можете смешивать аргументы стандартного и контентного блока:

11. Шаблон переопределения контент-блока

Рассмотрим mixin, который генерирует селектор и некоторые стили для него, позволяя вызывающему настраивать стиль при необходимости:

Вызов этого mixin с использованием ключевых аргументов (см. выше) довольно удобен, потому что если значения по умолчанию подходят, дополнительных аргументов не требуется. Если это не так, вам нужно только указать те аргументы, которые вы хотите переопределить:

Но для этого нужно, чтобы вы перечислили все переопределяемые свойства в сигнатуре mixin. Тем не менее, аргументы блока(content block) содержимого позволяют произвольные переопределения без аргумента jungle:

Здесь мы разрешаем каскад CSS с хорошим ole для выполнения переопределения свойства (последний margin переопределяет первый). Кроме того, мы не ограничиваемся переопределением свойств, о которых думал автор mixin. Фактически, это позволяет передавать также вложенные блоки:

Этот шаблон может быть полезен в любом библиотечном коде, который выводит нетривиальный стиль с созданными селекторами, поскольку он позволяет пользователю настраивать точку, превышающую то, что предвидел автор библиотеки. Заметьте, однако, что в простых случаях (когда селекционеры не выбрасываются в mixin) это необязательно, так как любые переопределения могут быть сделаны только с использованием стандартного каскада CSS.

12. Пузырение медиа-запросов

@media блоки не должны быть объявлены на корневом уровне таблицы стилей:

Обратите внимание, как компилятор «пузырится» над блоком @media на корневом уровне (поскольку обычный CSS не поддерживает селекторное вложение), и внутри него выводит весь стиль, который встречался внутри блока @media в источнике SCSS.
Это очень полезно, так как позволяет вам media-specific tweaks практически в любом месте вашего стиля, прямо там, где они актуальны, вместо того чтобы собирать все эти настройки до конца таблицы стилей и надеяться, что их селекторы будут синхронизироваться с теми, которые они переопределяют (они не будут).

13. Вложенность медиа-запросов

Вышеупомянутый механизм «пузырения» также учитывает вложенность и объединяет все применимые запросы с оператором and:

14. Расширение селекторов

SCSS позволяет расширить селектор , скопировав и объединив селекторы в выводе CSS. Интересно, что, хотя механизм (очевидно) очень отличается, семантика @extend аналогична традиционным объектно-ориентированным языкам программирования (например, Java & whatnot):

То есть, .cat имеет все свойства своего «родительского класса» .animal плюс любые специальные, которые он добавляет или переопределяет. Если в обычном CSS вам нужно будет ссылаться как на расширяющийся класс, так и на родительский класс (например <div class=»animal cat»>), теперь вы можете просто назвать нужный класс ( <div class=»cat»>). То, что он наследует (или не наследует), зависит от определения .cat и может впоследствии измениться, не касаясь разметки.
Классическое наследование, не так ли? Переопределение свойств в «дочернем классе» работает из-за каскада стиля в браузере: стилизация для того же селектора, который появляется позже в файле, всегда выигрывает у стиля, который был перед ним. Возможно, немного неинтуитивно, но это отлично работает, даже если комбинированные селекторы имеют различную специфичность (думаю, .class расширяя #id). Расширение селекторов часто может быть предпочтительным для использования mixins для достижения такого же эффекта:

Обратите внимание, что только последнее свойство ( color) отличается, в остальном они одинаковы. Поскольку мы определяем больше типов животных, количество повторяющихся свойств стиля в выходе CSS продолжает расти. Это в отличие от того, как расширение селектора решит ту же проблему:

Наконец, расширение селектора допускает интеграцию в сторонние библиотеки CSS, которые не обязательно должны быть специально разработаны для расширения или даже записываться в SCSS. Twitter Bootstrap , например, включает приятный стиль для кнопок .btn, но не применяет его к < button > элементам по умолчанию. В нашем стремлении сократить ненужные классы CSS мы можем исправить это просто с помощью:

Это добавит селектор button в источник Bootstrap везде, где .btn определен. Механизм расширения удивительно умный , даже с более сложными селекторами , и позволяет цепочке продолжаться(думаю , .cat extends .feline extends .animal), но с большой силой приходит большая ответственность: чрезмерно аккуратные трюки с @extend впоследствии могут усложнить отладку стилей. Используйте с умом.

15. Селекторы-заполнители

Поскольку в приведенном выше примере (-ах) .animal — базовый класс и напрямую нигде не используется (только через его дочерние классы), мы могли бы просто избавиться от него в выводе CSS. SCSS позволяет делать это с помощью селекторов-заполнителей . Принимая во внимание, что .foo — класс и #foo – идентификатор, а %foo считается плэйсхолдером, и обрабатывается компилятором особым образом: его стили никогда не выводятся сами по себе, только с помощью расширения.

Поскольку он %animal был просто селектором-заполнителем, он исчез из вывода. Что еще более важно, если вы никогда не определяете селектор, который расширяется %animal, его стили ( background: gray;и т. д.), то они полностью исключаются из вывода. Это может быть очень полезно для авторов структуры SCSS, поскольку вы можете предложить любое количество базовых классов для расширения, но только те, которые фактически используются , выводятся в полученный CSS.
Селекторы-заполнители на самом деле способны даже на большее, а именно, расширяя часть %placeholder до более сложного селектора во время @extend, но лично мне никогда не приходилось использовать эту функцию. Если вам это интересно, можете почитать документы по этому вопросу.

16. Множественное наследование селекторов

Селектор на самом деле может наследовать от нескольких других селекторов, то есть SCSS поддерживает множественное наследование. Для каждого @extend к расширенному селектору добавляется текущий селектор. В сочетании с селекторами-заполнителями это позволяет использовать мощные абстракции для авторов фреймворка. Это, пожалуй, лучше всего объяснить на примере:

У этого способа создания стилей есть несколько значительных преимуществ:

    • Самодокументация: вместо того, чтобы записывать множество анонимных свойств стиля, автор указывает «признаки» компонента пользовательского интерфейса, которые он проектирует. Имена признаков могут быть длинными и дескриптивными по мере необходимости (они не будут отображаться в выводе CSS).
    • Изоляция именования: приложение может использовать любые соглашения об именах и семантику в HTML, в то время как соглашения об именах фреймворков остаются внутренними по отношению к источнику SCSS. В приведенном выше примере структура принимает общий префикс %mfw(для «my framework» или что-то подобное), чтобы избежать повторений имен с другими библиотеками SCSS.
    • Уменьшение повторений: #join-button может использовать помощников border-radius()и box-shadow() непосредственно для достижения того же стилистического эффекта. Но для каждого дополнительного компонента, который делает это, помощник box-shadow() выводит точно такие же строки CSS, со всеми префиксами vendor и еще много чего. Однако расширение %mfw-slightly-shadowed просто добавляет селектор в список других селекторов, которые должны получить затенение.
    • Опция: если конкретный «признак» никогда не используется для описания компонента пользовательского интерфейса, его стили никогда не выводятся. То есть, если вы используете только 1% функций раздутой структуры стиля, ваша полезная нагрузка CSS будет содержать только 1%. Сравните это с де-факто способом просто включить весь Bootstrap или jQuery, потому что сайт использует 1 или 2 функции от каждого.

Потенциальные недостатки этого подхода, которые следует учитывать:

    • Отладка: без правильно настроенных исходных карт для SCSS может оказаться труднее выяснить, каким образом какой-то стиль повлиял на конкретный элемент (имея в виду, что вышеописанная точка самодокументации больше не применяется в скомпилированном CSS).
  • Аргументы: этот метод не будет заменять mixin, когда вычисление должно быть на основе некоторых аргументов. Хотя может быть несколько версий каждой «черты» (например, %mfw-slightly-shadowed против %mfw-heavily-shadowed), они всегда будут полностью статичными по содержанию.



1 комментарий

  1. Сам раньше использовал связку SASS+Compass, но сейчас отказался в пользу постпроцессоров считая, что это уже старый вариант. Они гибче, более расширяемы и функциональней, а возможности те же и дальше больше.