Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow @extend across media queries #1050

Open
Snugug opened this issue Dec 16, 2013 · 80 comments
Open

Allow @extend across media queries #1050

Snugug opened this issue Dec 16, 2013 · 80 comments
Labels
enhancement New feature or request planned We would like to add this feature at some point

Comments

@Snugug
Copy link

Snugug commented Dec 16, 2013

Edit: The current plan here is to allow @extend across media queries by duplicating the queries the current @extend is in and unifying them with any media queries the extendee is in. For example:

.a {w: x}
@media (min-width: 500px) {
  .b {@extend .a}
  .c {y: z}
}

would produce

.a {w: x}
@media (min-width: 500px) {
  .b {w: x}
}

@media (min-width: 500px) {
  .c {y: z}
}

and

@media screen {
  .a {w: x}
}

@media (min-width: 500px) {
  .b {@extend .a}
  .c {y: z}
}

would produce

@media screen {
  .a {w: x}
}
@media screen and (min-width: 500px) {
  .b {w: x}
}

@media (min-width: 500px) {
  .c {y: z}
}

Original issue follows:


As originally brought up in #456, one way to allow extending across media queries would be to have a flag for @extend to explicitly tell Sass that you're OK with creating a duplicate context in a similar fashion to how the !optional flag currently works.

The syntax as currently proposed would look/work something like the following:

%full {
  width: 100%;
  float: left;
  clear: both;
}

%half {
  width: 50%;
  float: left;
}

.sidebar-1 {
  @extend %full;
  background: blue;
  @media (min-width: 500px) {
    @extend %half !duplicate; // A new extend context will be created here for the all, min-width: 500px media context and extension will work as normal.
    background: red;
  }
}

.sidebar-2 {
  @extend %full;
  background: green;
  @media (min-width: 500px) {
    @extend %half !duplicate; // Because a context for this exact media query already exists, it will extend that one instead of creating a duplicate context
    background: orange;
  }
}

.content {
  @extend %half;
  background: purple;
}

would compile to

.sidebar-1, .sidebar-2 {
  width: 100%;
  float: left;
  clear: both;
}

.content {
  width: 50%;
  float: left;
}

.sidebar-1 {
  background: blue;
}

@media (min-width: 500px) {
  .sidebar-1, .sidebar-2 {
    width: 50%;
    float: left;
  }

  .sidebar-1 {
    background: red;
  }
}

.sidebar-2 {
  background: green;
}

@media (min-width: 500px) {
  .sidebar-2 {
    background: orange;
  }
}

.content {
  background: purple;
}

Of course the optimization around this would be difficult, needing to ensure that the matching only happens for identical @media contexts (but include ones in or chains) and a decision would need to be made as to if the selectors should be moved to the first or last item as the normal @extend pattern of "all" doesn't quite make sense here, but because it is an explicit call, a user will understand that they're changing how it works.

@robwierzbowski
Copy link

I like the idea of combining contexts/queries per extend, but not necessarily combining contexts/queries between different extends or with non-extended rulesets. My ideal would be:

SCSS

%half {
 width: 50%;
}

%full {
 width: 100%;
}

.one {
  @extend %half;
}

.two {
  @extend %full;
  @media (min-width: 30em) {
    @extend %half;
    color: blue;
  }
}

.three {
  @media (min-width: 30em) {
    @extend %full;
  }
}

CSS

.one {
  width: 50%;
}

@media (min-width: 30em) {
  .two {
    width: 50%;
  }
}

.two {
  width: 100%;
}

@media (min-width: 30em) {
  .three {
    width: 100%;
  }
}

.two {
  color: blue;
}

...keeping source order and general extend behavior as expected. For me, simplicity of behavior and sticking close to existing patterns trumps optimization. I'd prefer to combine all mqs with a post processor or optional Sass flag in a separate step.

I'm not sure what the status of this behavior (which has been proposed a couple times) is; if anyone knows of an issue tracking/rejecting it, please let me know. Really, anything that gets @extends and MQs working together is good for me.

@nex3
Copy link
Contributor

nex3 commented Dec 30, 2013

@robwierzbowski If we add this flag, it will likely have the behavior you suggest. Changing the source order is something we're very keen to avoid.

@chriseppstein
Copy link

The issue here is that you have a pattern that is not properly abstracted. The pattern is that there is some elements which are full width for small screens that become half width for large screens. If you have expressly created this abstraction you will have an easier to understand stylesheet and Sass won't have to do backflips to optimize your unnamed abstractions.

@mixin column($width, $last: $width == 100%) {
  float: left;
  width: $width;
  @if $last {
    clear: both;
  }
}

@mixin for-large-screens {
  @media (min-width: 500px) {
    @content;
  }
}

%full {
  @include column(100%);
}

%half {
  @include column(50%);
}

@include for-large-screens {
  %half-lg {
    @include column(50%);
  }
}

%full-to-half {
  @extend %full;
  @extend %half-lg;
}

.sidebar-1 {
  @extend %full-to-half;
  background: blue;
  @include for-large-screens {
    background: red;
  }
}

.sidebar-2 {
  @extend %full-to-half;
  background: green;
  @include for-large-screens {
    background: orange;
  }
}

.content {
  @extend %half;
  background: purple;
}
.sidebar-1, .sidebar-2 {
  float: left;
  width: 100%;
  clear: both;
}

.content {
  float: left;
  width: 50%;
}

