Розширення селекторів із медіа-запитів за допомогою Sass


86

У мене є клас предметів та компактний клас "модифікатора":

.item { ... }
.item.compact { /* styles to make .item smaller */ }

Це добре. Однак я хотів би додати @mediaзапит, який змушує .itemклас бути компактним, коли екран досить малий.

На перший погляд, це те, що я намагався зробити:

.item { ... }
.item.compact { ... }
@media (max-width: 600px) {
  .item { @extend .item.compact; }
}

Але це породжує таку помилку:

Ви не можете @extend зовнішній селектор зсередини @media. Ви можете лише @extend селектори в межах тієї самої директиви.

Як мені досягти цього за допомогою SASS, не вдаючись до копіювання / вставки стилів?


Fyi, ось проблема, через яку приклад, який ви навели, працює правильно: github.com/sass/sass/issues/1050
Ajedi32

Відповіді:


112

Проста відповідь: ви не можете, тому що Сасс не може (або не хоче) скласти селектор для нього. Ви не можете знаходитись усередині медіа-запиту і розширювати щось, що знаходиться поза медіа-запитом. Звичайно, було б непогано, якби просто скопіювати її, а не намагатися скласти селектори. Але це не так, ви не можете.

Використовуйте міксин

Якщо у вас є випадок, коли ви збираєтеся повторно використовувати блок коду всередині та поза медіа-запитів і все одно хочете, щоб він міг його розширити, тоді напишіть і мікшин, і клас розширення:

@mixin foo {
    // do stuff
}

%foo {
    @include foo;
}

// usage
.foo {
    @extend %foo;
}

@media (min-width: 30em) {
    .bar {
        @include foo;
    }
}

Розширте селектор у медіа-запиті ззовні

Це насправді не допоможе вашому випадку використання, але це інший варіант:

%foo {
  @media (min-width: 20em) {
    color: red;
  }
}

@media (min-width: 30em) {
  %bar {
    background: yellow;
  }
}

// usage
.foo {
  @extend %foo;
}

.bar {
  @extend %bar;
}

Зачекайте, поки Сасс скасує це обмеження (або виправте його самостійно)

З цією проблемою триває низка постійних дискусій (будь ласка, не робіть внесок у ці теми, якщо у вас немає чогось змістовного для додавання: супровідники вже знають, що користувачі бажають цієї функціональності, це лише питання про те, як її реалізувати та що синтаксис повинен бути).


@mindeavor Це працювало у вас? Ви змогли використовувати розширений клас у медіа-запиті? У Sass 3.2?
Yahreen

1
%fooє непотрібним, .fooможе безпосередньо @include foo.
phil294

У моєму випадку я щойно використав% заповнювач із розширенням зовнішніх медіа-запитів. Потім, всередині медіа-запиту, для мого селектора щойно додано exte% placeholder. Побачимо, чи не відбудуться обговорення з чимось зручним. Дякую Кімманону.
брелок

11

Для запису, ось як я врешті-решт вирішив проблему лише дублюючи створені стилі один раз:

// This is where the actual compact styles live
@mixin compact-mixin { /* ... */ }

// Include the compact mixin for items that are always compact
.item.compact { @include compact-mixin; }

// Here's the tricky part, due to how SASS handles extending
.item { ... }
// The following needs to be declared AFTER .item, else it'll
// be overridden by .item's NORMAL styles.
@media (max-width: 600px) {
  %compact { @include compact-mixin; }

  // Afterwards we can extend and
  // customize different item compact styles
  .item {
    @extend %compact;
    /* Other styles that override %compact */
  }
  // As shown below, we can extend the compact styles as many
  // times as we want without needing to re-extend
  // the compact mixin, thus avoiding generating duplicate css
  .item-alt {
    @extend %compact;
  }
}

2

Я вважаю, що SASS / SCSS не підтримує @extendдирективу всередині медіа-запиту. http://designshack.net/articles/css/sass-and-media-queries-what-you-can-and-cant-do/

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


Посилання на рішення вітається, але будь ласка, переконайтеся, що ваша відповідь корисна без нього: додайте контекст навколо посилання, щоб ваші однодумці мали певне уявлення, що це таке і чому воно є, а потім цитуйте найвідповіднішу частину сторінки, яку ви хочете повторне посилання на випадок, якщо цільова сторінка буде недоступна. Відповіді, які є лише кількома посиланнями, можуть бути видалені.
dippas

1

Це найчистіше, часткове рішення, яке я знайшов. Він використовує переваги @extend, де це можливо, і повертається до мікшинів, коли всередині медіа-запитів.

Крос-медіа-запити @extend Директиви в Sass

Подивіться статтю, щоб отримати докладні відомості, але суть полягає в тому, що ви викликаєте мікшинний "заповнювач", який потім вирішує, чи потрібно виводити @extend або @include.

@include placeholder('clear') {
   clear: both;
   overflow: hidden;
}

.a {
    @include _(clear);
}
.b {
    @include _(clear);
}
.c {
    @include breakpoint(medium) {
      @include _(clear);
   }
}

Зрештою, це може бути не краще, ніж просто використовувати міксини, що в даний час є прийнятою відповіддю.


0

Я використовую точки зупинку, але це та сама ідея:

@mixin bp-small {
    @media only screen and (max-width: 30em) {
        @content;
    }

Як користуватися ним:

.sidebar {
    width: 60%;
    float: left;
    @include bp-small {
        width: 100%;
        float: none;
    }
}

Існує текст про міксини, де ви можете дізнатись більше про цей варіант.


-2

Не могли б ви реструктуризуватися?

.compact { //compact-styles }
.item {}
.item.compact { @extend .compact } 

@media (max-width: 600px) {
    .item { @extend .compact; }
}

Якщо я правильно розумію документацію, це має спрацювати. Я думаю, що причина того, як ви намагаєтесь, не спрацює, полягає в тому, що він не бачить .item.compact, коли аналізує @extend, але це неінформована здогадка, тож візьміть це з вантажем солі! :)


Як ви складаєте свій SASS? Зовні, з JS, або з якимось серверним компонентом?
Jason M. Batchelor

Він компілюється через стандартний rails-sassсамоцвіт, використовуючи SASS v3.2.4
soundly_typed

1
Схоже, можливість розширювати запити @media застаріла і має бути виправлена в 3.3: chriseppstein.github.com/blog/2012/08/23/sass-3-2-is-released (прочитайте область із написом "Обмеження @extendв директивах CSS")
Джейсон М. Батчелор,

Якщо я зрозумів цю інформацію правильно, це може бути причиною проблеми. Мені було б цікаво дізнатись, що ти дізнаєшся!
Джейсон М. Батчелор
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.