less / less.js

Less. The dynamic stylesheet language.
http://lesscss.org
Apache License 2.0
17.01k stars 3.41k forks source link

Import options #1185

Closed lukeapage closed 11 years ago

lukeapage commented 11 years ago

We have decided that the best way to handle the import bugs is by having options.

Given the scope of the bugs I feel strongly that the options need to be inline with the actual import statement

I suggest removing @import-once and @import-multiple and allowing options to be passed to the @import statement

Note that import can already be followed by media statements e.g.

@import "file.css" (min-width:400px);

The options I propose we support are

  1. treat as less or treat as css - people have to add ?.css onto the end of url's at the moment to treat as css - a bit of a hack
  2. import-multiple to replace @import-multiple though not so important if we want to drop
  3. whether to keep the import in place or import it - at the moment we keep css imports inline, but it would be nice to be able to include in css files (treated as an anymous node)
  4. The ability to include a less file, but not output anything - just make the classes available as mixins.

so here are some options.

 @import (multiple: true, less: true, include: true) "file.less" (min-width:400px);

downsides are its a bit confusing with the media query syntax. we could also put the options second and mix them with the media query, defining our own special media query options essentially, but I don't like that in case we conflict in the future with css.

from @jonschlinkert

@options (multiple: true, less: true, include: true) {
    @import "file.less" (min-width: 400px);
}

and variations on the above, such as using closer media query syntax like

@import (multiple: true) and (less: true) "file.less";

I initially disliked @jonschlinkert's options idea, but it does actually allow for setting defaults.. what I don't like is that it looks a bit verbose.

we could also assume :true and have

@import (multiple, less) "file.less" (min-width:400px);

and I am open to any other suggestions.

lukeapage commented 11 years ago

@matthewdl's suggestion from #560

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

assume the options need to come before media queries and are differentiated from media queries because they are no in brackets?

jonschlinkert commented 11 years ago

I would add to your list the option to either combine imported files or keep them separate, regardless of whether they are LESS or CSS. The use case for me is that during development I often compile Less files separately so that it's much faster to debug, improve styling for a specific component, and force a separation of concerns. Then I combine stylesheets for production. It would be nice not to have to add @import "variables.less"; and @import "mixins.less"; at the top of every less file.

lukeapage commented 11 years ago

Isn't that an overall option rather than one to do on a single import? It is harder than it sounds, though could tie into the silent option.

I think I'd like to tackle it seperately after this.

All the above options (bar the import but silent) are easy.. I just want agreement on syntax. Not sure what my favourite is myself.

matthew-dean commented 11 years ago

I prefer the single line syntaxes rather than nested in an options block. Yes, I like the assumption of "true" for keywords. CSS behaves the same way. (If present, is on., a la the id attribute in header: header[id] {} )

The last part (min-width) isn't valid is it?

@import (multiple, less) "file.less" (min-width:400px);

The parser wouldn't know the width of your screen (unless compiling in browser). Unless, of course, we pushed the parsed block into a media query? Is that already supported in Less? (Pretty fucking cool if it is.)

I'm a fan of that or just straight keywords:

@import multiple less "file.less" (min-width:400px);

The @options block I had thought was for project-wide options. Wrapping it multiple times for stuff muddies the options feature, in my mind.

lukeapage commented 11 years ago

@matthewdl that syntax is css - if it is a css file imported less leaves it as it is and the browser wraps it in a media query essentially. If its a less file, less wraps the contents in a media query ;)

that example looks good to me.

 @import multiple less "file.less" (min-width:400px);

and the @options block - yes I think we've already agreed, but thought I'd include it in case people want to change their mind or anything.

lukeapage commented 11 years ago

@matthewdl that syntax is css - if it is a css file imported less leaves it as it is and the browser wraps it in a media query essentially. If its a less file, less wraps the contents in a media query ;)

that example looks good to me.

 @import multiple less "file.less" (min-width:400px);
matthew-dean commented 11 years ago

Well then that's fucking cool. I didn't know that. Is that documented?

jonschlinkert commented 11 years ago

@matthewdl lol yeah I know, it needs to be documented for sure! I thought that was pretty awesome too when I figured that out - that's why I threw it into the hat - since it already had precedence.

Isn't that an overall option rather than one to do on a single import? It is harder than it sounds, though could tie into the silent option.

I'm sold, that makes a lot of sense, and I don't really have any strong preferences regarding how this is accomplished. It would just be really useful to have options regardless of how it's done. And anyway my preference has always been to do this inline, and I think my suggestion for doing this using the @options directive was intended to be something that could be used as an alternative to inline - but only after inline existed first, and IF it made sense to use the @options direction in addition to inline. (I hope that makes sense). In other words, in my own projects I have these "less manifest" files (you know, the file everyone uses that has something like 80 @import statements to pull in other less files. Is there a better term for this?), it would be nice to not have to customize every single @import statement. So the idea was that you could do something like one of these concepts:

