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

Can't extend a nested class (concatenated selector) #1597

Open
DennisJohnsen opened this issue Oct 15, 2013 · 21 comments
Open

Can't extend a nested class (concatenated selector) #1597

DennisJohnsen opened this issue Oct 15, 2013 · 21 comments

Comments

@DennisJohnsen
Copy link

Heya guys.

I have found an annoying issue, which is pretty basic use of two mechanics:
I cant extend a class i generate by nesting it using "& {}"

Heres my example:

.box {
    padding: @base-spacing;

    &--large {
        padding: @large-spacing;
    }
}

.foo {
    &:extend(.box--large);
}

Expected result:

.box {
    padding: 24px;
}

.box--large,
.foo {
        padding: 48px;
}

What actually happens:

.box {
    padding: 24px;
}

.box--large {
    padding: 48px;
}

Imo this is very basic use of two mechanics, and it's not like its generated by some kind of wizard looping mixin.
Looking forward to have this fixed :-)

Kind regards, Dennis

@jonschlinkert
Copy link
Contributor

#1539

@jonschlinkert
Copy link
Contributor

#1554

@jonschlinkert
Copy link
Contributor

#1399

@lukeapage
Copy link
Member

although closest to #1539 i don't think it is a duplicate.. same root cause as #1539 though..

.a {
   &b

is treated as .a followed by a b element, with no space between them
.ab is treated as the class ab.. so less thinks they are different.

quite a hard one to solve, though I guess easier to solve than #1539

@lukeapage lukeapage reopened this Oct 15, 2013
@jonschlinkert
Copy link
Contributor

fair enough, I guess if solving one doesn't solve the other then it makes sense to keep both open.

@DennisJohnsen
Copy link
Author

Hello again : - )

I'm just writing to hear if theres some updates regarding this issue.

I have recently forwarded multiple people this issue, regarding to their LESS question about not beeing able to extend nested/generated classes.

Kind regards
Dennis

@Johns3n
Copy link

Johns3n commented Nov 20, 2013

+1

I tried doing the exact same thing:

.top{
    &-first{
        background:black;
        &-item{
            color:white;
        }
    }
    &-second{
        background:green;
        &-item:extend(.top-first-item){}
    }
}

expecting:

.top-first {
    background: black;
}
.top-first-item,
.top-second-item{
    color: white;
}
.top-second {
    background: green;
}

But got instead:

.top-first {
    background: black;
}
.top-first-item{
    color: white;
}
.top-second {
    background: green;
}

Soo +1 for this issue and looking forward to a fix! :)

Original: http://stackoverflow.com/questions/20091264/less-extend-a-previously-defined-nested-selector

@dvdln
Copy link

dvdln commented Dec 21, 2013

A lot of people are into BEM these days...

.block {
  &__elem {
    width: 200;
  }

  &__elem_mod_blue {
    &:extend(.block__elem);
    color: blue;
  }

  &__elem_mod_green {
    &:extend(.block__elem);
    color: green;
  }
}

@lukeapage
Copy link
Member

I guess the easiest way to fix is in the code handling & to change it to combine the value if there are no combinators between the previous value and the next value, then this would work. patches welcome!

@DennisJohnsen
Copy link
Author

Hello again.

Any updates into this? I havn't been following it for some time, but i find my self not beeing able to extend these dynamic classes a abit too often :(

Kind regards,
Dennis

@Johns3n
Copy link

Johns3n commented May 20, 2014

Again a +1 from me! Found myself needing to be able to extend a nested dynamic class the other day :)

.ui{
    &__theme{
        background-image:url(../images/watermark.gif);
        background-position:top left;
        background-attachment:fixed;
        background-repeat:no-repeat;
        &--inverted{
            &:extend(.ui__theme);
            background-image:url(../images/watermark--inverted.gif);
            background-position:top right;
        }
    }

expected:

ui__theme, ui__theme--inverted{
   //shared rules
}
ui__theme--inverted{
 //individual
}

@slantz
Copy link

slantz commented Jul 18, 2014

I've been working on the singlepage project, where each page has it's own less file compiled. Each page has it's own body class, so I can extend concatanated classes and other properties like so:
Let the pages have classes:

<body class="foo-bar-page">
<body class="bar-baz-page">

In my less files i start from not existing classes

.foo-bar {
  &-page {
    min-height:100%;
    #somediv {
      color : red;
    }
    &-holder {
      display : inline-block;
    }
  }  
}

For the other page i can just write:

.bar-baz {
  &:extend(.foo-bar all);
}

And the output will be:

.foo-bar-page,
.bar-baz-page {
  min-height: 100%;
}
.foo-bar-page #somediv,
.bar-baz-page #somediv {
  color: red;
}
.foo-bar-page-holder,
.bar-baz-page-holder {
  display: inline-block;
}

Sure if you need to inherit everything. Less 1.7.0

@jaredly
Copy link

jaredly commented Aug 21, 2014

+1!

@seven-phases-max seven-phases-max changed the title Can't extend a nested class Can't extend a nested class (with "concatenated identifier") Aug 21, 2014
@seven-phases-max seven-phases-max changed the title Can't extend a nested class (with "concatenated identifier") Can't extend a nested class (concatenated identifier) Sep 18, 2014
@seven-phases-max
Copy link
Member

Merging to #2200.

@seven-phases-max seven-phases-max changed the title Can't extend a nested class (concatenated identifier) Can't extend a nested class (concatenated selector) Sep 18, 2014
@guillaume-duchemin
Copy link

Hello, I know it's now into #2200 BUT 5 years without solution is it outdated ??

@matthew-dean
Copy link
Member

@guillaume-duchemin Not out-dated. Marked as up-for-grabs, so anyone can submit a PR for it at anytime.

@rejhgadellaa
Copy link

+1

@kubami19
Copy link

+1

1 similar comment
@acjbizar
Copy link

+1

@matthew-dean
Copy link
Member

matthew-dean commented Sep 19, 2019

In case someone comes here with a case like @Johns3n's example, you can always just convert that to the following to "share" rules between BEM classes:

.ui {
    &__theme {
        background-image:url(../images/watermark.gif);
        background-position:top left;
        &, &--inverted {
            background-attachment:fixed;
            background-repeat:no-repeat;
        }
        &--inverted {
            background-image:url(../images/watermark--inverted.gif);
            background-position:top right;
        }
    }
}

i.e. the key useful "trick" in Less is the &, &[something] { pattern, where you can abstract common rules without using "extend"

@kerryj89
Copy link

kerryj89 commented Apr 16, 2020

This would be a great feature as utility classes become even more popular. I was wanting to remove some utility classes from the markup where the sizing was set in stone. It would've been nice to just drop in &:extend(.padding-left-small); or &:extend(.padding-all-medium-lg-up);. I suppose I could wrap it in a mixin or something? Still, that's not intuitive when we have extends. Thanks for all the work you devs have done, though!

.padding {
  &-left {
    &-small {
        padding-left: @gutter-small !important;
    }
    &-...
  }
  &-...
}

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