SCSS-переопределение @extend другим @extend


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

Вот пример:

// class selectors to be @extended
// these could also use % to be silent/placeholder selectors
.size-2xl {
    @include rem(font-size, 40px);
}
.size-3xl {
    @include rem(font-size, 60px);
}

// mapping the class selector properties onto some structural classes
.heading1 {
    @extend .size-3xl;
}
.heading1-small {
    @extend .heading1;
    @extend .size-2xl;
}

Когда SCSS компилируется, .heading1 и .heading1-small получат правильные свойства, но .heading1-small будут слишком большими.

Это, по-видимому, происходит, когда класс @extend - able отображается на несколько различных селекторов.

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

Иногда SCSS кажется скомпилированным "не по порядку", так что скомпилированный .heading1 множественный селектор выводится после .heading1-small множественного селектора.

Это может быть даже вложенный @extend, вызывающий такое поведение.

Как лучше всего избежать этой ситуации? Некоторые вещи, о которых я могу думать с верхней части моей головы:
  1. использовать @include('size-2xl') (менее сухой)
  2. не @extend Правила, содержащие @extend (ограничивает использование @ extend)

Спасибо.

1 6

1 ответ:

Наборы правил в выходном CSS находятся точно в том же месте/порядке/последовательности, как они были определены в SCSS, только вы выводите только расширенные .size-2xl и .size-3xl наборы правил. Поэтому вам нужно поменять местами эти два определения правил (см. демо-версия) или определите правила size как микшины и включите их в заголовок правила (см. демо-версия). Итак, я думаю, что вы, должно быть, путаете что-то о том, как работает @extend.

Если вы есть что-то вроде этого:

.class1 {
   foo: bar1;
}

.class2 {
   foo: bar2;
   @extend .class1;
}

Вы только добавите селектор .class2 к уже существующему набору правил с селектором .class1 - так что выход будет выглядеть следующим образом:

.class1, .class2 {
   foo: bar1;
}

.class2 {
   foo: bar2;
}

Однако, если мы не добавим никаких новых свойств к .class2 , а просто используем @extend:

.class1 {
   foo: bar1;
}

.class2 {
   @extend .class1;
}

Набор правил .class2 не будет напечатан в CSS, и только селектор будет добавлен в .class1 - отсюда вывод:

.class1, .class2 {
   foo: bar1;
}

Это более или менее то, что вы делаете, просто добавляя селекторы .header1 и .header2 к правилам .size-2xl и .size-3xl, таким образом, выходные данные будут находиться в том же месте/порядке, в котором эти правила определены в SCSS.

Итак, что вы получите в конце вашего примера:

  • вы определяете наборы правил .size-2xl и .size-3xl
  • вы добавляете селектор .header1-small в наборы правил .size-2xl
  • вы добавляете .header1-small в селектор .header1 и добавляете оба в набор правил .size-3xl
  • набор правил .size-2xl (Теперь после расширения: .size-2xl, .header1-small) печатается в CSS
  • набор правил .size-3xl (Теперь после расширения: .size-3xl, .header1, .header1-small) печатается в CSS
  • набор правил .header1 (также расширенный .header1, .header1-small) не распечатывается, так как не имеет определенных свойств
  • набор правил .header1-small не распечатывается, так как не имеет определенных свойств

Еще одно примечание: то же самое произойдет и при использовании селекторов заполнителей (%), только тогда это может быть еще более запутанным, например в .size-3xl, .header1, .header1-small .size-3xl будет невидимым, но в CSS все это будет по-прежнему компилироваться в том месте, где Правило .size-3xl было определено в SCSS.