@import (rules) {
    "one.less",
    "one.less",
    "one.less",
    "one.less"
}
// Import all files within the given directory
@import "less/mixins/*.less"

// Import all files within the given directory AND sub-directories
@import "less/mixins/**/*.less"

I imagine Less would throw and error if you specified subdirectories but one of them did not contain an index.less file. I want to sell you guys on this, particularly @matthewdl ;-) because I think this would be the feature that puts LESS on the path to offering Compass-like capabilities. Please spend some time looking at node-glob before you dismiss this, it's very flexible, has strong support, it's used pervasively by Grunt.js for instance and it's addictive to use, and it allows many different patterns for including or excluding characters, files or directories, etc. So I envision using this to begin creating libraries similar to Compass. I understand that it wouldn't work in the browser, but IMO we should not allow a "worst practice" to prevent progress of the rest of the spec. And there are many tools out that that allow you to edit Less and have it compile and refresh the browser in real-time.

matthew-dean commented 11 years ago

I like this idea:

@import (rules) {
    "one.less",
    "one.less",
    "one.less",
    "one.less"
}

I think "grouping" settings might be valuable (such as a case where I have a group of files that end in ".css", but are actually Less files, which a number of users have described).

However, I think we might need one tweak for syntax. In CSS, curly braces inevitably wraps either property/value pairs terminated by semi-colons, or a group of selectors, such as with media queries. Animation keyframes have a group of keywords (values) which are followed by curly braced set.

So, can we make this more CSS-y? I can't think of how, off the top of my head. Not that Less has never added things that don't resemble CSS, but I know in conversations with @cloudhead that he was always loathe to. That is, let's make sure the syntax doesn't exist in CSS before we add something new.

I'll see if I can take some time to look at node-glob. I would say that could be its own issue (mass import). It does raise a question that's been tickling the back of my brain, but it would be a major shift, so I'm almost afraid to mention it. lol

jonschlinkert commented 11 years ago

we might need one tweak for syntax

we could grab one of the other syntax ideas that were thrown out for imports and just swap it in. The file list part is what I think would be nice to have, so whatever syntax makes the most sense is cool with me. But just a comment on this:

can we make this more CSS-y

IMO the example is a CSS-y syntax, I chose it because it's similar to media queries. We probably won't be able to please everyone anyway, so whatever syntax makes the most sense from the standpoint of enabling the functionality that we require is what I think we should implement.

I'll see if I can take some time to look at node-glob. I would say that could be its own issue (mass import)

I did make another issue for that #1181. But I'm actually thinking that since it does keep coming up along with the other import-related issues that it might be best to merge it over here. One thing we could start doing is using the new checkbox feature that GitHub added to Issues. I think it's for this very use case, and it allows you to add "tasks" to Issues. You just do - [ ] to add a checkbox (note that there is a space between the brackets), and you can add a completed task just by adding an x in the brackets. Like this:

Then anyone with edit rights can check the boxes in read mode. I saw these a couple of times before I realized you could actually check and uncheck them

matthew-dean commented 11 years ago

By CSS-y, I mean specifically that there's nothing in CSS where a comma-separated list is enclosed in curly braces. CSS typically treats lists as single line declarations (such as the CSS3 multiple-background syntax, or font-family).

If you think of the font shorthand, a more CSS-y type declaration would be like the following:

@import multiple less "one.less", "two.less", "three.less" (min-width:400px);

or, alternatively:

@import multiple less ("one.less", "two.less", "three.less") (min-width:400px);

I think of LESS as CSS+. If a syntax pattern exists in CSS, we should either use it or make a strong case why we're not using it. I couldn't think of any exceptions to this that might include a comma-separated list in curly braces, which is why I raised the issue.

jonschlinkert commented 11 years ago

there's nothing in CSS where a comma-separated list is enclosed in curly braces

@matthewdl Oh, lol. Yeah that's true, and I didn't know you were talking about that part of the syntax, which is the part I like. ;-) And what you're saying makes sense, but technically there are dozens of properties that allow a comma separated list, so if we wanted to be creative (before I put this, I really could go with whatever pattern works best from an implementation standpoint. I'm just throwing out stuff to see if anything works):

The thing about the @options concept that might not have been clear above, is that it's most useful for more than one statement, and wouldn't like be as complicated in most cases. So, this might be more common (I'm not really focusing on what options are actually here, just the general syntax, so whether it's less: true or whatever is arbitrary to this point):

@options (less: true) {
    @import "file1.less";
    @import "file2.less";
    @import "file3.less";
    @import "file4.less";
    @import "file5.less";
}
@options (less: false) {
    @import "file6.less";
    @import "file7.less";
    @import "file8.less";
    @import "file9.less";
    @import "file10.less";
}

