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

Class selectors in nested rules

Open jankrcal opened this issue 14 years ago • 37 comments

I want to set rules for A, A:hover, A.highlighted and A *.child-element. It all relates to A so it makes sense to write it all inside a nested rule as follows

A {
    color: blue;
    :hover {
        color: black;
     }
    .highlighted {
        color: red;
    }
    *.child-element {
        color: gray;
    }
}

But this gets compiled into ... A .highlighted {color: red;} A *.child-element {color: gray;}

I propose that any nested selector without the name specified (e.g. .class-name, :pseudo-class, [attribute="value"]) relates to the parent element. At the moment, this feature works for pseudo classes but not for other selectors.

I know this proposal has one major flaw - it is not backward compatible. The backward compatible but IMHO uglier alternative is to introduce a special name selector that refers to the parent. E.g. self or $. So one would have to write self.highlighted or $.highlighted.

What you think?

jankrcal avatar Oct 27 '09 12:10 jankrcal

I must agree with that. Let's look to this code.:

A {
    :hover { color: black; }
    .highlighted { color: red; }
}

compiled:

A:hover { color: black; }
A .highlighted { color: red; }

In first case there is no space, but what if a want (theoreticly) this?

A :hover { color: black; }

Well there is no chance - but i can use *:hover. - OK but the difference with space between .class and :pseudo-class is not logical. And I never can get something like this using mixin for A

A:hover { color: black; }
A.highlighted { color: red; } //without space

I think that because of incompatibility this should be changed in new major version - LESS 2.0. But I vote for this solution.:

A {
    :hover { color: black; }
    .highlighted { color: red; }
}

compiled to

A :hover { color: black; }
A .highlighted { color: red; }

and

A {
    $:hover { color: black; }
    $.highlighted { color: red; }
}

compiled to

A:hover { color: black; }
A.highlighted { color: red; }

The first case is used much more often - that's why I suggest this.

jtousek avatar Oct 27 '09 13:10 jtousek

.foo.bar is the same thing as .bar.foo, for that reason, it doesn't make as much sense to nest either. pseudo classes like :hover don't work that way.

cloudhead avatar Nov 19 '09 17:11 cloudhead

I don't get your point. Isn't .foo:hover the same as :hover.foo?

The reason for me is the clarity and elegance of the code. With my proposal, one can place all rules concerning one element into one block.

jankrcal avatar Nov 19 '09 18:11 jankrcal

clouhead: Yes of course, but what about this?

#header{
//global settings for page header
$.page1{
//special settings for page 1
}
$.page2{
//special settings for page 2
}
}

Now I have to write this:

#header{
//global settings for page header
}
#header.page1{
//special settings for page 1
}
#header.page2{
//special settings for page 2
}

I think you should agree that in this case the old way is not good enough.

jtousek avatar Nov 19 '09 19:11 jtousek

Ok, you convinced me : )

I'm thinking of something like this for the syntax: .foo { `.bar {...} // .foo.bar .baz {...} // .foo .baz }

any objections? (it's a backtick) pseudo-classes won't change for now though, as that would break things, you can still have it both ways by doing *:hover {...}

cloudhead avatar Nov 19 '09 20:11 cloudhead

well I really don't like backtick (`), I'd prefere $ or \ or &... about pseoudo-classes and pseudo-elements I agree

jtousek avatar Nov 19 '09 20:11 jtousek

great :)

what about <? As a kind of opposite of the direct ancestor concatenator. But I don't mind if it is the backtick.

jankrcal avatar Nov 19 '09 20:11 jankrcal

Example:

DIV {
    <.class1 {...}
    <.class2 {...}
}

jankrcal avatar Nov 19 '09 20:11 jankrcal

I'm still against backtick. :) But I'm ok with < idea (of course $ is prefered). Let's wait for cloudhead's opinion.

jtousek avatar Nov 19 '09 20:11 jtousek

&.class

+ same as Sass

  • quite noisy
<.class

+ could make sense as an opposit to >

  • looks a little funny (nothing like it in any other language)
$.class

+ $ is unique enough

  • no obvious logic behind it, a little noisy
`.class

+ very discreet

  • people don't like backticks

cloudhead avatar Nov 21 '09 04:11 cloudhead

I agree but people have to get used to it no matter which one it'll be. Another option might be %. Well one has to be chosen and imho $ is still the best choice even if it was not originaly my but jankrcal's idea. Obvious logic isn't behind any of them (not only $ - maybe except <). Backtick in any code looks just like some wierd char which should be deleted. ;)

jtousek avatar Nov 21 '09 07:11 jtousek

Ampersand. For serious. Please. With a cherry on top. I'm confused enough as it is switching back and forth between SASS and LESS.

thisisfranciswu avatar Nov 23 '09 21:11 thisisfranciswu

considered that, I guess & is the best after all, it is good if it's similar to SASS (even if I have no experience with it)

jtousek avatar Nov 23 '09 21:11 jtousek

I vote for & or $. & would be nice because it's like in SASS, and $ would rock, just because it's $.

DouweM avatar Nov 30 '09 16:11 DouweM

This is great. The inconsistency between pseudo-elements and other simple-selectors (like attribute selectors) has always bugged me.

I like the backticks. They aren't as visually noisy as the other characters.

jeremyh avatar Dec 03 '09 11:12 jeremyh

I've removed the paragraph. In hindsight it wasn't worth mentioning.

jeremyh avatar Dec 03 '09 21:12 jeremyh

< feels the most intuitive for referencing the parent element. For people familiar with CSS and unfamiliar with LESS, they're going to think of < as the opposite of the child selector.

tatey avatar Dec 14 '09 10:12 tatey

Agreed. I think it is between < and & now. Cloudhead?

jtousek avatar Dec 14 '09 10:12 jtousek

I vote for &, as it functions more as a this or self selector than a parent selector... So < wouldn't actually be the opposite of the > selector.

DouweM avatar Dec 14 '09 14:12 DouweM

& it is!

The thing to remember is .a { &.b {...} } is the same as .b { &.a {...} } so it's more of an 'append' than simply a reference to the parent selector. I liked the backticks, but they aren't that obvious, and should probably be kept for quoting things.

cloudhead avatar Dec 14 '09 17:12 cloudhead

Yeah, but .a { ... &.b { ... } } isn't the same as .b { ... &.a { ... } } ;-) But I get what you mean :-)

(Will .a { &:hover { ... } } also be available next to the original .a { :hover { ... } }?)

DouweM avatar Dec 14 '09 17:12 DouweM

Yea, &:hover should behave the same as :hover. If you want the equivalent of a :hover, you can use *:hover

cloudhead avatar Dec 14 '09 17:12 cloudhead

Ok :-) And is it already in 1.2.20?

DouweM avatar Dec 14 '09 17:12 DouweM

great! :) btw. cloudhead, is there some kind of change log? there are lot of issues reported here but I don't know what is already implemented/fixed and what is still waiting...

jtousek avatar Dec 14 '09 18:12 jtousek

@Douwe: I haven't implemented this yet, no : )

@jtousek: if the issue is still open here, then it's not fixed/implemented. The most accurate changelog would probably be the commit history, although that can be hard to follow — I don't really have the patience/time to maintain a separate one...

cloudhead avatar Dec 14 '09 19:12 cloudhead

cloudhead: Yeah, just as I thought... :-D

jtousek avatar Dec 14 '09 19:12 jtousek

Any ETA on a fix for this?

wmdmark avatar Jan 24 '10 20:01 wmdmark

Just signed up to thank you for your fantastic work... and to note that this missing feature is what prevents me from using less :(

protyposis avatar Jan 25 '10 12:01 protyposis

Anything?

DouweM avatar Jan 25 '10 15:01 DouweM

Well what prevents me from using less is this thing along with "filter: ..." incompatibility... I'm looking forward for finishing these issues.

jtousek avatar Jan 25 '10 15:01 jtousek