@media (min-width: 500px) {
  .sidebar-1, .sidebar-2 {
    float: left;
    width: 50%;
  }
}
.sidebar-1 {
  background: blue;
}
@media (min-width: 500px) {
  .sidebar-1 {
    background: red;
  }
}

.sidebar-2 {
  background: green;
}
@media (min-width: 500px) {
  .sidebar-2 {
    background: orange;
  }
}

.content {
  background: purple;
}

I remain unconvinced that Sass needs any magic for extend within runtime-based contexts. I find the above stylesheet more understandable than your original. Additionally, by reading it, it's very easy to deduce what the output will be.

@Snugug
Copy link
Author

Snugug commented Jan 6, 2014

@chriseppstein The issue with what you've written is it actually goes against the best practices of responsive web design. When working with media queries, the best practice is to make changes as needed and not necessarily group them all together, especially true when it comes to grids as different layouts tend to ebb and flow much more than full-to-half. With the way you've described, every single different permutation of change between every single set of grids one may have across all permutations of media queries would need to be made available which is a maintenance nightmare and will easily become hard to decipher for developers. On the other hand, if each layout were to have their own extendable and could be called as such, that would make it infinitely easier to mix and match, and what was happening would be easier to grok.

Let's also not forget that this isn't just for layouts, it's for any number of items. Background image, clearfixes, box sizing, fonts stacks and definitions, all can benefit from being able to be extended from within a MQ and have a context created and needing to create extendable classes for all of their potential permutations seems like a maintenance headache as well.

@emagnier
Copy link

emagnier commented Jan 6, 2014

+1, I'm completely agree with the latest comment of @Snugug.
I already had this need, and had to do some code gymnastics to get round this limitation. This gave things ​​less flexible, and more difficult to read and maintain.

@robwierzbowski
Copy link

My example was based off @Snugug's (which I think is valid). But disagreeing with the example is not a disagreement with the issue.

@chriseppstein Do you think we shouldn't be able to extend a(ny) value from within a media query? By which I mean apply <rules> to <selector>, where <selector> is .class or @media (foo) { .class }.

In my experience this is one of the most often requested features in Sass, both verbally among my peers and from what I see in issue queues and comment threads on the internet.

@nex3
Copy link
Contributor

nex3 commented Jan 7, 2014

I want to continue considering this. Even if it's the case that there's a better factoring available for every stylesheet that wants to extend out of a media query, it's clear that users aren't able to see that refactoring easily. @robwierzbowski is right that this is highly-requested functionality. People run into the issue of extending out of media queries frequently, and I'd like a solution that we can at least explain in the error message.

@chriseppstein
Copy link

The definition of A { @extend B; } is to style elements matching A as if it matched selector B.

The definition of @media (some runtime expression) { A { @extend B; } } is to style elements matching A as if matching B when the media matches some runtime expression.

I'm not trying to tell people that they are wrong for wanting this to work. I think they are right for wanting this to work. Hell, I want this to work. But the bottom line is that a precompiler simply cannot implement this semantic without yielding output that we've deemed as too magical and bloat prone.

I'm love that you guys want this feature. You're preaching to the choir. You need to take this argument up with the CSS working group. Until then, I feel the @at-root directive provides enough of an escape hatch for people who know what they are doing to accomplish their needs.

I don't see any point in continuing to beat this dead horse.

@nex3
Copy link
Contributor

nex3 commented Feb 24, 2014

I think it's reasonable to allow users to opt in to the extra bloat. As I mentioned above, it's clear that users aren't able to easily figure out how to use @at-root to work around this.

@chriseppstein
Copy link

@nex3 I'm not convinced. We've only just introduced @at-root and there is a learning/education period that is required to decide that. Furthermore, we have a way to produce bloat: mixins. I am against making @extend sometimes a selector operation and sometimes a rule copy operation. I'd rather see users write mixins that conditionally extend or include. This is not a feature Sass needs to add.

Additionally, I feel this will only increase the confusion about how people think that placeholder selectors can only be used like simple mixin declarations (having no arguments) rather than the powerful selector concept that they are.

@nex3
Copy link
Contributor

nex3 commented Feb 24, 2014

We've only just introduced @at-root and there is a learning/education period that is required to decide that.

Can you summarize tersely how to take any cross-media @extend and make it work using @at-root? I don't fully understand the process myself.

Furthermore, we have a way to produce bloat: mixins. I am against making @extend sometimes a selector operation and sometimes a rule copy operation.

I would rather have users think of @extend as a semantic operation than in terms of its effect on the physical stylesheet. Making users switch between @extend and @include based on whether they're within a @media block makes the semantic abstraction more leaky, while having Sass make @extend itself work however necessary makes it less leaky.

Additionally, I feel this will only increase the confusion about how people think that placeholder selectors can only be used like simple mixin declarations (having no arguments) rather than the powerful selector concept that they are.

I'd rather focus our education efforts here than on complex work-arounds for @extend in @media.

@chriseppstein
Copy link

Can you summarize tersely how to take any cross-media @extend and make it work using @at-root? I don't fully understand the process myself.

@at-root (without: media) { & { extend .something; }} removes the runtime context so that the extend operation can be performed as if it were not within a media context. This is useful in places where the base definition is a constant across all media definitions or is appropriately overridden via the cascade even when applied across media types.

I would rather have users think of @extend as a semantic operation than in terms of its effect on the physical stylesheet.

I want this too. Opting-in using !duplicate or some other syntax makes the user think about it. Not requiring an opt-in causes huge surprise when the stylesheet bloats like using mixins. I think we have reached the boundary where @extend can be implemented in a preprocessor without being a leaky abstraction.

I'd rather focus our education efforts here than on complex work-arounds for @extend in @media.

There is going to be education required no matter how we tackle this problem.

@nex3
Copy link
Contributor

nex3 commented Feb 25, 2014

@at-root (without: media) { & { extend .something; }} removes the runtime context so that the extend operation can be performed as if it were not within a media context. This is useful in places where the base definition is a constant across all media definitions or is appropriately overridden via the cascade even when applied across media types.

This doesn't scope the definition to the media query, though, which I think is what users are trying to express. Ensuring that the properties cascade so that a top-level extension works out is complicated and contingent on the specifics of the user's CSS.

I want this too. Opting-in using !duplicate or some other syntax makes the user think about it. Not requiring an opt-in causes huge surprise when the stylesheet bloats like using mixins. I think we have reached the boundary where @extend can be implemented in a preprocessor without being a leaky abstraction.

I agree that the abstraction is still leaky, but !duplicate (or whatever) makes it less leaky, and there's value in that. @extend is how users expect to be able to express this -- we have ample evidence of that from the volume of requests we get for it to work.

@robwierzbowski
Copy link

I really appreciate the points on both sides here, and I think they're
making the argument for extend with a flag very strong. It's a syntax that
users expect, and the code result proposed is no larger than any equivalent
code produced by at-root.

I agree with Nathan that users (like myself) specifically want to extend
the styles but scope them to the query. I can imagine a couple ways of
creating mixins with at root that would accomplish this, but none so direct
or understandable as processing at the Sass level with extend.

On Monday, February 24, 2014, Nathan Weizenbaum notifications@github.com
wrote:

@at-root (without: media) { & { extend .something; }} removes the runtime
context so that the extend operation can be performed as if it were not
within a media context. This is useful in places where the base definition
is a constant across all media definitions or is appropriately overridden
via the cascade even when applied across media types.

This doesn't scope the definition to the media query, though, which I
think is what users are trying to express. Ensuring that the properties
cascade so that a top-level extension works out is complicated and
contingent on the specifics of the user's CSS.

I want this too. Opting-in using !duplicate or some other syntax makes
the user think about it. Not requiring an opt-in causes huge surprise when
the stylesheet bloats like using mixins. I think we have reached the
boundary where @extend can be implemented in a preprocessor without being
a leaky abstraction.

I agree that the abstraction is still leaky, but !duplicate (or whatever)
makes it less leaky, and there's value in that. @extend is how users
expect to be able to express this -- we have ample evidence of that from
the volume of requests we get for it to work.

Reply to this email directly or view it on GitHubhttps://github.com//issues/1050#issuecomment-35961979
.

Rob Wierzbowski
@robwierzbowski http://twitter.com/#!/robwierzbowski
http://github.com/robwierzbowski
http://robwierzbowski.com

@chriseppstein
Copy link

You both seem to be thinking that I'm disputing the use case. I'm not. I simply think that it's not a direction sass should go. I think the implementation is very tricky and the output is going to surprise users. even the ones who add the !duplicate flag because Sass says "Hey you gotta add the !duplicate flag to do this and it's going to copy all this stuff for ya".

Furthermore, I think Sass's set of existing abstractions enables users to accomplish this in "user space".

These are all the criteria that Nathan usually uses to justify not doing something and I'm usually the one arguing for Sass making things easier. I think he just likes to disagree with me. >_<

@robwierzbowski
Copy link

My thought is that there isn't a way with current abstractions to do what I and other users are asking. Is there a way to create the behavior in #1050 (comment) with four breakpoints and twelve collumns? I don't think a matrix of mixin-utilizing extends for each viewport and widths combination used (12col-to-6col-to-3col, 12col-to-12col, 8col-to-4col-pushed-2col-to-6col, etc.) is a realistic solution.

@chriseppstein
Copy link

@robwierzbowski Yes. As long as you can name each break point. Mixins, at-root, and extend are powerful enough to express the exact behavior that is desired. I guess I need to write a Sass library that demonstrates how.

@nex3
Copy link
Contributor

nex3 commented Feb 26, 2014

Furthermore, I think Sass's set of existing abstractions enables users to accomplish this in "user space".

This is the crux of the issue for me. The user-space solution you're suggesting is complex and requires a large-scale restructuring of the surrounding Sass to make it work. Users are looking for a drop-in solution and you're proposing a full refactoring of their stylesheets. We have the power to provide precisely the semantics they're asking for; we can't do it for free, but I think conditionally adding bloat is a better compromise than trying to teach everyone a refactoring technique that it seems like no one but you understands.

@chriseppstein
Copy link

We have the power to provide precisely the semantics they're asking for

Well, the semantics I'm seeing asked for don't make sense to me. Sometimes it acts like extend and sometimes it acts like include. I very much dislike this. The most important aspect of @extend is that is preserves the function of the cascade. The proposal on the table here is to copy things to the location of the @extend statement -- this is going to change the cascade and makes the implementation complex because the extend step now has to do a lot more than selector rewriting.

Instead, I think a solution would need to add @media directives all over the document -- wherever an extended selector is found; just like we do with selectors now.

An example:

.a { prop1: value1; }
.b { prop2: value2; }
@media (...phone...) { .c { @extend .a; prop3: value3; } }
@media (...tablet...) { .d { @extend .b; prop4: value4; } }
.e .a { prop5: value5; }

would compile to:

.a { prop1: value1; }
@media (...phone...) { .c { prop1: value1; } }
.b { prop2: value2; }
@media (...tablet...) { .d { prop2: value2; } }
@media (...phone...) { .c { prop3: value3; } }
@media (...tablet...) { .d { prop4: value4; } }
.e .a { prop5: value5; }
@media (...phone...) { .e .c { prop5: value5; } }

The implementation of this is a lot less complex as well.

@cimmanon
Copy link

Sometimes it acts like extend and sometimes it acts like include.

Newcomers to Sass don't understand the difference or why it matters.

The most important aspect of @extend is that is preserves the function of the cascade.

Again, most users don't understand this. All they understand is that it consolidates selectors, which means more compact CSS to them (though this isn't always the case). Users are disappointed that code like this doesn't work:

%clearfix {
    /* clearfix stuff */
}

.one {
    color: blue;
    @extend %clearfix;
}

.two {
    color: green;
    @media (min-width: 50em) {
        @extend %clearfix;
    }
}

.three {
    @extend %clearfix;
}

.four {
    color: orange;
    @media (min-width: 40em) {
        @extend %clearfix;
    }
}

The normal expectation is that it would generate something like this:

.one, .three {
    /* clearfix stuff */
}

.one {
    color: blue;
}

@media (min-width: 50em) {
    .two {
        color: green;
        /* clearfix stuff */
    }
}

@media (min-width: 40em) {
    .four {
        color: orange;
        /* clearfix stuff */
    }
}

To propose sprinkling extra media queries everywhere is the exact opposite of what users expect when they use extend (smaller CSS). Easier to write doesn't make for a good experience. Would adding a LESS-style include (where classes are also mixins with no arguments) really be that bad? I don't think anyone cares what it's called (extend vs include vs copy-it-here-because-i-said-so), they just want the behavior.

@robwierzbowski
Copy link

Sass isn't only for newcomers. Preserving source order at the expense of a
little more markup is a positive trade IMO.

Rob Wierzbowski
@robwierzbowski http://twitter.com/#!/robwierzbowski
http://github.com/robwierzbowski
http://robwierzbowski.com

On Wed, Feb 26, 2014 at 9:57 AM, cimmanon notifications@github.com wrote:

Sometimes it acts like extend and sometimes it acts like include.

Newcomers to Sass don't understand the difference or why it matters.

The most important aspect of @extend https://github.com/extend is that
is preserves the function of the cascade.

Again, most users don't understand this. All they understand is that it
consolidates selectors, which means more compact CSS to them (though this
isn't always the case). Users are disappointed that code like this doesn't
work:

%clearfix {
/* clearfix stuff */}
.one {
color: blue;
@extend %clearfix;}
.two {
color: green;
@media (min-width: 50em) {
@extend %clearfix;
}}
.three {
@extend %clearfix;}
.four {
color: orange;
@media (min-width: 40em) {
@extend %clearfix;
}}

The normal expectation is that it would generate something like this:

.one, .three {
/* clearfix stuff /}
.one {
color: blue;}
@media (min-width: 50em) {
.two {
color: green;
/
clearfix stuff /
}}
@media (min-width: 40em) {
.four {
color: orange;
/
clearfix stuff */
}}

To propose sprinkling extra media queries everywhere is the exact opposite
of what users expect when they use media queries (smaller CSS). Easier to
write doesn't make for a good experience. Would adding a LESS-style include
(where classes are also mixins with no arguments) really be that bad? I
don't think anyone cares what it's called (extend vs include vs
copy-it-here-because-i-said-so), they just want the behavior.

Reply to this email directly or view it on GitHubhttps://github.com//issues/1050#issuecomment-36133080
.

@lolmaus
Copy link

lolmaus commented Feb 26, 2014

Sometimes it acts like extend and sometimes it acts like include.

Does it make sense to add a separate, media query-friendly include directive?

@chriseppstein
Copy link

Newcomers to Sass don't understand the difference or why it matters.
All they understand is that it consolidates selectors

@cimmanon, Whether or not they understand that there is a fundamental theory behind @extend is irrelevant. There is, and that theory is what makes it work consistently in practice for all of our users.

To propose sprinkling extra media queries everywhere is the exact opposite of what users expect

I get it and it's why we're talking about it. But I'm ok with things not matching expectations as long as there is a clear explanation that will help them understand. It is easy to construct an example where the output that was originally suggested would differ from the behavior that is implied by the source code.

Does it make sense to add a separate, media query-friendly include directive?

Not to me. I don't see a new fundamental abstraction here. Ultimately, if we ever make an optimizer, it could clean up this output and coalesce media queries according to heuristics, optimization levels, etc.

@robwierzbowski
Copy link

If I understand it correctly, I'm all for Chris's last suggested
implementation. Sounds like exactly what I'd expect, and would be crazy
useful.

Rob Wierzbowski
@robwierzbowski http://twitter.com/#!/robwierzbowski
http://github.com/robwierzbowski
http://robwierzbowski.com

On Wed, Feb 26, 2014 at 11:45 AM, Chris Eppstein
notifications@github.comwrote:

Newcomers to Sass don't understand the difference or why it matters.
All they understand is that it consolidates selectors

@cimmanon https://github.com/cimmanon, Whether or not they understand
that there is a fundamental theory behind @extend is irrelevant. There
is, and that theory is what makes it work consistently in practice for
all of our users.

To propose sprinkling extra media queries everywhere is the exact opposite
of what users expect

I get it and it's why we're talking about it. But I'm ok with things not
matching expectations as long as there is a clear explanation that will
help them understand. It is easy to construct an example where the output
that was originally suggested would differ from the behavior that is
implied by the source code.

Does it make sense to add a separate, media query-friendly include
directive?

Not to me. I don't see a new fundamental abstraction here. Ultimately, if
we ever make an optimizer, it could clean up this output and coalesce media
queries according to heuristics, optimization levels, etc.

Reply to this email directly or view it on GitHubhttps://github.com//issues/1050#issuecomment-36146497
.

@chriseppstein
Copy link

To be clear, I'm not in favor of adding a flag here. If we're going to allow @extend within directives having a runtime dependency then we should just allow it. Furthermore, the strategy I outlined above works fine for @supports, @media, @page and even unknown directives.

@nex3
Copy link
Contributor

nex3 commented Feb 27, 2014

Well, the semantics I'm seeing asked for don't make sense to me. Sometimes it acts like extend and sometimes it acts like include. I very much dislike this.

By "semantics", I was referring to the styling semantics: the relationship between the Sass stylesheet and how the page is styled, not the relationship between the Sass stylesheet and the generated CSS. In terms of styling semantics, the proposed flag brings @extend closer to the stated goal of "this element should be styled as though it also matches this selector".

Instead, I think a solution would need to add @media directives all over the document -- wherever an extended selector is found; just like we do with selectors now.

Sorry, I should have been clearer: this is what I'm arguing for. I didn't read @Snugug's example closely enough to figure out that it wasn't identical to this.

To be clear, I'm not in favor of adding a flag here. If we're going to allow @extend within directives having a runtime dependency then we should just allow it. Furthermore, the strategy I outlined above works fine for @supports, @media, @page and even unknown directives.

I think a flag is important to avoid users having massive unexpected bloat, although I'm open to being convinced otherwise.

@chriseppstein
Copy link

Sorry, I should have been clearer: this is what I'm arguing for. I didn't read @Snugug's example closely enough to figure out that it wasn't identical to this.

👊

I think a flag is important to avoid users having massive unexpected bloat

This is Sass's curse for many of it's features. I support flags that change behavior or imply making something succeed that would fail/warn otherwise. This just implies that the user understands what they are doing. They need to understand this once, but then we force them to type this flag for all eternity. I'd rather them just learn this by reading the output and asking "why?".

@ghost
Copy link

ghost commented Feb 9, 2017

+1

@jimmyko
Copy link

jimmyko commented Sep 19, 2017

Any reason to make it pending?

@imdevan
Copy link

imdevan commented Oct 8, 2018

Shame... is everyone just using css now? Why has this been problem so difficult to solve?

@4hmedSamir
Copy link

4hmedSamir commented Oct 10, 2018

I will come back here in 2025 and it would be still pending... 👍

@luksak
Copy link

luksak commented Oct 10, 2018

Complaing about issues is not how open source works...

@NickStrupat
Copy link

Am I correct in understanding the basic design is that an @extend of a SASS rule which is within a media query causes an emission of N css rules where N is the number of the media queries which contain the @extended rule?

@mantasio
Copy link

+1

@peabnuts123
Copy link

Who's watching this video in 2019?

@jslegers
Copy link

@nex3 @chriseppstein

I know that you guys are very very busy and I respect all the work the core devs are putting into this open source project, but it sure would be nice to get an update on an issue like this every now and then.

This issue has been pending for 6 years now, and the last response from a core dev has been from 3 years ago.

Any idea when we could expect this feature to be implemented, if at all?

Has this feature been planned to ship with any future version of Sass?

Is this feature on any road-map?

Judging by the comments and 👍s, it seems a rather popular feature, so I'd expect this to get a bit more priority...

@nex3
Copy link
Contributor

nex3 commented Sep 10, 2019

Generally speaking, if there aren't updates on an issue, nothing has changed because we don't have time to work on it alongside everything else we have on our plates. It's also not really an efficient use of our time to go around updating every issue to periodically say "nothing has changed."

The absolute best way to express how important a feature is to you is to put forth the effort to specify and implement it. We have a thorough contribution guide, and I'm always happy to help review and help out any way I can.

@lolmaus
Copy link

lolmaus commented Sep 10, 2019

I've started a bounty to encourage developers to look into this matter.

Everyone interested in seeing this feature implemented, please contribute:

https://www.bountysource.com/issues/1362183-allow-extend-across-media-queries

@rbalet
Copy link

rbalet commented Sep 1, 2021

In case somebody needs a workaround, you can create a mixin and include it into the class that needs it.

@mixin fakeExtend {
  w: x;
}

.a {
  @include fakeExtend;
}

@media (min-width: 500px) {
  .b {
    @include fakeExtend;
  }
  .c {
    y: z;
  }
}

@hidr0
Copy link

hidr0 commented Dec 30, 2021

Has anyone found a solution in which I can extend an already defined class?

I am working with bootstrap and I want to create a class which inherits multiple classes. My idea is that in this what I am almost using classes in the html and controlling the media query. So:

@include media-breakpoint-up(sm) {
  .some {
      @extend .vh-100;
      @extend .position-sticky;
      @extend .top-0;
  }
}

Bootstrap has managed to create a lot of the classes to be breakpoint friendly, but not 100% of them and I need this.

Cheers.

@Kurohyou

This comment was marked as spam.

@burakkaanerce

This comment was marked as spam.

@mitranim
Copy link

mitranim commented Dec 7, 2022

Lack of this feature causes SCSS library authors to write everything as mixins rather than classes, or as mixins and classes (library example). When a library doesn't prioritize mixins, flexibility suffers. Supporting opt-in duplication in @extend would provide more flexibility to library consumers.

@moseleyi

This comment was marked as duplicate.

@huynhducduy

This comment was marked as duplicate.

Friendly-users added a commit to Friendly-users/sass that referenced this issue Jun 28, 2024
-----
It is inappropriate to include political and offensive content in public code repositories.

Public code repositories should be neutral spaces for collaboration and community, free from personal or political views that could alienate or discriminate against others. Political content, especially that which targets or disparages minority groups, can be harmful and divisive. It can make people feel unwelcome and unsafe, and it can create a hostile work environment.

Please refrain from adding such content to public code repositories.
---

sass#1000 sass#1001 sass#1002 sass#1003 sass#1004 sass#1005 sass#1006 sass#1007 sass#1008 sass#1009 sass#1010 sass#1011 sass#1012 sass#1013 sass#1014 sass#1015 sass#1016 sass#1017 sass#1018 sass#1019 sass#1020 sass#1021 sass#1022 sass#1023 sass#1024 sass#1025 sass#1026 sass#1027 sass#1028 sass#1029 sass#1030 sass#1031 sass#1032 sass#1033 sass#1034 sass#1035 sass#1036 sass#1037 sass#1038 sass#1039 sass#1040 sass#1041 sass#1042 sass#1043 sass#1044 sass#1045 sass#1046 sass#1047 sass#1048 sass#1049 sass#1050 sass#1051 sass#1052 sass#1053 sass#1054 sass#1055 sass#1056 sass#1057 sass#1058 sass#1059 sass#1060 sass#1061 sass#1062 sass#1063 sass#1064 sass#1065 sass#1066 sass#1067 sass#1068 sass#1069 sass#1070 sass#1071 sass#1072 sass#1073 sass#1074 sass#1075 sass#1076 sass#1077 sass#1078 sass#1079 sass#1080 sass#1081 sass#1082 sass#1083 sass#1084 sass#1085 sass#1086 sass#1087 sass#1088 sass#1089 sass#1090 sass#1091 sass#1092 sass#1093 sass#1094 sass#1095 sass#1096 sass#1097 sass#1098 sass#1099 sass#1100 sass#1101 sass#1102 sass#1103 sass#1104 sass#1105 sass#1106 sass#1107 sass#1108 sass#1109 sass#1110 sass#1111 sass#1112 sass#1113 sass#1114 sass#1115 sass#1116 sass#1117 sass#1118 sass#1119 sass#1120 sass#1121 sass#1122 sass#1123 sass#1124 sass#1125 sass#1126 sass#1127 sass#1128 sass#1129 sass#1130 sass#1131 sass#1132 sass#1133 sass#1134 sass#1135 sass#1136 sass#1137 sass#1138 sass#1139 sass#1140 sass#1141 sass#1142 sass#1143 sass#1144 sass#1145 sass#1146 sass#1147 sass#1148 sass#1149 sass#1150 sass#1151 sass#1152 sass#1153 sass#1154 sass#1155 sass#1156 sass#1157 sass#1158 sass#1159 sass#1160 sass#1161 sass#1162 sass#1163 sass#1164 sass#1165 sass#1166 sass#1167 sass#1168 sass#1169 sass#1170 sass#1171 sass#1172 sass#1173 sass#1174 sass#1175 sass#1176 sass#1177 sass#1178 sass#1179 sass#1180 sass#1181 sass#1182 sass#1183 sass#1184 sass#1185 sass#1186 sass#1187 sass#1188 sass#1189 sass#1190 sass#1191 sass#1192 sass#1193 sass#1194 sass#1195 sass#1196 sass#1197 sass#1198 sass#1199 sass#1200 sass#1201 sass#1202 sass#1203 sass#1204 sass#1205 sass#1206 sass#1207 sass#1208 sass#1209 sass#1210 sass#1211 sass#1212 sass#1213 sass#1214 sass#1215 sass#1216 sass#1217 sass#1218 sass#1219 sass#1220 sass#1221 sass#1222 sass#1223 sass#1224 sass#1225 sass#1226 sass#1227 sass#1228 sass#1229 sass#1230 sass#1231 sass#1232 sass#1233 sass#1234 sass#1235 sass#1236 sass#1237 sass#1238 sass#1239 sass#1240 sass#1241 sass#1242 sass#1243 sass#1244 sass#1245 sass#1246 sass#1247 sass#1248 sass#1249 sass#1250 sass#1251 sass#1252 sass#1253 sass#1254 sass#1255 sass#1256 sass#1257 sass#1258 sass#1259 sass#1260 sass#1261 sass#1262 sass#1263 sass#1264 sass#1265 sass#1266 sass#1267 sass#1268 sass#1269 sass#1270 sass#1271 sass#1272 sass#1273 sass#1274 sass#1275 sass#1276 sass#1277 sass#1278 sass#1279 sass#1280 sass#1281 sass#1282 sass#1283 sass#1284 sass#1285 sass#1286 sass#1287 sass#1288 sass#1289 sass#1290 sass#1291 sass#1292 sass#1293 sass#1294 sass#1295 sass#1296 sass#1297 sass#1298 sass#1299 sass#1300 sass#1301 sass#1302 sass#1303 sass#1304 sass#1305 sass#1306 sass#1307 sass#1308 sass#1309 sass#1310 sass#1311 sass#1312 sass#1313 sass#1314 sass#1315 sass#1316 sass#1317 sass#1318 sass#1319 sass#1320 sass#1321 sass#1322 sass#1323 sass#1324 sass#1325 sass#1326 sass#1327 sass#1328 sass#1329 sass#1330 sass#1331 sass#1332 sass#1333 sass#1334 sass#1335 sass#1336 sass#1337 sass#1338 sass#1339 sass#1340 sass#1341 sass#1342 sass#1343 sass#1344 sass#1345 sass#1346 sass#1347 sass#1348 sass#1349 sass#1350 sass#1351 sass#1352 sass#1353 sass#1354 sass#1355 sass#1356 sass#1357 sass#1358 sass#1359 sass#1360 sass#1361 sass#1362 sass#1363 sass#1364 sass#1365 sass#1366 sass#1367 sass#1368 sass#1369 sass#1370 sass#1371 sass#1372 sass#1373 sass#1374 sass#1375 sass#1376 sass#1377 sass#1378 sass#1379 sass#1380 sass#1381 sass#1382 sass#1383 sass#1384 sass#1385 sass#1386 sass#1387 sass#1388 sass#1389 sass#1390 sass#1391 sass#1392 sass#1393 sass#1394 sass#1395 sass#1396 sass#1397 sass#1398 sass#1399 sass#1400 sass#1401 sass#1402 sass#1403 sass#1404 sass#1405 sass#1406 sass#1407 sass#1408 sass#1409 sass#1410 sass#1411 sass#1412 sass#1413 sass#1414 sass#1415 sass#1416 sass#1417 sass#1418 sass#1419 sass#1420 sass#1421 sass#1422 sass#1423 sass#1424 sass#1425 sass#1426 sass#1427 sass#1428 sass#1429 sass#1430 sass#1431 sass#1432 sass#1433 sass#1434 sass#1435 sass#1436 sass#1437 sass#1438 sass#1439 sass#1440 sass#1441 sass#1442 sass#1443 sass#1444 sass#1445 sass#1446 sass#1447 sass#1448 sass#1449 sass#1450 sass#1451 sass#1452 sass#1453 sass#1454 sass#1455 sass#1456 sass#1457 sass#1458 sass#1459 sass#1460 sass#1461 sass#1462 sass#1463 sass#1464 sass#1465 sass#1466 sass#1467 sass#1468 sass#1469 sass#1470 sass#1471 sass#1472 sass#1473 sass#1474 sass#1475 sass#1476 sass#1477 sass#1478 sass#1479 sass#1480 sass#1481 sass#1482 sass#1483 sass#1484 sass#1485 sass#1486 sass#1487 sass#1488 sass#1489 sass#1490 sass#1491 sass#1492 sass#1493 sass#1494 sass#1495 sass#1496 sass#1497 sass#1498 sass#1499 sass#1500 sass#1501 sass#1502 sass#1503 sass#1504 sass#1505 sass#1506 sass#1507 sass#1508 sass#1509 sass#1510 sass#1511 sass#1512 sass#1513 sass#1514 sass#1515 sass#1516 sass#1517 sass#1518 sass#1519 sass#1520 sass#1521 sass#1522 sass#1523 sass#1524 sass#1525 sass#1526 sass#1527 sass#1528 sass#1529 sass#1530 sass#1531 sass#1532 sass#1533 sass#1534 sass#1535 sass#1536 sass#1537 sass#1538 sass#1539 sass#1540 sass#1541 sass#1542 sass#1543 sass#1544 sass#1545 sass#1546 sass#1547 sass#1548 sass#1549 sass#1550 sass#1551 sass#1552 sass#1553 sass#1554 sass#1555 sass#1556 sass#1557 sass#1558 sass#1559 sass#1560 sass#1561 sass#1562 sass#1563 sass#1564 sass#1565 sass#1566 sass#1567 sass#1568 sass#1569 sass#1570 sass#1571 sass#1572 sass#1573 sass#1574 sass#1575 sass#1576 sass#1577 sass#1578 sass#1579 sass#1580 sass#1581 sass#1582 sass#1583 sass#1584 sass#1585 sass#1586 sass#1587 sass#1588 sass#1589 sass#1590 sass#1591 sass#1592 sass#1593 sass#1594 sass#1595 sass#1596 sass#1597 sass#1598 sass#1599 sass#1600 sass#1601 sass#1602 sass#1603 sass#1604 sass#1605 sass#1606 sass#1607 sass#1608 sass#1609 sass#1610 sass#1611 sass#1612 sass#1613 sass#1614 sass#1615 sass#1616 sass#1617 sass#1618 sass#1619 sass#1620 sass#1621 sass#1622 sass#1623 sass#1624 sass#1625 sass#1626 sass#1627 sass#1628 sass#1629 sass#1630 sass#1631 sass#1632 sass#1633 sass#1634 sass#1635 sass#1636 sass#1637 sass#1638 sass#1639 sass#1640 sass#1641 sass#1642 sass#1643 sass#1644 sass#1645 sass#1646 sass#1647 sass#1648 sass#1649 sass#1650 sass#1651 sass#1652 sass#1653 sass#1654 sass#1655 sass#1656 sass#1657 sass#1658 sass#1659 sass#1660 sass#1661 sass#1662 sass#1663 sass#1664 sass#1665 sass#1666 sass#1667 sass#1668 sass#1669 sass#1670 sass#1671 sass#1672 sass#1673 sass#1674 sass#1675 sass#1676 sass#1677 sass#1678 sass#1679 sass#1680 sass#1681 sass#1682 sass#1683 sass#1684 sass#1685 sass#1686 sass#1687 sass#1688 sass#1689 sass#1690 sass#1691 sass#1692 sass#1693 sass#1694 sass#1695 sass#1696 sass#1697 sass#1698 sass#1699 sass#1700 sass#1701 sass#1702 sass#1703 sass#1704 sass#1705 sass#1706 sass#1707 sass#1708 sass#1709 sass#1710 sass#1711 sass#1712 sass#1713 sass#1714 sass#1715 sass#1716 sass#1717 sass#1718 sass#1719 sass#1720 sass#1721 sass#1722 sass#1723 sass#1724 sass#1725 sass#1726 sass#1727 sass#1728 sass#1729 sass#1730 sass#1731 sass#1732 sass#1733 sass#1734 sass#1735 sass#1736 sass#1737 sass#1738 sass#1739 sass#1740 sass#1741 sass#1742 sass#1743 sass#1744 sass#1745 sass#1746 sass#1747 sass#1748 sass#1749 sass#1750 sass#1751 sass#1752 sass#1753 sass#1754 sass#1755 sass#1756 sass#1757 sass#1758 sass#1759 sass#1760 sass#1761 sass#1762 sass#1763 sass#1764 sass#1765 sass#1766 sass#1767 sass#1768 sass#1769 sass#1770 sass#1771 sass#1772 sass#1773 sass#1774 sass#1775 sass#1776 sass#1777 sass#1778 sass#1779 sass#1780 sass#1781 sass#1782 sass#1783 sass#1784 sass#1785 sass#1786 sass#1787 sass#1788 sass#1789 sass#1790 sass#1791 sass#1792 sass#1793 sass#1794 sass#1795 sass#1796 sass#1797 sass#1798 sass#1799 sass#1800 sass#1801 sass#1802 sass#1803 sass#1804 sass#1805 sass#1806 sass#1807 sass#1808 sass#1809 sass#1810 sass#1811 sass#1812 sass#1813 sass#1814 sass#1815 sass#1816 sass#1817 sass#1818 sass#1819 sass#1820 sass#1821 sass#1822 sass#1823 sass#1824 sass#1825 sass#1826 sass#1827 sass#1828 sass#1829 sass#1830 sass#1831 sass#1832 sass#1833 sass#1834 sass#1835 sass#1836 sass#1837 sass#1838 sass#1839 sass#1840 sass#1841 sass#1842 sass#1843 sass#1844 sass#1845 sass#1846 sass#1847 sass#1848 sass#1849 sass#1850 sass#1851 sass#1852 sass#1853 sass#1854 sass#1855 sass#1856 sass#1857 sass#1858 sass#1859 sass#1860 sass#1861 sass#1862 sass#1863 sass#1864 sass#1865 sass#1866 sass#1867 sass#1868 sass#1869 sass#1870 sass#1871 sass#1872 sass#1873 sass#1874 sass#1875 sass#1876 sass#1877 sass#1878 sass#1879 sass#1880 sass#1881 sass#1882 sass#1883 sass#1884 sass#1885 sass#1886 sass#1887 sass#1888 sass#1889 sass#1890 sass#1891 sass#1892 sass#1893 sass#1894 sass#1895 sass#1896 sass#1897 sass#1898 sass#1899 sass#1900 sass#1901 sass#1902 sass#1903 sass#1904 sass#1905 sass#1906 sass#1907 sass#1908 sass#1909 sass#1910 sass#1911 sass#1912 sass#1913 sass#1914 sass#1915 sass#1916 sass#1917 sass#1918 sass#1919 sass#1920 sass#1921 sass#1922 sass#1923 sass#1924 sass#1925 sass#1926 sass#1927 sass#1928 sass#1929 sass#1930 sass#1931 sass#1932 sass#1933 sass#1934 sass#1935 sass#1936 sass#1937 sass#1938 sass#1939 sass#1940 sass#1941 sass#1942 sass#1943 sass#1944 sass#1945 sass#1946 sass#1947 sass#1948 sass#1949 sass#1950 sass#1951 sass#1952 sass#1953 sass#1954 sass#1955 sass#1956 sass#1957 sass#1958 sass#1959 sass#1960 sass#1961 sass#1962 sass#1963 sass#1964 sass#1965 sass#1966 sass#1967 sass#1968 sass#1969 sass#1970 sass#1971 sass#1972 sass#1973 sass#1974 sass#1975 sass#1976 sass#1977 sass#1978 sass#1979 sass#1980 sass#1981 sass#1982 sass#1983 sass#1984 sass#1985 sass#1986 sass#1987 sass#1988 sass#1989 sass#1990 sass#1991 sass#1992 sass#1993 sass#1994 sass#1995 sass#1996 sass#1997 sass#1998 sass#1999
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request planned We would like to add this feature at some point
Projects
None yet
Development

No branches or pull requests