2

In Less, I can write:

.outer {  
    .inner {  
        color: red;  
    }  
}

.test {  
    .outer .inner;
}

But when I write:

.outer {  
    &-inner {  
        color: red;  
    }  
}

.test {  
    .outer-inner;
}

When I remove the .test, the .outer-inner output properly, but when I add it back, the compiler says

.outer-inner is undefined.

Is there anyway to re-use the styles of .outer-inner?

Harry
  • 87,580
  • 25
  • 202
  • 214
  • Similar item - http://stackoverflow.com/questions/24879871/how-do-i-extend-a-class-mixin-which-has-dynamically-formed-selector/26450099#26450099 – Harry Oct 25 '14 at 04:37
  • 1
    Thanks for answer me quickly. Now I'm cleared. – Thinh Pham Duy Oct 25 '14 at 06:02
  • 1
    Voting for closing as duplicate though strictly speaking it's not. "dynamically defined selectors" are those defined with "selector interpolation" (thus "dynamic"). Selectors using `.a { &-b {` are "static" so more strict name for them is just "concatenated". In summary: `extend` can't work with both "dynamic" and "concatenated", contrary` mixin stuff *can* work for "dynamic" selectors but can't for "concatenated" ones. – seven-phases-max Oct 25 '14 at 11:29

1 Answers1

2

Calling a mixin whose selector is formed by concatenation is currently not possible with Less. However the same is possible for selectors formed at compilation time using interpolation (also referred to as dynamically formed selectors).

The below (interpolated/dynamically formed selector) would work fine.

@selector: .box;
@{selector}{
    color: red;
    .child{
        color:blue;
    }
}
.demo{
    .box; /* will create both parent & child */
}
.container{
    &.box{
        background: black;
    }
}
.demo2{
    .container.box;
}

whereas, the following example will not work.

.container{
    &-box{
        color: blue;
    }
}
.demo2{
    .container-box; /* this will not work */
}

Currently, one work-around to the scenario in question is to create two separate Less files.

In the first file (test.less) add the below code and compile it into a CSS file.

.outer {  
    &-inner {  
        color: red;  
    }  
}

In the second file, import the CSS created from the first file with the (less) directive and then call/re-use the mixin.

@import (less) "test.css";
.test {  
    .outer-inner;
}

Note: As mentioned in comments by seven-phases-max, this issue is similar to this item. However both these issues are not the same as extend will not work with both interpolated selector (dynamically formed) and concatenated selector.


Option 2: Another option would be to write a dummy mixin or a separate detached ruleset with common properties and make use of it like below.

@dummy: {color: red}; // detached ruleset

.outer{
    &-inner{
        @dummy();
    }
}

.test{
    @dummy();
}

or

.dummy() {color: blue}; // dummy mixin and would produce no extra selector in output as it has parentheses.

.outer{
    &-inner{
        .dummy;
    }
}

.test{
    .dummy;
}
Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214