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

Using @import (reference) with mixins with & selectors output incorrect css #2047

Closed
eamodio opened this issue Jun 5, 2014 · 8 comments
Closed

Comments

@eamodio
Copy link

eamodio commented Jun 5, 2014

First off this might be a dup of #1968 or #1646 and if so I apologize, but I think this is slightly different than the other 2 and possibly much worse.

Say I have 2 files:

ref.less

.mixin(@selector) {
  &@{selector}, .bar @{selector} {
    color: #fff;
    &:hover {
      color: #000;
    }
  }
}

root.less

//@import "ref.less";
@import (reference) "ref.less";

.mixin(~'.foo');

.parent {
  .mixin(~'.child');
}

The output of compiling root.less is:

root.css - with (reference)

.foo,
.bar .foo {
  color: #fff;
}
.parent.child,
.parent .bar .child {
  color: #fff;
}
.parent .bar .child:hover {
  color: #000;
}

Which is not what I would expect at all, and if I remove the (reference) from the @import this is what I get (and expect):

root.css - without (reference)

.foo,
.bar .foo {
  color: #fff;
}
.foo:hover,
.bar .foo:hover {
  color: #000;
}
.parent.child,
.parent .bar .child {
  color: #fff;
}
.parent.child:hover,
.parent .bar .child:hover {
  color: #000;
}

Thank you in advance for any help you can provide!

@seven-phases-max
Copy link
Member

It's actually a duplicate of #1979. (So I'll close this).

Either way, is there any special reason for you to use reference while importing this particular less file? Recently I noticed (by number of related questions at the SO) a strange tendency of "using reference everywhere" while normally we never need it in a Less project/library unless we're doing some hacking.

@eamodio
Copy link
Author

eamodio commented Jul 11, 2014

@seven-phases-max Sorry for the long delay on this response. What I provided here was obviously an extremely simple example to show the problem. My use-case is to be able to include a less file's mixins for use without pulling in the actual less file. We have many components which re-use many less files and would like to make sure that any non-mixin content doesn't get included. In my mind, this is exactly what the use of reference is for (otherwise I'm not sure what it's for). So given that use-case this type of issue completely kills the use of the feature in many cases.

@jonschlinkert
Copy link
Contributor

while normally we never need it in a Less project/library unless we're doing some hacking.

just noticed this. I think this assessment is completely wrong. Reference is the best feature less has for creating specialized, project-specific components from a library of generic reusable components. Of course we will see it everywhere. I don't think there is anything hacky at all about using the feature.

@seven-phases-max
Copy link
Member

Reference is the best feature less has for creating specialized, project-specific components from a library of generic reusable components.

Well, it depends :) For me what is "absolutely wrong" is mixin up CSS classes (front-end entities) and "generic reusable components" (which ideally should always be a set of parametric mixins in a Less library). I can see why it went this wrong way historically (there were no parametric stuff initially and even now we still can't use extend with (parametric) mixins) but... I wrote about this there.

So yes, technically, when reference will work as supposed w/o issues and side-effects I guess there will be nothing wrong with "using reference everywhere" and we'll see a lot of such libraries. But for me this always remains a poor library design if there's no strict boundary between "final" CSS styles ("Hello, I'm a CSS selector, I'm designed to be used with your HTML and meant to be used only there") and reusable components ("Hello, I'm a generic building-block, I'm here to help you to craft your own CSS classes and I'm optimized to do this and only this"). Obviously this "boundary" does not have to be only in parens (i.e. parametric vs. non-parametric mixins) but it should be clearly designated by "something" at the point of an entity definition (i.e. in the file itself by the file author and not out of it by the file user like we have it with reference). Currently this is not always possible, e.g. if we want our component to be used with extend and not appear in the resulting CSS we have to wrap it with reference, but I do not hesitate to name it "just a hack" until we have #1177 (and other related features).

@matthew-dean
Copy link
Member

@seven-phases-max I see where you're coming from, but I don't know that I'd call it a hack. I think it's a good general-purpose "wrapper" for a variety of libraries or imported css where you can be choosy about inclusion. But I agree that it's sort of a wrapper for non-optimized libraries, and probably, in some cases, takes the place of more modular construction, or of missing pieces like extending mixins. There's still a lot of needed work on extend. (See: #2101, and of course the one you mentioned.)

@jonschlinkert
Copy link
Contributor

...remains a poor library design if there's no strict boundary between "final" CSS styles ("Hello, I'm a CSS selector, I'm designed to be used with your HTML and meant to be used only there") and reusable components...

But how many libraries have any of us published in our careers? Usually we need to get a client project shipped. Which means you'll use the best tools to get the job done, including an actual library that has already implemented great code decisions - or at least has code that you'd like to use but not re-write - like Bootstrap, Foundation, etc. Whatever your poison, the fact remains - 99.5% less.js users use less.js in order to leverage frameworks created by better coders than ourselves.

But I agree that it's sort of a wrapper for non-optimized libraries, and probably, in some cases, takes the place of more modular construction,

Virtually every code decision comes with a price and results in a tradeoff from any number of other potential solutions. JavaScript itself is a hack. But if you know how to use it well enough to get the job done, then does it really matter? We should never sacrifice developer convenience for perfection or over-optimization, and more importantly, we should never sacrifice or subvert long-term ideals because of short-term faults. e.g. if reference is not good for the future of less.js, then it should be removed at the soonest pragmatic opportunity. But if it is good for the future of less.js, then while we're on the core team we should be lauding it, cheerleading its usage, and asking users to please give us feedback on how to make it more valuable to them.

I believe that reference can do for CSS what node.js did for javascript. I recently told a friend that reference (IMHO) gets us (less.js) close to the holy grail of CSS. I'm getting the sense that the point of the reference feature is being totally lost here. If reference gets polished up, I don't think it would be possible for a library to be as optimized and modular as it could be with reference (and I mean this sincerely, not hyperbole at all). There is no reason to focus on the downsides of reference when it has so much promise for modularizing libraries.

At the end of the day, we can either hold onto outmoded ways of thinking about CSS, underestimate our users and think that they are not capable of making good decisions about their own usage and use cases, or we can embrace the fact that the very reason less.js has any users at all is that they want more advanced solutions than what CSS provides, and they should be driving the functionality and features that less.js needs to stay relevant.

IMHO, until a more important goal surfaces, if the less.js team had one singular driving mission, it should be "write once, use anywhere", e.g. "help developers write reusable, modular LESS components".

just my 2c

@matthew-dean
Copy link
Member

I don't think anyone is advocating against reference, Jon. It's a great feature. When it comes to library building, it doesn't do everything library builders need, though, and that's why we have other issues open with other important features as well. I'm with you that it's not a hack, nor was it designed as such. It's an important feature on the road to many more great ideas.

I will say that when it was proposed, the use cases were for libraries which were not "designed" for reference. I think what's needed are community blog posts / examples that present how to design with reference, not just use it to consume third-party modules. Less provides a lot of object-oriented and modular patterns for styling that doesn't exist in CSS, which I don't think has really occurred to the general community. It's not just for "grouping" your styles. There are a lot of nifty OO patterns you can do now.

@seven-phases-max
Copy link
Member

Yes, of course, I wasn't against reference at all. I was just wondering about using it in the original snippet (as I've already seen a lot of misinterpretations of its current state like this or this).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants