-
Notifications
You must be signed in to change notification settings - Fork 47
Less language Nesting
A ruleset can be nested into another ruleset. Nested rulesets make no difference to the outer ruleset, it will be compiled the same way as usually.
Selectors of the nested ruleset are combined with outer selectors. This helps to avoid repetition whenever style sheet contains multiple rulesets with similar selectors. Common part is placed into the outer ruleset while each nested ruleset can add its own parts.
Nested ruleset can use all variables and mixins defined in the outer one, but it will not contain outer selector css properties.
Unless specified otherwise, all nested selectors are considered to be descendants of all outer selectors:
h1, h2 {
padding: 2 2 2 2;
:nested, p {
margin: 3 3 3 3;
}
}
Output:
h1, h2 {
padding: 2 2 2 2;
}
h1 :nested, h2 :nested, h1 p, h2 p {
margin: 3 3 3 3;
}
Nested ruleset can use all variables and mixins defined inside the outer one:
@scope: 1;
h1, h2 {
scope: @scope;
:nested, p {
scope: @scope;
}
@scope: 2;
}
Output:
h1, h2 {
padding: 2;
}
h1 :nested, h2 :nested, h1 p, h2 p {
margin: 2;
}
Prefix nested selector by and css combiner to override default "descendant" behavior:
h1, h2 {
padding: 2 2 2 2;
+ :nested, >p {
margin: 3 3 3 3;
}
}
Output:
h1, h2 {
padding: 2 2 2 2;
}
h1 + :nested, h2 + :nested, h1 > p, h2 > p {
margin: 3 3 3 3;
}
Use appender &
to override the default "outer selector comes first" behavior. Appender can be placed anywhere inside the nested selector and each nested selector can contain multiple appenders. The compilation replaces it with all outer selectors. Both combinators and whitespaces before and after the appender are respected.
Appender is replaced by all outer selectors:
:first, :second {
padding: 2 2 2 2;
h1&:hover, h2 & :visit {
margin: 3 3 3 3;
}
}
Output:
:first,
:second {
padding: 2 2 2 2;
}
h1:first:hover,
h1:second:hover,
h2 :first :visit,
h2 :second :visit {
margin: 3 3 3 3;
}
Multiple appenders generate all combinations of outer selectors:
:first, :second {
padding: 2 2 2 2;
h1&:hover& {
margin: 3 3 3 3;
}
}
Output:
:first,
:second {
padding: 2 2 2 2;
}
h1:first:hover:first,
h1:first:hover:second,
h1:second:hover:first,
h1:second:hover:second {
margin: 3 3 3 3;
}
Nested rules can go arbitrary deep:
h1 {
padding: 2 2 2 2;
p {
margin: 3 3 3 3;
&:hover {
width: 2;
}
}
}
Output:
h1 {
padding: 2 2 2 2;
}
h1 p {
margin: 3 3 3 3;
}
h1 p:hover {
width: 2;
}
Both combinators and whitespaces before and after the appender are respected:
h1, h2 {
padding: 2 2 2 2;
&:direct, & + :child, & :descendant {
margin: 3 3 3 3;
}
}
:first, :second {
padding: 2 2 2 2;
descendant &, child + &, direct& {
margin: 3 3 3 3;
}
}
Output:
h1, h2 {
padding: 2 2 2 2;
}
h1:direct, h2:direct,
h1 + :child, h2 + :child,
h1 :descendant, h2 :descendant {
margin: 3 3 3 3;
}
:first, :second {
padding: 2 2 2 2;
}
descendant :first, descendant :second,
child + :first, child + :second,
direct:first, direct:second {
margin: 3 3 3 3;
}
In case of conflict, the inner selector combinator wins:
> h1 {
name + & {
declaration: 1 2;
}
}
Output:
name + h1 {
declaration: 1 2;
}