With the idea being that we would still have a "global @options directive", but only a couple of options from that would be usable with import statements like this (if using @options in both places is too confusing, this could still be done using the "media query style" syntax with @import that I gave in the earlier example). The other thing about this concept that is really cool, is that after the @options directive is implemented (assuming it is), we could sometime down the road implement a new option called "contexts" (which was "part 2" of that proposal) that is used to control how the individual LESS files are compiled from the global @options directive. It would work kind of like this (gist works best for this): https://gist.github.com/jonschlinkert/4975400

other concepts

@import (concatenate: true, process: true) {
    multiple: "one.less", "two.less", "three.less", "four.less";
    multiple: "one.less", "two.less", "three.less", "four.less";
}

By the way, I think I need clarification on what the options are: "include", "multiple" and "less". I'm confused between multiple and include in particular.

lukeapage commented 11 years ago

It is documented here

https://github.com/cloudhead/lesscss.org/pull/64

someone needs to pull that.

I suggest that we start simply and allow ourselves room to maneuver

I prefer this syntax best...

@import multiple "one.less" (min-width:400px);

@import (multiple, less) "one.less" (min-width: 400px);

@import (multiple, less) ("one.less", "two.less", "three.less") (min-width:400px);

@import (multiple:false, less:true) ("one.less", "two.less", "three.less") (min-width:400px);

and I suggest we start with only implementing the first two for now.

I suggest we can include these options in the @options directive as well - but we tackle that in the seperate issue.

After we have done points (1) and (2) and the @options we decide whether to allow importing multiple files in one @import statement, or whether @options can be used in the way @jonschlinkert suggests, defining options inline.

I think its important we look ahead, but I think as long as we are happy we have a rough roadmap, we don't need to consider this advanced usage - no-one has asked for it yet.

Remember that files with extension .less won't need a less option, they will be by default parsed as less still - and the that the silent option is likely used with a library where you just need to import a single file - so I've not yet seen a use-case where someone needs to apply these @import options to multiple files.

lukeapage commented 11 years ago

How about this for the option names?

multiple, once - whether to import the file with that href/path once or multiple times. Default once.

less, css - whether to treat the import as less or css. Defaults to less unless ending in .css, then it is css

silent - whether to silence the output and just allow the importer to reference the styles

inline - whether to put the contents inline or keep it as an import. must be true for less files, css files default to false

matthew-dean commented 11 years ago

I like all of the above keywords except I think inline is unnecessary. If it's a CSS, can we not just interpret as LESS? Of course, you may have invalid CSS, but just wondering about that one.

In general, in agreement with @agatronic. I don't like the @options blocks used with this.

I think this should be allowed:

@import multiple less "one.less", "two.less", "three.less" (min-width:400px);
@import "one.less", "two.less", "three.less" multiple less (min-width:400px);

It makes it additive to this:

@import "one" multiple;

So, the dev isn't required to add parentheses by adding more options. Seems pretty similar to shorthand syntax then. And if its shorthand, maybe longhand is this?:

@import (min-width:400px) {
  options: multiple less;
  source: "one.less", "two.less";
}

(Combining some of @jonschlinkert's ideas.)

lukeapage commented 11 years ago

if we get rid of the brackets I would like to get rid of the commas between file names

@import multiple less "one.less", "two.less", "three.less" (min-width:400px);

reads as

@import multiple less "one.less";
@import "two.less"
@import "three.less" (min-width:400px);

I don't like the keywords at the end because media queries can look like this

@import "file.css" tv and (scan: progressive)

and I'd rather not be trying to distangle a media query keyword (tv) from a @import option

inline is useful if you have a component with its own stylesheet, which isn't less compatible and you want to compile your stylesheets together without using an extra tool. There are quite a few things that less doesn't parse around comments and particularly css hacks. One use-case was a guy using the jquery ui stylesheet which has css hacks in it - an obviously you don't want to edit the library - but at the same time would quite like the css inlined in the place you want it.

matthew-dean commented 11 years ago

Ah, interesting.... that being the case, then forcing compile flags at start seems reasonable.

So, you're suggesting syntax like this? :

@import "one";
@import multiple "one";
@import multiple less "two.css" "three.css" "four.css" (min-width:400px);

Basically, one can add as many quoted files as they want (and import keywords, but must be at start)?

By the way, what's the use case for importing a file multiple times? Changing variable scope? I never quite got that.

lukeapage commented 11 years ago

Multiple has no know usecases but is current behavior. In previous pulls and work by cloudhead it was kept in.. I am no fan but considering its simplicity to implement and that its current behavior, I'm tempted to keep it.

matthew-dean commented 11 years ago

Yep, makes sense.

ztane commented 11 years ago

How about the "@use" directive suggestion that was merged into this issue? The case is that sometimes we need to have rules for .one-class in one file exactly like .another-class in another file. That is to say, we need an @import directive, that even if the file is included only once, no rules will be produced additional rules, and its contents can be used as mixins only.

lukeapage commented 11 years ago

@ztane that is the silent option

jonschlinkert commented 11 years ago

@agatronic

I suggest we start with only implementing the first two for now.

and

we don't need to consider this advanced usage

Sounds good to me.

I prefer this syntax best

Sounds good to me.


@agatronic's proposal for options:

How about this for the option names? multiple, once - whether to import the file with that href/path once or multiple times. Default once. less, css - whether to treat the import as less or css. Defaults to less unless ending in .css, then it is css silent - whether to silence the output and just allow the importer to reference the styles inline - whether to put the contents inline or keep it as an import. must be true for less files, css files default to false

multiple

multiple has no know use cases but is current behavior... I am no fan but considering its simplicity to implement and that its current behavior, I'm tempted to keep it.

My gut tells me that something like this happened: originally, Less.js just allowed multiple by default, then someone made a request to "fix" it, and acknowledging that it needed to be fixed, when @cloudhead implemented "multiple" he was probably planning for when @import would default to "once", at which time "multiple" would be the fallback for anyone who was taking advantage of that behavior prior to the fix.

I say "to the gallows with multiple"!

IMO it's just clutter and I think we should deprecate it "officially" and we should stop using it in examples so we don't confuse anyone (I already do that enough for us) - I don't think any of us have ever heard one use case for it. We could still keep in the code for now, and I can label it clearly as deprecated in any documentation (primarily here #64, as @agatronic pointed out) - allowing anyone who sees the deprecation notice ample opportunity to speak up and fill us all in and provide the heretofore undiscovered use case for keeping it (and maybe win some kind of prize?). With the net impact that nothing really changes and you're not really doing anything in the code, but we can stop using it in these examples and plan to phase it out. That's my 4 cents on that.

less

I suppose this makes sense, but what was the use case for this? Whatever it is I agree with @matthewdl that it should default to LESS.

silent

Why don't we just call this what it is? "mixin". Isn't that what we're doing here?

@import mixin "one";

If I'm wrong then ignore my point as well as the next statement lol. But "silent" kind of reminds me of how SASS chose terminology for mixins. You create a mixin with @mixin and then you @include it, so it's kind of disconnected even though it does make sense in their spec. I was confused by that at first since I had been using Less for a while. Anyway, unless you're planning ahead for additional behavior than what I've seen described, to me it makes perfect sense to call this option mixin. (oh, and I don't think @use makes sense either. I would think @dont-use-unless-mixed-in would be more accurate, right?).

inline

@matthewdl

I think inline is unnecessary

I'm inclined to agree, seems like if you have access to a CSS file to import it, why not just rename it to ".less". Although it has been requested by several folks as a way to concatenate CSS files alongside LESS files, rather than pass them through individually as with a regular CSS @import. So I suppose there are use cases.

So assuming we do implement this feature, unless I'm missing something, here are the reasons I think this should be called concatenate, or "concat" for short:

I don't even mind if we call it "concatcss", to describe exactly what it's doing. There are plenty of plugins out there called "mincss" or "cssmin" etc. In any case, if you don't want to use concat, at least don't use "inline".

However, I personally would much rather see the option for what I requested earlier in this thread (here https://github.com/cloudhead/less.js/issues/1185#issuecomment-13677140), which is kind of the opposite of the inline feature and would add an option to split out all @imported files into individual files. Honestly I never even thought to request it as a feature before this came up, but it's the biggest thing I've struggled with since I started using LESS. It might sound strange, but it works very well for component-based development - which is where front-end development is going right now.

jonschlinkert commented 11 years ago

Regarding the last paragraph of my comment, that option could be called "separate" or "split".

matthew-dean commented 11 years ago

@jonschlinkert There's a lot of related issues to reference.

"less" is for when it's not a file that explicitly ends in ".less", but you want to interpret as LESS. There are a number of reasons people have mentioned why this might happen, but I don't want to summarize them all. It's valid.

@import mixin "one";

No.

This reads like I'm importing a mixin called "one", or maybe only mixins from "one.less". But, in any case, it's not a mixin. "Silent" has nothing to do with mixins. I just don't want it to render anything. Whether or not that roughly matches a definition of mixin seems neither here nor there, it's just an obfuscation of terms. I think "silent" is an elegant keyword for importing an entire library without rendering, whereas mixins in LESS do not span libraries, typically, plus the import takes no variables. So, no.

"multiple" - You're probably right. LESS just faithfully respected every time you used the @import statement, and assumed you knew what you were doing. It was probably just not anticipated that you would obnoxiously import the same thing several times, yet somehow expect it to show up once.

But of course, as you said, people have done just that, and understandably, because they are importing libraries as components that can separately reference the same file.

So, I think that's an interesting proposal. If I recall, @agatronic or someone mentioned some use cases where someone claimed to use multiple import behavior, but if so, it's probably an edge case and not the only way to go about things to get the same result in LESS.

"inline" - @jonschlinkert - Your definition of "inline" actually describes the behavior @agatronic is definining. Rather than the CSS staying external, it's rendered inline. But, I don't disagree that's a weird feature in and of itself.

There are quite a few things that less doesn't parse around comments and particularly css hacks. One use-case was a guy using the jquery ui stylesheet which has css hacks in it - an obviously you don't want to edit the library

There have been lots of times historically where LESS couldn't read a CSS library. @font-face, for example, wasn't supported for a while. In those cases, you just referenced the CSS separately in your HTML. Wasn't the end of the world. I don't think LESS has to necessarily be a minifier for all manner of CSS that isn't valid. There are minifiers to do just that. So, I can have my LESS lib, my CSS libs, and if I really care about the extra HTTP requests, I can install a minifier to lump up various http resources.

On the other hand, devil's advocate, it's trivial to include, but yeah, kinda iffy.

lukeapage commented 11 years ago

yep.. I suggest reading the 3 linked bugs.

multiple - I think I might implement it but not document it - if people complain we can add it to the documentation, if they don't I'll remove it the release after

inline - @matthewdl it may not be "the end of the world" to render css outside less, but its hardly making things easy. Also there are css hacks less has never supported and still doesn't - should we just ask people to wait forever.. ideally people want only 1 stylesheet. Regarding getting an extra minifier, if less didn't include its own minifier and use yahoos minifier I would agree with you, but it does include those.

So for all those reasons and because it is a low cost implementation, I would like to do it.

@jonschlinkert your option for keeping files seperate - I would like to handle that as a seperate issue/request - all the above options are relatively simple and have been asked for time and time again over the last 2 years. As I said it is slightly different because I think it would benefit from being a global option better than a option on each import.

jonschlinkert commented 11 years ago

I think it would benefit from being a global option better than a option on each import.

Agreed, thanks. I'll create that issue.

How fast are we moving on this one? Seems like there should be more discussion before a final decision is made. I'm having a difficult time understanding some of the reasoning here.

lukeapage commented 11 years ago

As I said, these issues have been long standing for a long time. I wanted to get this resolved for 1.40.

what more discussion needs to take place?

jonschlinkert commented 11 years ago

what more discussion needs to take place?

Nice.

lukeapage commented 11 years ago

@jonschlinkert Well what I mean is - what is controversial, what needs discussing, what is concerning etc. because I don't see anything that needs alot of discussion. Particularly when each of the original issues also has discussion and has been open for discussion some time. Its taken many months as it is to get to this point..

jonschlinkert commented 11 years ago

Technically, no more discussion is required at all. But seems like we're in repeating a pattern here:

from @matthewdl

Whaaaaaaaa.....? o_O Considering that !important is widely considered one of the largest syntax mistakes of the CSS spec, I'm not a huge fan of this....

and

As is, this is an absolute no for me.

And then @agatronic

@matthewdl we are woefully short of people to help contribute to less.js and I'm scared your negativity really puts people off. We should be cautious with new features, but there is no need to go ott.

Then me:

just my 2c but I didn't perceive negativity like that from @matthewdl. In retrospect we were kind of jumping on this one pretty quickly without due diligence - that's what I think Matthew was picking up on.

and then @matthewdl again:

So, rather than just react and say "no", what I really would like to propose is that big features like this get much more time for debate / comment. I try to stay on top of what LESS discussion are happening, but don't always have time, and some things I would have liked to throw my $0.02 in before they were merged into code. Or there's things that have been pulled / merged, but upon further discussion, there was consensus around a different approach, but it had already made it in a release.

and then @agatronic again:

I'll always try and bring other people in on any syntax changes before I merge and I'll always hold off if you or anyone else sows the seed of doubt, but after that we need a way forward - either @cloudhead comments with an executive decision or its based on positives vs negatives.

What happened to this sentiment? And @matthewdl, do you still have food poisoning?

here is @matthewdl's response to my suggestions on this issue:

but I don't want to summarize them all. It's valid.

Matthew you know I'm working on the docs, so I'm asking for more than one reason. And I said I was "just curious". So why the tone of handing down a decision that is not to be questioned. I didn't even care about this keyword enough to question it. And pragmatically if we need to have multiple discussions about something like this it's a waste of time. It would be more effective for everyone if you just answer the question or don't say anything at all if you have zero value to add. And then I can spend my time contributing rather than explaining why you ought to explain.

but then

No.

and then:

So no.

Regardless of whether or not my suggestions were even worth considering, you are demonstrating some patterns here, one of which is being dismissive, and I take particular exception to it considering that I was the one that suggested we create this Issue in the first place, my name is next to at least a couple of the proposed solutions, and I've been participating in the discussions related to this feature for quite a while.

I really don't care which words we choose for the keywords, but seriously guys, is it really okay to accept reasoning like:

I think "silent" is an elegant keyword

Shouldn't we set the bar a little higher? Maybe have some kind of logic to back up our assertions? I mean, I personally think the word "stark" sounds chilly, dark and lonely. But who gives a shit? This is Less.js, an open source project, with a large community and one of the top projects on GitHub, and you guys are the stewards of it. We need to do better than this.

This reads like I'm importing a mixin called "one"

I feel no sense of entitlement over my suggestions whatsoever, so if it doesn't work, let's move on. But when I suggest "mixin" and Matthew replies as he did here. My only thought was, "okay, add an 's' to it". Would it then read like your importing "mixins"?

But, in any case, it's not a mixin.

Perhaps, but the styles do "behave like mixins", don't they? I mean, perception is reality.

"Silent" has nothing to do with mixins.

I'm inclined to agree. nothing.

I just don't want it to render anything.

Meaning "ever". What would be the point. Of do you mean you want it to behave like mixins? I'm just saying.

Whether or not that roughly matches a definition of mixin seems neither here nor there,

I'm calling bullshit on this one, but if this is indeed the case then I'm more confused than ever. "roughly [matching] the definition of mixin", isn't relevant (to the decision)? Then I have indeed misunderstood what this feature would do. I was under the impression that the feature would allow a user to use an entire external file as if they were mixins. So that the styles are made available, but they aren't rendered in the CSS unless they are used somewhere (e.g. as mixins).

it's just an obfuscation of terms.

I don't care if we go with something I suggested, but your reaction makes it seem perfectly clear that this feature has absolutely nothing to do with mixins. Nothing whatsoever. So please clarify what the feature does then. How does one use a "silent style"? It only makes me think of "silencing errors", which doesn't educate a user on what the feature does without documentation.

I have similar views of one of the other keywords, but I don't have enough time to write them out today. You guys seem like my kind of people, but when you get down to it we're all here to help out with Less.js. And we all have other battles to fight, so if you prefer I'll just shift gears to the docs and spec entirely and leave you guys to the features and issues.

matthew-dean commented 11 years ago

@agatronic - Inline I was on the fence about. You're for it. That's good enough for me to put it in.

@jonschlinkert - Be nice. ;-)

As far as speed, I feel like these are minor revisions to @import. That is, I don't feel like [multiple|once] [less|css] silent inline are controversial.

That said, overall LESS contribution has picked up speed as of late, at least in terms of discussion. We might want to start making broader plans about what to focus on. You have to be on the ball in Github to figure out which Github issues have active discussion, or are related to important features. Whereas, we could be saying, "We're focused on extend, then extend mixins, then options". But that's a tangent from this discussion.

In this case, I'm happy with the minified syntax and the few keywords we've added to make imports more manageable.

matthew-dean commented 11 years ago

@jonschlinkert - Just read the response you posted around the same time. Probably valid criticism.

Probably most valid is if there's a different direction a features is headed, then not properly communicating what it actually means in practice. So yes, ask tough questions. But please refrain from asking if I'm motivated by food poisoning or tossing sarcastic asides or threatening to leave. Let's all work together to keep a civil tone, and I'll work to be less dismissive.

I get now what you were saying about mixins. I suppose, in a way, you could say you're converting the behavior of the included classes, selectors to something like mixins. It just struck me as wrong that the entire file is converted to a mixin. In my mind, I was imagining wrapping the import in a mixin, that was called with parameters. You are correct, the effect, as I would understand it, is that nothing is output initially. But, of course, the classes / mixins / selectors are still available, so, it is a good point that they're similar to mixins.

Should we discuss that specific point? Mixin vs. silent?

jonschlinkert commented 11 years ago

@matthewdl, wha! I didn't threaten to leave, are you referring to this? if you prefer I'll just shift gears to the docs and spec entirely and leave you guys to the features and issues". I did use the word "leave" lol, but not the way you read it.

Actually that was the problem with the points I made on some of the keywords, you somehow thought I meant the complete opposite of what I was saying. We agree a lot and you think I'm disagreeing. Once in another discussion I even stated that I agreed completely with you and then you replied that you disagreed lol. So the next time you said something like "hey! we agree for once!", I jokingly replied that I disagreed... anyway.

Should we discuss that specific point? Mixin vs. silent?

I'd like to if @agatronic is open to it. But rather than focusing on the keyword, I'm curious, if you were writing tests for the feature what would the code comments say? Or if we were to add a brief summary about the feature in the docs, what would that say? I guess I'm always the one doing docs for project I work on, so I view things through that lens by default. Something that might make be okay with everyone is to just use the terms you have, but only as "candidates", and then crystallize them after you start testing the features. So we would have breathing room to pick the right terminology, but you don't have to wait.

matthew-dean commented 11 years ago

Well, let's agree to disagree that we agree. ;-) Just kidding.

If I were writing it up, it could be something like:

silent: Imported file is silent. e.g. no CSS is generated by default.

But, now I'm glad you brought it up, because it's possible that I'm assuming behavior that maybe it doesn't have. I think this is the result / offshoot of @use, but I couldn't find code examples in that thread either.

So, here's how I would EXPECT it to behave. Which may or may not be what other people expect / would use it for.

// file: mylibrary.less
#someid .someclass {
   property: value;
}

// file: myrootfile.less
@import silent "mylibrary";

Compiled as nothing... until...

// file: myrootfile.less
@import silent "mylibrary";

#mapto .thisclass {
  #someid .someclass;
}

So, you could use it to do some pretty powerful translation stuff, for examples like:

  1. I want to use the styles of Bootstrap on a SharePoint site, but changing the markup, class names in SharePoint would take too much work. Instead, I'd like to convert Bootstrap classes to SharePoint ones, without altering the source code of Bootstrap (for upgrades / bug fixes). (Or, for example, Wordpress, where changing default class names is not very feasible.)
  2. I want to use the mixins of a particular library (and all its associated LESS files), but not any of the output classes. The mixins are not cleanly separated (for whatever reason).
  3. I want to do a combination of both. Use some mixins, and also use styles but convert class names.

Those are my common use cases for silent. But not sure if a) that's the supported behavior, b) other people have differing use cases which we might take into consideration.

However, other devs in the @use thread made good points where telling a LESS library developer to make their library play well with others and not overwrite base/default HTML styles (* cough * Bootstrap * cough *) is really not going to solve the problem. Instead, the goal would be to make give consumption of libraries an "opt-in" option.

In a way, it's like many of your statements that helped guide us to default extend behavior (conservative importing). So, you could import tons of libraries whose CSS would normally clash, and then pick and choose how you want them to be output in your CSS.

@agatronic (and others) - Am I on the right track with how you were thinking about this?

cscott commented 11 years ago

I'd feel better about this thread if I saw more code attached.

matthew-dean commented 11 years ago

@cscott Noted, and at this point, agreed. Each of these options need code / flow examples, even if we think we're on the same page about them.

lukeapage commented 11 years ago

sorry I said end of discussion I was just reading quickley and genuinely didn't think there was anything left undecided or contraversial.. I wasn't trying to stop better ideas coming through.

silent - yes agree with above on how it would work.

Im happy to add any more examples if anything else above isn't clear..?

Silent vs mixin.. mixin is specific and implies just mixins (not extend?.. not some other reference in the future). Silent is a bit misleading in that the output isn't silent if referenced.. "reference" is an alternative? For clarity of understanding still prefer silent though.

matthew-dean commented 11 years ago

mixin is specific and implies just mixins

Right, that was what I was trying to say as well. That "mixin" was problematic (or more problematic), not that "silent" was perfect, just because the behavior / scope is larger than or somewhat incongruent with the concept of mixins, whereas "silent" has no weight of meaning attached in terms of LESS wording. So we can attach the meaning we wish.

jonschlinkert commented 11 years ago

Okay... it makes more sense than it did. The "silent" part isn't really about the styles at all, it's about the file(s)? So regardless of whether or not the styles are used, the file itself is "silent". "reference" doesn't seem right either, but I can see the reasoning there too. Are we thinking of mixins as being something more planned and organized? As with parametric mixins for browser prefixes and complicated gradients? Technically mixins are any old class.

I hate to sound like I'm beating this to death, but this is just brainstorming... and I really am totally cool with going with whatever term you decide on. But this still sounds exactly like mixins to me. Or like a flavor of externalized mixins. We already have different types of mixins: just regular "mixins" and "parametric mixins".

To your point about it being specific and implying mixins and not extends, it seems that we should try to plan the feature more to be more clear, with a specific purpose in mind, and ease of use. I'm taking a leaf out of @agatronic's book here, but if someone comes up with the future use case you're describing we could look at it then. And if it has something to do with "extend", then I would think that logically it would be, well, and "extension of extend"... hmm. Plus, I can't think of any scenarios where you would be able to "extend into" the "silent file". So how would that work?

Ah, I just thought of something, to your point about having some other reference in the future, I think it would be harder to get mileage out of silence than mixin. Or rather, if there is functionality that no longer fits the description of mixin, then it should be called something else at that time...

matthew-dean commented 11 years ago

The future use case I'm describing? What do you mean? Has something to do with extend? o_O ? I must have missed something that I wrote or someone else wrote... Are you referring to this?

it's like many of your statements that helped guide us to default extend behavior (conservative importing)

?

If so, I just meant the thought process towards conservative output was similar, not that the two features (silent import and extend) had anything to do with each other, which I don't think anyone was suggesting. But, it raises a good question about how :extend would interact with "silent".

The use cases I was describing weren't future, to my knowledge, they'd be current ones behind the reason to have the silent feature.

matthew-dean commented 11 years ago

