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
Why Doesn't Min() (Or Max()) Work with Unitless 0
Using Two CSS Classes on One Element
How to Control Number of Items Per Row Using Media Queries in Flexbox
Position:Relative Leaves an Empty Space
Responsive Clip-Path with Inline Svg
Hide Scrollable Content Behind Transparent Fixed Position Divs When Scrolling the Page
Why Are Spaces Used to Separate Things in CSS
What Are the Rules Around Whitespace in Attribute Selectors
Prevent Children from Inheriting Transformation CSS3
Why Can't Child Elements Override the Opacity of Parent with a Greater Value
Media Query Grouping Instead of Multiple Scattered Media Queries That Match
Generate Random Number in Less CSS
CSS - Shrink a Parent Div to Fit One Child's Width and Constrain the Width of the Other Child