-
Notifications
You must be signed in to change notification settings - Fork 47
Less language Nesting
A ruleset can be written inside another ruleset. The compiler then removes the inner ruleset, places it right after the outer ruleset and combines their selectors. This helps to avoid repetition whenever a style sheet contains multiple rulesets with similar selectors. Common part is placed into the outer ruleset while each nested ruleset can add its own part.
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, inner and outer selectors are combined with the descendant combiner:
h1 {
padding: 2 2 2 2;
p {
margin: 3 3 3 3;
}
}
Output:
h1 {
padding: 2 2 2 2;
}
h1 p {
margin: 3 3 3 3;
}
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 arbitrarily 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;
}