I have an item class and a compact "modifier" class:
.item { ... }
.item.compact { /* styles to make .item smaller */ }
This is fine. However, I'd like to add a @media
query that forces the .item
class to be compact when the screen is small enough.
On first thought, this is what I tried to do:
.item { ... }
.item.compact { ... }
@media (max-width: 600px) {
.item { @extend .item.compact; }
}
But this generates the following error:
You may not @extend an outer selector from within @media. You may only @extend selectors within the same directive.
How would I accomplish this using SASS without having to resort to copy/pasting styles?
The simple answer is: you can't because Sass can't (or won't) compose the selector for it. You can't be inside of a media query and extend something that's outside of a media query. It certainly would be nice if it would simply take a copy of it instead of trying to compose the selectors. But it doesn't so you can't.
If you have a case where you're going to be reusing a block of code inside and outside of media queries and still want it to be able to extend it, then write both a mixin and an extend class:
@mixin foo {
// do stuff
}
%foo {
@include foo;
}
// usage
.foo {
@extend %foo;
}
@media (min-width: 30em) {
.bar {
@include foo;
}
}
This won't really help your use case, but it is another option:
%foo {
@media (min-width: 20em) {
color: red;
}
}
@media (min-width: 30em) {
%bar {
background: yellow;
}
}
// usage
.foo {
@extend %foo;
}
.bar {
@extend %bar;
}
There are a number of ongoing discussions regarding this issue (please don't contribute to these threads unless you have something meaningful to add: the maintainers are already aware that users desire this functionality, it's just a question of how to implement it and what the syntax should be).