Less - Scope
LESS - Understanding Scope
Section titled “LESS - Understanding Scope”Description
Section titled “Description”Scope in LESS refers to the visibility and accessibility of variables and mixins. LESS uses lexical (or static) scoping, meaning that variables and mixins are resolved based on where they are defined in the code structure. When LESS encounters a variable, it first looks for it in the current, local scope. If not found, it progressively searches in parent scopes, up to the global scope.
A unique aspect of LESS variable scoping is often described as “lazy evaluation” or, more accurately, “last declaration wins within the same or accessible parent scope.” This means that the value of a variable is determined by its last definition encountered before or during the parsing of the block that uses it, within the accessible scopes. This allows for flexibility in defining variables, even after their first usage within the same block or in an imported file.
Example
Section titled “Example”The following example demonstrates how variable scope and the “last declaration wins” principle work in LESS:
index.html:
Section titled “index.html:”<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>LESS Scope Example</title> <link rel="stylesheet" type="text/css" href="style.css" /></head><body> <header> <h1>Scope Demonstration</h1> </header> <div class="content-block"> <p class="main-text">This text uses a font size defined by a variable.</p> <div class="inner-block"> <p>This inner text might have a different style.</p> </div> </div></body></html>style.less:
Section titled “style.less:”// Global scope@base-color: #333;@default-padding: 10px;
header { @header-color: blue; // Local to header color: @header-color; padding: @default-padding; // Uses global @default-padding}
.content-block { @block-padding: 15px; // Local to .content-block padding: @block-padding; color: @base-color; // Uses global @base-color
.main-text { // LESS 'lazy evaluation' demonstration: // @font-size is used before its final definition within this scope. font-size: @dynamic-size; @temp-size: 14px; @dynamic-size: @temp-size + 2px; // First definition: 14px + 2px = 16px }
// Re-definition of @dynamic-size within the same .content-block scope // This will be the value used by .main-text because it's the last declaration encountered // before the .content-block scope fully resolves. @another-var: 10px; @dynamic-size: @another-var + 8px; // Last definition: 10px + 8px = 18px
.inner-block { @block-padding: 5px; // Local to .inner-block, shadows .content-block's @block-padding padding: @block-padding; background-color: lighten(@base-color, 80%); font-size: @dynamic-size; // Uses the @dynamic-size from .content-block (18px) }}Compile style.less to style.css using: lessc style.less style.css
Compiled style.css:
Section titled “Compiled style.css:”/* Global scope styles */header { color: blue; padding: 10px;}.content-block { padding: 15px; color: #333;}.content-block .main-text { font-size: 18px; /* Used the last definition of @dynamic-size from .content-block */}.content-block .inner-block { padding: 5px; background-color: #cccccc; font-size: 18px; /* Also uses the 18px @dynamic-size from .content-block */}Explanation of Scope Behavior:
Section titled “Explanation of Scope Behavior:”- Lexical Scoping: Variables like
@header-colorare local toheader.@block-paddingdefined in.inner-blockshadows the one in.content-blockonly within.inner-block. - Global Scope:
@base-colorand@default-paddingare global and accessible everywhere unless shadowed locally. - Last Declaration Wins (within accessible scope): In
.content-block,@dynamic-sizeis used by.main-text. Even though an initial calculation for@dynamic-size(16px) occurs before its use, the final definition of@dynamic-size(18px) within the.content-blockscope is what gets compiled. This is because LESS processes all variable declarations within a scope before outputting rules for that scope. - Nested Scopes:
.inner-blockcan access@dynamic-sizefrom its parent (.content-block) because it doesn’t define its own@dynamic-size.
Understanding variable scope is essential for writing predictable and maintainable LESS. The “last declaration wins” rule offers flexibility but should be used carefully to avoid confusion in complex stylesheets. Organizing variables logically (e.g., in a dedicated _variables.less file imported at the top) is a common best practice.