Does Less Have an "Extend" Feature

Does LESS have an extend feature?

Yes, Less.js introduced extend in v1.4.0.

:extend()

Rather than implementing the at-rule (@extend) syntax used by SASS and Stylus, LESS implemented the pseudo-class syntax, which gives LESS's implementation the flexibility to be applied either directly to a selector itself, or inside a statement. So both of these will work:

.sidenav:extend(.nav) {...}

or

.sidenav {
&:extend(.nav);
...
}

Additionally, you can use the all directive to extend "nested" classes as well:

.sidenav:extend(.nav all){};

And you can add a comma-separated list of classes you wish to extend:

.global-nav {
&:extend(.navbar, .nav all, .navbar-fixed-top all, .navbar-inverse);
height: 70px;
}

When extending nested selectors you should notice the differences:

nested selectors .selector1 and selector2:

.selector1 {
property1: a;
.selector2 {
property2: b;
}
}

Now .selector3:extend(.selector1 .selector2){}; outputs:

.selector1 {
property1: a;
}
.selector1 .selector2,
.selector3 {
property2: b;
}

, .selector3:extend(.selector1 all){}; outputs:

.selector1,
.selector3 {
property1: a;
}
.selector1 .selector2,
.selector3 .selector2 {
property2: b;
}

,.selector3:extend(.selector2){}; outputs

.selector1 {
property1: a;
}
.selector1 .selector2 {
property2: b;
}

and finally .selector3:extend(.selector2 all){};:

.selector1 {
property1: a;
}
.selector1 .selector2,
.selector1 .selector3 {
property2: b;
}

LESS: Extend a previously defined nested selector

LESS currently does not support extending a "concatenated name" selectors (basically, .top &-first &-item is interpreted as three distinct selector elements and never found by extend looking for a single selector).

A workaround for your particular case:

.top {
&-first {
background: black;
}

&-second {
background: green;
}

&-first, &-second {
&-item {
color: white;
}
}
}

LESS CSS Extend function not working as expected

This is a very weird kind of behavior and currently I don't have an explanation as to why it works this way but there is a workaround. It seems to work if we use the parent selector (&) at all levels before the actual nested selector (except the inner-most one).

Considering for how long the :extend() feature has existed and how common this scenario seems to be, it could possibly be an intended feature. I will add more explanation about the reason once I've managed to find it :)

.h3-text{
color: #424242;
font-size: 20px;
line-height: 28px;
}
#how-it-works {
& .timeline {
& > .timeline-step {
& > h3:extend(.h3-text) {};
}
}
}

Another approach that also seems to work is to avoid the & (parent selector) at all levels. It shouldn't be a big problem for this particular scenario because the & is basically doing nothing.

.h3-text{
color: #424242;
font-size: 20px;
line-height: 28px;
}
#how-it-works {
.timeline {
> .timeline-step {
> h3:extend(.h3-text) {};
}
}
}

Even :extend inside a ruleset works. Seems like the problem happens when :extend attached to a selector is used and the selector has & only at some levels.

.h3-text{
color: #424242;
font-size: 20px;
line-height: 28px;
}
#how-it-works {
.timeline {
& > .timeline-step {
& > h3 {
&:extend(.h3-text);
}
}
}
}

LESS extend() not working

When we simply import a CSS file with the .css extension it will be treated as CSS and the @import statement left as-is.

For the extend feature to work, Less compiler has to interpret the imported file as a Less file. This can be done in two ways and they are as follows:

Option 1: (Using the (reference) directive)

Using the (reference) directive, allows for pulling in only the targeted/referenced styles from the external bootstrap library. Hence, it would result in a smaller file and is preferred when you are going to reference only few styles from a large library (like bootstrap). Note that this directive was introduced only with Less v1.5.0 and hence will not work in lower compiler versions.

@import (reference) 'less/bootstrap.less';

.filters {
.type {
button.selected:extend(.btn-success) {};
}
}

Option 2: (Using the (less) directive)

When the (less) directive is used, the Less compiler would treat the code present within the imported file as Less code (irrespective of the file extension) and hence would allow extending any rule-sets/classes specified within it. However, the drawback of using this directive is that the entire contents of the .css file (including classes that you may not require in the output file) will be copied to the output. This was introduced in Less v1.4.0.

@import (less) 'bootstrap.css';

.filters {
.type {
button.selected:extend(.btn-success) {};
}
}

extend parent and children nested selectors in less

The issue with parentChildProperty not being applied to the ul element can be fixed by also extending .parent-class .child-class in the ul styles

This will not resolve all the issues. It will still leave many unnecessary selectors in the generated CSS, but it will generate the required CSS to allow the page to display correctly.

Updated less:

.parent-class{
parentProperty: value;
.child-class { parentChildProperty: value; }
}

.child-class {
childProperty:value;
& > li{ childLiProperty:value; }
}

nav{
&:extend(.parent-class all);
ul{
&:extend(.child-class all);
&:extend(.parent-class .child-class);
}
}

use variables on mixin or extend in Less.js

You are trying to call a mixin using selector interpolation, which is not possible.

As for extend, Less documentation states it clearly:

Extend is NOT able to match selectors with variables. If selector contains variable, extend will ignore it.



Related Topics



Leave a reply



Submit