-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Parent selectors not working within mixins using (reference) #1979
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
Comments
Same here. If the mixin.less is something like this works: .mixin-test() {
.test {
color: red;
}
.test:first-child {
color: blue;
}
} So the point is in reference import only the first level nested rules are used. It goes no deeper than that. Another example: less code: #hola {
display: block;
background-color: red;
height: 30em;
& > div {
height: 20em;
width: 80%;
background-color: white;
& > div {
height: 10em;
width: 80%;
background-color: green;
}
}
} html code: <div id="hola">
<div>
<div></div>
</div>
</div> You'll only see two of the three divs. |
@aonez Could you elaborate what your second example has to do with |
Sure, sorry I copy-pasted some code and now it does lack some meaning: Take a common.less file: .hola {
display: block;
background-color: red;
height: 30em;
& > div {
height: 20em;
width: 80%;
background-color: white;
& > div {
height: 10em;
width: 80%;
background-color: green;
}
}
} Take a someName.less file that imports common.less and uses its classes: @import 'common';
#hola
{
.hola;
} The html page is the same as in my first comment, and will be using the someName.less file: <link rel="stylesheet/less" type="text/css" href="someName.less"/>
<script type="text/javascript" src="less.min.js"></script>
<div id="hola">
<div>
<div></div>
</div>
</div> The css output, just using plain import is the expected: .hola {
display: block;
background-color: red;
height: 30em;
}
.hola > div {
height: 20em;
width: 80%;
background-color: white;
}
.hola > div > div {
height: 10em;
width: 80%;
background-color: green;
}
#hola {
display: block;
background-color: red;
height: 30em;
}
#hola > div {
height: 20em;
width: 80%;
background-color: white;
}
#hola > div > div {
height: 10em;
width: 80%;
background-color: green;
} Oviously we only need the #hola part in this case, so common.less must be imported using reference: @import (reference) 'common';
#hola
{
.hola;
} The new ouput: #hola {
display: block;
background-color: red;
height: 30em;
}
#hola > div {
height: 20em;
width: 80%;
background-color: white;
} As you can see, it lacks any nested rule but the first level. In that case, the code should be: #hola {
display: block;
background-color: red;
height: 30em;
}
#hola > div {
height: 20em;
width: 80%;
background-color: white;
}
#hola > div > div {
height: 10em;
width: 80%;
background-color: green;
} It lacks the third div properties: #hola > div > div {
height: 10em;
width: 80%;
background-color: green;
} Hope this helps 😄 |
I see, thanks. So the second example is just more verbose variant of the original snippet. |
You mean it's useless for you? |
I just add a sort-of self-note to save some time when reading this issue in future... (well, honestly, yes, it's sort of useless then since it adds nothing new). |
The point is that reference ignores third level and up nested rules, not rules with parent selectors as the tittle of this ticket says. |
But all examples here use parent selector... (i.e.
which btw. is equal style ( |
We use Modernizr classes in our build - here's an example of our justify-align hack: .justify(@flex: true) {
line-height: inherit;
width: 100%;
.__hack() { // named for the technique, not related to the bug
font-size: 0.1px;
text-align: justify;
&::after {
content: '';
display: inline-block;
height: 0;
width: inherit;
}
}
.flexbox & when (@flex = true) {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.no-flexbox & when (@flex = true) {
.__hack();
}
& when (@flex = false) {
.__hack();
}
} ._justify { .justify(); } // intended for extending the default result @import (reference) "justify"; // prevents the ._justify class from being output
.box {
.justify();
} Expected output: .box {
line-height: inherit;
width: 100%;
}
.flexbox .box {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.no-flexbox .box {
font-size: 0.1px;
text-align: justify;
}
.no-flexbox .box::after {
content: '';
display: inline-block;
width: 100%;
} Actual output: .box {
line-height: inherit;
width: 100%;
}
.flexbox .box {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.no-flexbox .box {
font-size: 0.1px;
text-align: justify;
} The key is that the The only working solution would be to change the mixin and reduce the nesting, like so: .justify(@flex: true) {
line-height: inherit;
width: 100%;
.__hack() {
font-size: 0.1px;
text-align: justify;
}
.__hack-after() { // move the ::after to its own mixin, to reduce duplication I guess
content: '';
display: inline-block;
height: 0;
width: inherit;
}
.flexbox & when (@flex = true) {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.no-flexbox & when (@flex = true) {
.__hack();
}
.no-flexbox &::after when (@flex = true) {
.__hack-after();
}
& when (@flex = false) {
.__hack();
}
&::after when (@flex = false) {
.__hack-after();
}
} ._justify { .justify(true); } |
I think I incidentally fixed this by #2410 . So I will just add unit test for this into that one. |
Name: Parent selectors not working within mixins using (reference) Number: less#1979
Having on mixin.less
And main.less
It Outputs:
but if I remove the (reference) it prints
lessc 1.7.0 (LESS Compiler) [JavaScript]
Not sure if it's related to: #1851
The text was updated successfully, but these errors were encountered: