-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Mixins should accept LESS blocks #965
Comments
Oh, I need this too! |
+1 |
Absolutely. Please! |
I can see some collisions by adding this functionality to the normal mixin syntax. Just by looking, it would impossible to tell if the call above would compile to .big-desktop-button .mobile {
display: none;
} or @media all and (max-device-width: 480px) {
.big-desktop-button {
display: none;
}
} So I think it would need new syntax. Here is my idea. Allow blocks of LESS to be passed into parametric mixins, as a normal positional parameter surrounded by braces. .mobile(@content) {
@media all and (max-device-width: 480px) {
@content
}
}
.big-desktop-button {
...
.mobile({
display:none;
});
} Due to variable scoping and evaluation, I imagine this would require that mixins that accept LESS content blocks can only accept content blocks. |
+1 This is a must. |
+1 SASS can do this. |
+1 |
I don't understand these examples. What is @content defined as in the first example? |
With SASS, you can pass a whole content block to a mixin independent of the parameters. So you have something like this: .mobile() {
@media your-query-here {
@content
}
}
.someclass {
// some general styles here
.mobile() {
// your mobile styles here
}
} that would compile to: .someclass {
// some general styles here
}
@media your-query-here {
.someclass {
// your mobile styles here
}
} I'm adding my support for this. Real logic operators (if/else) and this feature are the biggest things keeping me from using LESS at this point. |
+1!!! |
I'm still confused by this. Some real world examples of this being used would really help a lot. I tried to read through the SASS docs, but I still struggled with it. It sounds like |
@jonschlinkert You're right. It's extremely useful when you need a "wrapper" selector. For example, I have a project where we have to share the page with styles from a third-party, so we "pseudo-namespace" our styles in order to make them more specific than the third party styles. We do this by wrapping all of our styles with an arbitrary selector, and we can nest styles within that selector and leverage the fact that a complex selector such as Another use for having an arbitrary selector to wrap styles is if you want to reuse Sass or Less "modules" between different projects or documents and for some reason you need to give them different wrapper hooks in your markup (or want the flexibility to do so). My use cases are attempting to bridge the fact that the CSS cascade lacks a concept of a true namespace, but you can leverage a stylesheet preprocessor to get something practically close to one. "Media query bubbling" is a similar use case (since it allows "blocks" of styles to be passed around and wrapped with different selectors), although I don't know how Less supports this internally, but a cursory Google search suggests that Less does support this feature. |
@davidrivers thanks, the wrapper analogy helps, that's sort of how I saw it in my mind. Looking at this semantically, this is a better use case for the term David if you find some time, would you mind adding some detailed code examples here so when @MatthewDL and @lukeapage review again they can make a better evaluation of this? thanks! |
Yes, LESS supports media query bubbling. There's probably ways to do namespacing as you describe, but like @jonschlinkert, the examples are still a head-scratcher. That is, I can't see how it's not currently supported. You can segment code into, say, mobile-specific definitions using variables / mixin guards. |
+1!! |
I wonder if extend and extend mixins (equivalent to sass placeholders) actually provide this functionality.. anyway, here is the example from the sass docs, converted into pseudo less.
output
usecase - stop repetition of selectors/media queries throughout the code and abstract them out to one place. here is how I might do it with extend
disadvantages
here is how I might do it with mixins
note this does work with multiple apply-to-ie6-only classes and because of media bubbling it does work applying media queries to multiple classes. disadvantages
I can't think of a nice way of implementing a Another proposed feature that might be useful for your specific case is "silent" imports. You could wrap everything in a class, import your library silently, then extend a particular namespace.. then the new namespaces selectors would be brought in and the old selectors kept quiet... |
I'm not sure I completely understand your examples, but they seem to all be backwards in a way - sorry if I'm getting them wrong. What I (and I the thread opener who is a collegue of mine) want to achieve is that I can group the media query specific styles with the other styles to a particular page element. The idea here is that this solves the problem that using media queries always means you have to look in many files / places in the same file to find all the styles that pertain to one specific element. The solution to this now should allow that you can write styles more along the lines of this:
That way the wrapping structure of less can be used to really group all styles for an element together and see the different responsive elements in one piece. No matter the solution - this is what it should allow to achieve to solve this bug. |
@dwt I think that media bubbling is the feature you are looking for. Documentation:
To make it work in your example, you have to replace:
Modified version of your example:
Less.js-1.3.3 compiled it into this:
Basically, |
Maybe I'm misunderstanding you, but the whole point of this bug report is being able to abstract about the media rules and I think that the media query bubling is only providing the foundation of this feature. I.e. we want to define the actual breakpoints of the media queries at exactly one point, and then Does that make sense? |
@dwr I misunderstood you and what you want make sense now, sorry. You could currently use only media query interpolation, but that is somewhat limited compared to this feature.
|
Indeed I just found out that since 1.3 this is possible and a good start towards this goal. That being said, a way to abstract about blocks of less would still be very much apreciated. |
Here is an example that I think may help get the idea across. When compiling a stylesheet for legacy browsers, you could simply switch
|
And here is the output from my last example: /* @isResponsive: true; */
@media screen and (min-width: 30em) {
.some-element {
color: blue;
background: red;
}
}
@media screen and (min-width: 48em) and (max-width: 60em) {
.some-element {
border: 1px solid red;
}
} /* @isResponsive: false; */
.some-element {
color: blue;
background: red;
} |
It would be great if LESS was capable of achieving this http://jakearchibald.github.io/sass-ie/ As far as I can see the only thing holding it back is the lack of support/alternative for @content. |
@leads yes! +1! 👍 I was just in the process of converting sass-ie to LESS when I hit a brick wall with
I think the sass-ie code is a prime example of |
I think I found a workaround for this. Since mixins see and can access their callers scope, you can place media and selectors into mixin and inject content by another mixin defined inside the caller: /*
Usage: the caller must have .content declared in its scope!
*/
.mobile() {
@media all and (max-device-width: 480px) {
.content();
}
}
/* use the .mobile inside desktop button */
.big-desktop-button {
.content() { //this will be injected into .mobile mixin
display:none;
}
// the .mobile sees this scope and will use .content mixin
.mobile();
}
/* use the .mobile inside mobile button */
.big-mobile-button {
.content() { //this will be injected into .mobile mixin
display:inline;
}
// the .mobile sees this scope and will use .content mixin
.mobile();
} compiles into: @media all and (max-device-width: 480px) {
.big-desktop-button {
display: none;
}
}
@media all and (max-device-width: 480px) {
.big-mobile-button {
display: inline;
}
} |
I would like to add another usecase to let us abstract about Since IE 7 does not support @media queries, one possible workaround is to ensure that all styles that are in the desktop media query are also in an ie specific file and get included there. Since manual labour sucks and css is much better we have some css classes on body that let us target ie specificly from css where required with classes like .lt-ie8 or .lt-ie7. Now, if we could abstract about media queries, we could build a mixin which would put all the desktop rules into the desktop media query and into the scope of the .lt-ie8 class. In pseudo-code I would assume this could look a bit like this .desktop() {
@media (something) {
@content()
}
.lt-ie-9 {
@content
}
} Pretty please, can we have something like this? I'd love to get rid of the special IE.css file we maintain by hand where we copy over styles once in a while and then forget to update them. |
+1 - Bounty here: https://www.catincan.com/bounty/mixins-should-accept-less-blocks-issue-965-less-less-js-github Crowdfund issue & get merged into main branch to collect. |
Here is a SASS mixin library I wrote using display: table that I think shows a good idea of how powerful this feature could be (semantics aside). I'm obviously making many assumptions/compromises but there is so much more you can do with this type of functionality. |
Just my +1 to support SomMeri's syntax proposal... .block {
size: 2;
}
#use-something {
.something(@variable);
@variable: .block;
/* ^ assign any arbitrary "name" to a variable (at this point nothing indicates
that the variable points to a mixin - it's only a "raw" value and we can use
it just as any other variable - for example putting it as a CSS property value)
*/
}
.something(@value) {
@value();
// ^ now the parens show that variable's value
// is a mixin name and we want to expand it here
} The idea behind this syntax is a possibility to provide arguments for the expansion at any level if the variable points to a parametric mixin, i.e.: .something(@value) {
@a: 1;
@b: 2;
@value(@a, @b);
} |
I've just noticed a "minor" problem with 18462037's So thinking of possible alternatives:
... we won't need any special syntax for a "named mixin assignment" as we'll be able to do it with:
And though |
Just sketching and thinking about how this could be accomplished with mixin extends.. what do you think about this?
essentially you make a template, put your mixin in the template and then extend the template... |
Per discussion on other issue threads, +1 to @seven-phases-max's proposal of assigning mixins to variables. |
I'll also +1 @seven-phases-max's proposal. The |
Implemented and will be in 1.7 release soon, see #1859. seperate issue for passing mixins. |
+1 |
By the by, I can confirm this is working in 1.7. |
is it working right now? |
@AndrewEastwood See the docs. |
Thanks |
It would be helpful if mixins had access to a content block passed to them, so one could encapsulate media queries or browser hacks in a central place and reference them symbolically.
This is basically the "Passing Content Blocks to a Mixin" feature of SASS:
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixin-content
In LESS this would mean something like:
The text was updated successfully, but these errors were encountered: