less.ruby icon indicating copy to clipboard operation
less.ruby copied to clipboard

Mixin doesn't work when the class is split

Open onlinesid opened this issue 16 years ago • 19 comments

test.less:

.abc { display: block; } .abc { height: 10px; } .test { .abc; }

Resulted test.css:

.abc { display: block; } .abc { height: 10px; } .test { display: block; }

Expected result:

.abc { display: block; } .abc { height: 10px; } .test { display: block; height: 10px; }

onlinesid avatar Aug 02 '09 10:08 onlinesid

You aren't really supposed to use mixins this way, that's why.. I'll look into patching it though, because this could be interesting.

cloudhead avatar Aug 02 '09 10:08 cloudhead

I know, I simplified it just to show how to reproduce the error, but I was actually compiling blueprint's screen.css (version 0.9).

The more I see now that CSS syntax is really a mess and framework like blueprint should really be written in LESS :)

onlinesid avatar Aug 02 '09 10:08 onlinesid

Ah I see! Hopefully we start seeing some CSS 'frameworks' converted to LESS in the near future :)

cloudhead avatar Aug 02 '09 11:08 cloudhead

This would be immensely useful. Speaking as a maintainer of Blueprint, it's safe to say we will fully support LESS once this is implemented.

The reason why we can't right now is because of this feature. Although I understand that mixins aren't supposed to be used this way, this would allow developers to use our grid system in a semantic fashion quickly and easily.

For example, http://github.com/joshuaclayton/blueprint-css/blob/414d9242c3b3ffdf5e2d90a84c87a4c4c711a135/blueprint/screen.css#L100 shows a bulk assignment of all grid-related classes to float left and have a margin. Then, each width gets assigned a specific width.

Allowing a dev to use a mixin of .span-8 (pulling in the margin, float, and width) would be a great addition and, as I mentioned before, a deal-breaker for encouraging use of LESS.

+1

joshuaclayton avatar Aug 18 '09 20:08 joshuaclayton

That's reason enough for me to consider this : )

+1

cloudhead avatar Aug 19 '09 00:08 cloudhead

+1 this would be stellar.

jonbuda avatar Aug 19 '09 14:08 jonbuda

+1

timkelty avatar Aug 20 '09 12:08 timkelty

+1 Especially due to blueprintcss

erikzaadi avatar Oct 22 '09 11:10 erikzaadi

@cloudhead Any progress on this? Not having this feature really changes how I would ideally use less for grids, clearfixes, etc. +1 again!

timkelty avatar Oct 22 '09 13:10 timkelty

I'll make it my next priority, the dynamic mixins still have some bugs to iron out.

cloudhead avatar Oct 22 '09 14:10 cloudhead

I'll be eagerly anticipating, thanks. Less makes life more awesome.

timkelty avatar Oct 22 '09 14:10 timkelty

+1

mikegrassotti avatar Nov 06 '09 22:11 mikegrassotti

Yeah actually we thought that we should have done this on our .NET port. Seems sensible to support blueprint etc..

chrisjowen avatar Nov 09 '09 19:11 chrisjowen

You're asking an awful lot of a CSS compiler that has no knowledge of the document to which the CSS is being applied. For instance, in the blueprint example .span-1 is a class that can be applied to all kinds of elements (div, input, td, th). Then there are element selectors for div.span-1, input.span-1 that further augment the selector.

If less adds this feature via mixins, it will be a disaster and very confusing to users. The reason is that a mixin behavior is not actually what you seek. Allow me to present a slightly more complicated example:

.column    { width: 300px; }
div.column { float: left; margin-right: 10px;}
td.column  { padding-right: 10px; }

.foo { .column; }

The "right" behavior of what the contents of .foo should be depends on what element the .foo class has been applied to. Something that a compiler cannot know. Now you could force the user to exactly match the selector, but still how will you handle descendent selectors, etc? It just cannot be done with mixins.

You want class inheritance.

The expected output that you really want for the example above is:

.column, .foo       { width: 300px; }
div.column, div.foo { float: left; margin-right: 10px;}
td.column, td.foo   { padding-right: 10px; }

In other words, you need to take the inheritance to the selectors.

Unfortunately, even this approach fails in some ways that are a bit edge-case in nature.

I wrote up a blog post on the subject back in October:

http://chriseppstein.github.com/blog/2009/10/12/css-class-inheritance/

I argued there that the Less syntax gives users the impression that they are using inheritance instead of mixins even though that is not the case. I think this issue backs up those claims.

FYI: There is a PHP-based css compiler that does inheritance this way called xCSS. http://xcss.antpaw.org/

chriseppstein avatar Dec 20 '09 17:12 chriseppstein

Chris,

Great points. I'm not sure what Alexis has in store, but I was under the impression that a class (acting as a mixin) only provides the rules within that pure (not applied to an element) class to whatever mixes it in.

In the 'more complicated' example, I'd expect .foo to only have the 300px width set and nothing more. I'm not sure what standard users would expect, though, so I can't speak for everyone (nor Alexis) regarding this feature. I see your example both convoluted and backwards in terms of what I envisioned for this feature.

That said, I'm a proponent of very basic usage of classes as mixins in that document structure isn't implied and the only rules that get applied when mixing in a class are those of the vanilla selector.

joshuaclayton avatar Dec 21 '09 00:12 joshuaclayton

+1 I can't mix in Blueprint's .span-* classes until this feature is added. (Actually, I can but only if I use an older version (50d160b713f119627c7beaebd35b751bc26c5c0a~1) before it changed a div.span-* selector into a .span-*. Now the .span-* is opened twice.)

TylerRick avatar Jan 28 '10 19:01 TylerRick

So anyupdates on this "issue"? Will it be added as a feature in the soon future?

andriijas avatar Feb 09 '10 15:02 andriijas

I recently implemented this in less.js, which will be stable soon.

http://github.com/cloudhead/less.js

cloudhead avatar Mar 06 '10 23:03 cloudhead

Happy 2011! Can this be closed now? :)

nathanbrauer avatar May 20 '11 17:05 nathanbrauer