Чуть больше SASS для (БЭ)Модификаторов

В начале 2013 года синтаксис «Блок, Элемент, Модификатор» (БЭМ), применяемый к CSS, стал крайне популярной методологией организации кода, добавляющей определенное единообразие в проекты. Если брать в целом, то я просто обожаю БЭМ. Он действительно хорошо структурирован, и для меня это важно. Единственное, что меня волновало все это время, да и не только меня, но и большинство моих коллег разработчиков — это то, насколько длинными и избыточными становились значения атрибута class у элементов. Особенно, когда дело доходило до модификаторов.

<button>

Обособленные модификаторы: сокращенный синтаксис

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

И при этом мы сохраним дефис в начале имени класса, чтобы показать, что он является модификатором.

HTML

<button>

SCSS

.button {
	&.-green {...}
	&.-rounded {...}
	&.-large {...}
}	

Такой ход обеспечивает наглядное отделение элементов и модификаторов, позволяя при этом избегать повторения в имени класса. И да, использование дефиса в качестве первого символа в селекторе валидно, а вот использование двойного дефиса — нет. Если вас действительно беспокоят селекторы по нескольким классам, то возможно, что у вас просто остались плохие воспоминания об ужасах времен IE6. Но, поверьте, вам больше действительно не стоит о нём беспокоиться.

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

SCSS

.button {
	&.-hoverable {
		&:hover {
			opacity: 0.75;
		}
	}
}
.overrides {
	&.-disabled {
		opacity: 0.25;
	}
}	

HTML

<button>Disabled</button>	

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

.button.-hoverable, перекрывается другими свойствами, указанными для селектора .overrides.-disabled, обладающего той же специфичностью, но определенного в таблице позже.

Сохраненные вариации: расширение с помощью Sass

Гибкость использования модификаторов в разметке — это круто, но когда я замечаю часто повторяющиеся группы свойств, я предпочитаю комбинировать их в моей таблице стилей. Директива @extend в Sass отлично подходит для этого.

SCSS

.button--save {
	@extend %button;
	@extend %button--large;
	@extend %button--rounded;
	@extend %button--green;
}	

HTML

<button>Save</button>	

Весьма наглядно. В этом примере вы должны обратить свое внимание на следующее:

  1. я использую селектор-плейсхолдер % в Sass;
  2. и я все еще использую обычный синтаксис БЭМ элемент--модификатор.

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

%button {
	background: #45beff;
	border: none;
	padding: 1em 2em;
	font-size: 16px;
	
	&:hover {
	    opacity: 0.75;
	}
}
%button--green {
	background: #3efa95;
}
%button--red {
	background: #ff3a6a;
}
%button--large {
	font-size:20px;
}
%button--rounded {
	border-radius: 10px;
}

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

.button {
	@extend %button;
	&.-green {
		@extend %button--green;
	}
	&.-large {
		@extend %button--large;
	}
}
. button--delete {
	@extend %button;
	@extend %button--large;
	@extend %button--rounded;
	@extend %button--red;
}

Посмотреть пример на CodePen.

От БЭМ к БЭВМ?

После всего, что сказано и сделано выше, паттерн БЭМ блок__элемент--модификатор для меня трансформировался во что-то более похожее на блок__элемент--вариация -модификатор (БЭВМ), дополненный внутренними Sass-селекторами вида %модификатор.

// Внутренний модификатор
%button--red {
	background: #ff3a6a;
}
// Элемент
.button {
	// Модификатор
	&.-red {
		@extend %button--red;
	}
}
// Вариация
.button--delete {
	@extend %button;
	@extend %button--red;
}

Мне все это нравится, а что думаете вы? Удобно? Странно? Давайте обсудим!

sass — Почему люди используют @extend в SCSS?

спросил

2 года, 1 месяц назад

Изменено 2 года, 1 месяц назад

Просмотрено 9к раз

В Sass я обнаружил, что могу использовать ‘@extend’ с ‘@mixin’. Но из кода мне стало любопытно, в чем преимущество использования расширения.
Если мы точно знаем, какие «классы» нам нужно использовать, мы можем просто использовать два класса, а не расширять и создавать еще один класс.

На мой взгляд, если бы мы просто использовали два класса, не делая множественных расширений, код был бы короче, и мы могли бы сэкономить память. Что я могу сказать о преимуществе, так это то, что его просто легче увидеть на «выводе CSS», но обычно люди просто проверяют файл SCSS, а не вывод кода CSS.

Не лучше ли использовать два отдельных класса вместо использования нескольких расширений? В чем основное преимущество использования ‘@mixin’?

  • sass
  • scss-примеси

5

Помогает быстро писать СУХОЙ код. @extend может быть очень полезен при правильном использовании.

Позволяет селектору расширять стили другого селектора, по существу предоставляя форму подкласса.

@extend работает, объединяя селекторы в один селектор, разделенный запятыми.

Т.е. —

 .А {
    размер шрифта: 1rem;
    красный цвет;
}
.а{
    @продлить .А;
    высота строки: нормальная;
   }
Что выводит:
.А,.а {
   размер шрифта: 1rem;
    красный цвет;
}
.а{
   высота строки: нормальная;
}
 

2

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

  • они изменяют порядок ваших правил CSS и часто неловко перегруппировывают их, что может привести к непреднамеренным проблемам в будущем
  • они менее производительны, чем миксины, когда ваш Sass минимизирован и сжат с помощью gzip.

Отличная статья Гарри Робертса с подробным описанием этих проблем: «Примеси для лучшей производительности»

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя адрес электронной почты и пароль

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

SASS: использование @extend с @use

Задавать вопрос

спросил

Изменено 2 года, 6 месяцев назад

Просмотрено 3к раз

У меня есть два следующих файла:

 main. scss
|- база
| |- _typography.scss
 

Файл _typography.scss содержит:

 $font-family: Roboto;
%опечатка-кнопка{
    семейство шрифтов: $font-family;
    размер шрифта: 14px;
    вес шрифта: 500;
    преобразование текста: верхний регистр;
}
 

Теперь я пытаюсь @расширить класс в main.scss с заполнителем %typo-button.

 @use 'база/типографика';
.кнопка{
    отображение: встроенный блок;
    высота: 48 пикселей;
    отступ: 12px 0px;
    @расширить типографику.%typo-button;
}
 

Возникает следующая ошибка:

 Ошибка: ожидаемый идентификатор.
│ @расширить типографику.%typo-button;
 

Итак, каков правильный синтаксис для использования @extend с @use ? Использование @use с @mixin не проблема, например. @include typography.my-mixin() . Но в некоторых случаях я хотел бы использовать @extend вместо примесей.

  • sass
  • extend

Префиксы пространств имен не нужны на @extends — только для функций, примесей и переменных. Удалите типографику . и должно работать:

 @use 'base/typography';
.кнопка{
    отображение: встроенный блок;
    высота: 48 пикселей;
    отступ: 12px 0px;
    @продлить %typo-button;
}
 

(Упомянутое выше ограничение восходящего потока означает, что модуль «typography» не может расширять что-либо внутри «основного» модуля, который его использует, но селекторы в «main» могут расширять селекторы в «typography».)

0

Я считаю, что у вас есть два способа решить эту проблему:

первый — использовать @mixin вместо %typo-button и @include typography.typo-button вместо @extend typography .typo-button

ИЛИ

вам нужно @use '../main' внутри _typography.