Wait.....

Ah, I just thought of something, to your point about having some other reference in the future, I think it would be harder to get mileage out of silence than mixin. Or rather, if there is functionality that no longer fits the description of mixin, then it should be called something else at that time...

I feel like I totally missed something. I can't grok what in the thread you are referring to. I don't know what "harder to get mileage out of silence than mixin" refers to. My understanding is that the behavior is the same and we were debating wording. Can you clarify what you mean?

jonschlinkert commented 11 years ago

@matthewdl sorry, I didn't put names. i was referring to @agatronic's comments.

jonschlinkert commented 11 years ago

This

Silent vs mixin.. mixin is specific and implies just mixins (not extend?..not some other reference in the future).

Sorry for the confusion. The point I was making is - per Luke's comment - that if we want to be kind of "future proof", then silent seems more limiting anyway (not saying mixins is "the" term), but IMO we should intentionally be specific and descriptive regarding the functionality that this feature does have today.

jonschlinkert commented 11 years ago

I might be coming down with a cold so I'm going off to bed. I'll definitely around tomorrow morning though. Have a good night

lukeapage commented 11 years ago

So did we agree on

@import multiple less "http://here.com/file.php" tv and (max-width: 400px);

or

@import (multiple, less) "http://here.com/file.php" tv and (max-width: 400px);

I'm cool with either..

Once we have that nailed, does anyone object to me pulling the pull request above and altering if need be to the format suggestion?

Next..

less/css

@import "file.css";

gets treated as css and left alone (meaning a @import appears in the output to this file. import with any other file extension gets treated as less, meaning it is parsed and inlined. Specifically we will continue to look at the end of the href rather than the file extension specifically so that existing hacks continue to work (for now).

use the css option for cases where a web service returns css you do not have control over - e.g. instead of doing @import "http://google/file?.css to make less think it is css.

use the less option when you reference a css file that you want to be parsed as less, but cannot change the file extension for some reason.

once / multiple

whether to import the file once or multiple times. we used to default to multiple, now we default to once.

use case for multiple is when you have a less file you can't change and want to include that less file inside different media queries, using the scope of the media query to change variables used in the less file - kind of like a massive mixin.

we will not document this option explicitly and will remove it in the future unless we get strong use of the above usecase or other uses cases that multiple can be used for.

inline

copies the contents of a file into the less, rather than reference it. e.g.

@import "file.css";

would at the moment become

@import "file.css";

and this would inline the css so it becomes

// I am a css file, I use a css hack less has never worked with
.a/*\*/.b*/ { color: black; }

(bad example above, can't remember my hacks!)

only valid with a css file

silent (/mixin / reference) ??

import takes the contents of the less file and puts it inline, as if the files were joined together. Silent continue to do this, but marks the contents as silent, so they can be referenced but not output. e.g.

//file.less
.a { color: black; }
.b .c.d { color: white; }

//main.less
@import "file.less";
.e { .a; }
.f:extend(.b .c.d) {}

current output...

.a { color: black; }
.b .c.d,
.f { color: white; }
.e { color: black; }

output with silent

.f { color: white; }
.e { color: black; }

I see this as every selector in file.less is silenced, but if it is referenced it doesn't stop the use of it from being silent. I imagine this like a silent boolean property on root level selectors and directives - if a new selector is added to a ruleset then it still gets output.

usecase - powerful refactoring/ use of libraries.

only valid with a less file

cscott commented 11 years ago

I implemented

@import less "foo.css"  /* for just one option */
@import (multiple, less) "foo.css" /* for more than one option */

I also suggest that the "silent" and "inline" options be split out into new bugs. This bug should be for basic option syntax, with no new features (IMO).

jonschlinkert commented 11 years ago

@cscott, really this issues was created to discuss new features (reason for the "feature" tag ;-), with syntax only being incidental to that. But I don't really care where the discussion takes place - if we close and create a new one we can always reference past discussions. I think this is completely up to @agatronic

lukeapage commented 11 years ago

If I don't do inline and silent for 1.4.0 I'll close this and make new bugs for the bits not implemented, otherwise lets keep it simple for now.

@matthewdl I think we are just waiting for some feedback from you on the exact syntax ?

@jonschlinkert any preferences on syntax or comments/concerns over my proposal for a final spec above?

lukeapage commented 11 years ago

@matthewdl I would like to include this now and get rid of @import-multiple and @import-once and release a new alpha.. is this ok with you?

matthew-dean commented 11 years ago

I think if we support this:

@import multiple "foo.css"  

...then we should probably support both of these:

@import multiple less "foo.css"  
@import (multiple, less) "foo.css"

Or is that too complicated? Just feels weird to change the config syntax based on number of options. CSS doesn't usually act that way. If we don't support both, then I would support this:

@import (multiple) "foo.css"  
@import (multiple, less) "foo.css"

What do other people think?