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

@include .css file contents #560

Closed
sergeylukin opened this issue Jan 10, 2012 · 14 comments
Closed

@include .css file contents #560

sergeylukin opened this issue Jan 10, 2012 · 14 comments

Comments

@sergeylukin
Copy link

I think @include method should be implemented. Sometimes there is a need to include .css file contents in compiled file while there is no possibility to change included file's extension, here is an example situation:
let's assume a CSS project that has a submodule which refers to some remote repository (let's take normalize.css as an example)
.less file needs to @include normalize.css, while it's not possible to rename normalize.css to normalize.less locally as the possibility to pull submodule's remote normalize.css in future will be lost.

Hope that makes sense..

@matthew-dean
Copy link
Member

I actually think the way LESS works is more intuitive, because, alternatively, if you WANTED to preserve your CSS import statements, how would you do it? Preserving CSS imports allows you to maintain backward compatibility on projects, or to import CSS files which may change, or may be generated dynamically.

In some cases, an imported CSS file may change on a daily basis (auto-generated as a result of a PHP script, for example), yet the LESS files may be compiled once. Allowing both import behaviors (merge and preserve) is an elegant solution.

@matthew-dean
Copy link
Member

I think I misinterpreted this question originally. It's actually not a bad idea.

@lukeapage
Copy link
Member

my only gripe with this feature is that we already have @import @import-once @import-multiple though you could argue that import-once is the default behaviour now so could be removed and we're not sure if anyone would ever use import-multiple.

If we don't think its confusing, then @include is a great idea.

@matthew-dean
Copy link
Member

Yeah, @import-once and @import-multiple don't make sense to me. How did those come about?

It's another keyword, yes, but it still seems like a simpler and more elegant option. You're explicitly triggering the parser rather than hackishly triggering it using text matches.

@jonschlinkert
Copy link
Contributor

@MatthewDL and/or @agatronic I have a potential solution for this I'd like to propose that might also resolve a number of other Issues. I think it's a pretty strong idea, but I'm not sure if it's inline with the direction you guys want to go with Less.

But before I just put it up here as a proposal I wanted to see if you (and by proxy @cloudhead) would prefer for me to socialize my suggestions with you first. (I submitted the accepted syntax for the ":extends" feature). Or if you want I can just put it up in a new issue with a link back to this one.

@lukeapage
Copy link
Member

@jonschlinkert I prefer it public so other people can particpate. You could just put a comment here? If we agree we can always copy it into a new issue and close the old ones.. or create a new issue, thats fine. Look forward to hear your suggestion.

@jonschlinkert
Copy link
Contributor

Awesome, will do. thanks

@jonschlinkert
Copy link
Contributor

I've also thought that it would be nice to have CSS files imported and concatenated the same was as LESS files, so I like this request but I'm not a fan of the specific method suggested by the OP. Even though their suggested use for @include seems consistent with what you would expect includes to do considering how includes work in other languages, I think this is a challenge that should be solved closer to the root of the problem, and in a way that isn't so hard-coded.

I started a new issue to make my proposal here: #1134 because it goes beyond the scope of this request.

However, if the solution I proposed in the other Issue isn't attractive, there are still other reasons I think we should try to find alternatives to using @include:

  1. This request really boils down to the requirement for a new processing/compiling option. Even if my solution doesn't work, it seems like a bad idea to address this with a new language feature. For example, a processing option would give the flexibility of compiling with or without concatenation - or even some other conditional behavior, whereas if we implement as suggested by the OP concatenation would be hard coded into the @include directive. So then we would have @import, @import-multiple, @import-once and @include.
  2. If we do decide to approach this as a compiling option, then we will probably find that a number of other Issues and feature requests can be addressed simultaneously.
  3. The include directive could be (or maybe should be) formally introduced into the LESS syntax, but with different objectives and very powerful language features that are useful for more than concatenating external CSS files during build.
  4. In a perfect world, the option to import something once, multiple times, or to concatenate or not should not be so hard-coded in the directives themselves. So it might not be good to go down a path that reinforces this compromise and makes it harder to "fix" later.
  5. Given that CSS and LESS already use the @import directive I think we should at least try to find a solution that leverages @import, and if we can't find something elegant then go back to @include.

Also, if the suggestions here don't cut it, then I suggest that we at least look at implementing something less hard-coded than @include. A better approach would be something that allows the same features for both less and css, like @import:blah-blah "styles.css", @import("some-variable") "styles.css", or even @import:blah-blah (variables) "styles.css", and so on.

In any case, I don't like the idea of @include because it takes us further down the road of hard-coding processing features into the language itself. So to that end, I also propose that we do some housekeeping and reduce the unnecessary overhead associated with @import, @import-once and @import-multiple, so that:

  • @import will always import once by default,
  • @import-multiple can be used to override if there is a use case (I'd give one if I could think of one)

Unless of course I'm completely missing something and there is a pragmatic reason why @import isn't already @import-once by default. And if there is a reason, it still might be better to clean them up and use an alternate method to achieve the same goal - but without complicating the directives...

@matthew-dean
Copy link
Member

I think the fact that @import isn't import once by default has been discussed as simply being an oversight. It seems intuitively like it should be the default behavior.

@include was a suggestion as simply an alias for @import, with the exception that @import tries to "smart guess" whether to compile the file or not. If it doesn't end in ".less", it spits it out in the resulting CSS. However, in some cases, the LESS file extension may not be .less for a variety of reasons. Rather than try to guess / circumvent all the reasons, it makes sense to be able to explicitly say: "Compile this file!" without a bunch of fluff or attaching URL fragments or a bunch of special text matching.

That's not to say that @include is the only option. We could also do things like explicitly declaring file mime type at the top of a file that the parser looks at, I dunno. There's a lot of ways to solve the problem, but I consider @include more elegant that doing things like @import url('actuallyalessfile.css?less=yes');

@jonschlinkert
Copy link
Contributor

I see your point, that makes sense. I guess my point is that a more powerful approach would allow you to set contexts on the @import statement so that you can choose at compile time what you want to do with the css files, or less files for that matter. @include is a hard-coded decision, and maybe that's okay, especially if this is kind of an isolated feature solving an isolate problem, for very predictable use cases. But I can already think of scenarios where having some kind of variables or contexts in the directives would be extremely advantageous. But instead of getting into those, first I'm just going to nerd-out for a second and put some alternate syntaxes so we can throw darts at them for the sake of discussion:

You can already do this with CSS:

@import url(example.css) screen and (color), projection and (color);

That syntax is just begging to be used for what we're talking about...

But we could also do these:

@import:context "styles.css"; (could be @import:css "styles.css" or @import:less "styles.css")
@import(context) "styles.css";
@import context "styles.css";
@import:context(variable) "styles.css";
@import "styles.css" less;

And if we're going to throw out convention altogether, how about arrays?:

@import ["styles1.css", "styles2.css", "styles3.css", "styles4.css", "styles5.css", "styles6.css"] 
// or the same beautified
@import [
    "styles1.css",
    "styles2.css",
    "styles3.css", 
    "styles4.css", 
    "styles5.css", 
    "styles6.css"
] 

And any of the concepts for context that I listed should still apply (I like contexts because they let me decide later what I want to do with the files in that context):

@import:dev [
    "styles1.css",
    "styles2.css"
] 
// or 
@import("dev") [
    "styles1.css",
    "styles2.css"
] 

and so on...

I just don't think @include is flexible enough to solve the real problem, which is that sometimes you want either your LESS and/or CSS files to be concatenated/appended, sometimes you don't.

@matthew-dean
Copy link
Member

Man, your brain needs to be here more often. I think you make some great points.

One of the things about LESS that we try to preserve (because of @cloudhead's directive), is that LESS be as CSS-like is possible. Not so extreme that it becomes awkward, but if there's a similar construct in CSS, we model after that.

So, of those options, I find @import "styles.css" less; the best, the cleanest, and most resembling CSS.

However, it's opposite seems awkward:

@import "styles.less" css;

What we mean with the second is not "turn into LESS" or "turn into CSS". What we really mean is compile inline or preserve @import behavior (which also means placing @imports at the top of the compiled file, per the spec.

So it might be better to have something like:

@import "styles.css" compile;    
@import "styles.less" no-compile;  // mimics "repeat no-repeat" of CSS

What do you think?

@matthew-dean
Copy link
Member

Oh, and obviously "compile" is optional and default with .less files, and "no-compile" would be optional and default with .css files.

@jonschlinkert
Copy link
Contributor

Yeah I definitely prefer that direction, but I don't feel strongly about any particular implementation. I liked that idea initially because I it seemed clean, but I'll think about it and let you know if any real pros or cons come to mind. (and thanks for the compliment!)

@lukeapage
Copy link
Member

moving discussion to a single issue #1185

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

No branches or pull requests

4 participants