-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Comments
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 |
@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. |
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. |
@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 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. |
+1, I'm completely agree with the latest comment of @Snugug. |
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 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. |
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. |
The definition of The definition of 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 I don't see any point in continuing to beat this dead horse. |
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 |
@nex3 I'm not convinced. We've only just introduced 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. |
Can you summarize tersely how to take any cross-media
I would rather have users think of
I'd rather focus our education efforts here than on complex work-arounds for |
I want this too. Opting-in using
There is going to be education required no matter how we tackle this problem. |
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 agree that the abstraction is still leaky, but |
I really appreciate the points on both sides here, and I think they're I agree with Nathan that users (like myself) specifically want to extend On Monday, February 24, 2014, Nathan Weizenbaum [email protected]
Rob Wierzbowski |
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 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. >_< |
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. |
@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. |
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. |
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 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. |
Newcomers to Sass don't understand the difference or why it matters.
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. |
Sass isn't only for newcomers. Preserving source order at the expense of a Rob Wierzbowski On Wed, Feb 26, 2014 at 9:57 AM, cimmanon [email protected] wrote:
|
Does it make sense to add a separate, media query-friendly include directive? |
@cimmanon, Whether or not they understand that there is a fundamental theory behind
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.
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. |
If I understand it correctly, I'm all for Chris's last suggested Rob Wierzbowski On Wed, Feb 26, 2014 at 11:45 AM, Chris Eppstein
|
To be clear, I'm not in favor of adding a flag here. If we're going to allow |
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
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, although I'm open to being convinced otherwise. |
👊
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?". |
Another vote for this functionality. There are hack workarounds, but they are troublesome with CSS frameworks like Bootstrap. |
Are we any closer with this? I presume it's a case of not merging the media queries that contain I could really do with extending some utility classes (to maintain consistency above all) where it's otherwise awkward to use them in the markup and with the @<breakpoint> suffix. |
+1 |
Any reason to make it pending? |
Shame... is everyone just using css now? Why has this been problem so difficult to solve? |
I will come back here in 2025 and it would be still pending... 👍 |
Complaing about issues is not how open source works... |
Am I correct in understanding the basic design is that an |
+1 |
Who's watching this video in 2019? |
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... |
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. |
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 |
In case somebody needs a workaround, you can create a @mixin fakeExtend {
w: x;
}
.a {
@include fakeExtend;
}
@media (min-width: 500px) {
.b {
@include fakeExtend;
}
.c {
y: z;
}
} |
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:
Bootstrap has managed to create a lot of the classes to be breakpoint friendly, but not 100% of them and I need this. Cheers. |
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
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 |
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:would produce
and
would produce
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:
would compile to
Of course the optimization around this would be difficult, needing to ensure that the matching only happens for identical
@media
contexts (but include ones inor
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.The text was updated successfully, but these errors were encountered: