-
Notifications
You must be signed in to change notification settings - Fork 47
Less Language Detached Rulesets
Detached ruleset is a group of css properties, nested rulestes, media declarations or anything else stored in a variable. You can include it into a ruleset or another structure and all its properties are going to be copied there. You can also use it as a mixin argument and pass it around as any other variable.
Simple example:
// declare detached ruleset
@detached-ruleset: { background: red; };
// use detached ruleset
.top {
@detached-ruleset();
}
compiles into:
.top {
background: red;
}
Parentheses after detached ruleset call are mandatory. The @detached-ruleset;
call would NOT work.
Detached ruleset can contain everything an ordinary ruleset can: properties, nested rulesets, media declarations, variables declarations, mixins, etc. Variables and mixins defined inside mixins act as return values and are usable in caller.
All returned mixins are copied into caller as if they were defined there. Returned variables are copied too, but only if the callers scope does not contain variable with the same name. Variables already present in callers scope are not going to be rewritten.
BEWARE: variables returned from detached rulesets behave slightly differently then variables returned from mixins. Variables returned from detached rulesets protect whole callers scope. The variable defined in local scope is protected exactly the same way as the variable defined in its parent scope. Variables returned from mixin protect only local scope.
Media inside detached ruleset:
// detached ruleset with nested media
@detached-ruleset: {
@media print {
.nested-ruleset {
color: blue;
}
}
};
// call detached ruleset
.caller {
@detached-ruleset(); // use detached ruleset
}
compiles into:
@media print {
.caller .nested-ruleset {
color: blue;
}
}
Detached ruleset copies all its mixins into caller:
// detached ruleset with nested media
@detached-ruleset: {
.mixin() {
color:blue;
}
};
// call detached ruleset
.caller {
@detached-ruleset();
.mixin();
}
compiled css:
.caller {
color: blue;
}
It does NOT return variables, following results in an error:
detached-ruleset: {
@color:blue; //this variable is private
};
.caller {
color: @color; //syntax error
}
Detached ruleset can be used as mixin argument. Next mixin wraps its argument into media declarations:
//mixin assumes that @rules parameter contains detached ruleset
.big-screen-exception(@rules) {
@media screen and (min-width: 1200) {
//use detached ruleset from parameter
@rules();
}
}
.caller {
color: red;
//detached ruleset is sent as parameter
.big-screen-exception({ color:blue a; });
}
compiles into:
.caller {
color: red;
}
@media screen and (min-width: 1200) {
.caller {
color: blue a;
}
}
Note: detached ruleset can not be used as parameter default. This limitation is present only in less.js, less4j supports it. Following is NOT allowed in less.js:
.mixin(@parameter: {default: default;}) { // syntax error: detached ruleset as default value
@parameter();
}
Scoping of detached rulesets is almost the same as mixins scoping. Detached ruleset can use all variables and mixins accessible on place where it is defined and where it is called. Otherwise said, both definition and caller scopes are available to it. If both scopes contains the same variable or mixin, declaration scope value takes precedence.
Detached mixin sees callers variables and mixins:
@detached-ruleset: {
caller-variable: @callerVariable;
.callerMixin();
};
selector {
@detached-ruleset();
//define variable and mixin
@callerVariable: value;
.callerMixin() {
variable: declaration;
}
}
compiles into:
selector {
caller-variable: value;
variable: declaration;
}
Variable and mixins accessible form definition win over those available in caller:
@variable: global;
@detached-ruleset: {
//will use global variable, because it is accessible
//from detached-ruleset definition
variable: @variable;
};
selector {
@detached-ruleset();
@variable: value; //variable defined in caller - will be ignored
}
compiles into:
selector {
variable: global;
}