Skip to content

Nested Directives and Bubbling

LESS allows you to nest CSS at-rules (directives) like @media, @supports, or @keyframes within selectors, similar to how you nest selectors themselves. When LESS compiles these nested directives, they “bubble up” to the top level of the CSS output, wrapping the selectors they originated from. This feature is extremely useful for co-locating styles for a component, including its responsive or conditional variations, within a single block of LESS code.

Let’s demonstrate bubbling with nested @media queries:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nested Directives Example</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div class="component">
<p>This is a responsive component.</p>
<button class="component-button">Click Me</button>
</div>
</body>
</html>
.component {
width: 90%;
margin: 20px auto;
padding: 15px;
background-color: #f0f0f0;
p {
color: #333;
font-size: 16px;
}
// Nested @media query for medium screens
@media screen and (min-width: 768px) {
width: 700px;
padding: 25px;
p {
font-size: 18px;
}
// Further nested @media query for high resolution on medium screens
@media (min-resolution: 192dpi) {
p {
text-shadow: 1px 1px 0px rgba(0,0,0,0.1);
}
}
}
.component-button {
background-color: blue;
color: white;
padding: 10px 15px;
border: none;
// Nested @supports directive
@supports (display: grid) {
display: inline-grid; // Applied if browser supports grid
gap: 5px;
}
}
}

Compile style.less to style.css using: lessc style.less style.css

.component {
width: 90%;
margin: 20px auto;
padding: 15px;
background-color: #f0f0f0;
}
.component p {
color: #333;
font-size: 16px;
}
/* Bubbled @media query */
@media screen and (min-width: 768px) {
.component {
width: 700px;
padding: 25px;
}
.component p {
font-size: 18px;
}
}
/* Bubbled nested @media query (combines with parent @media) */
@media screen and (min-width: 768px) and (min-resolution: 192dpi) {
.component p {
text-shadow: 1px 1px 0px rgba(0, 0, 0, 0.1);
}
}
.component .component-button {
background-color: blue;
color: white;
padding: 10px 15px;
border: none;
}
/* Bubbled @supports directive */
@supports (display: grid) {
.component .component-button {
display: inline-grid;
gap: 5px;
}
}
  • The @media screen and (min-width: 768px) directive, originally nested inside .component, has bubbled up. It now wraps the .component and .component p selectors with their respective styles for that breakpoint.
  • The deeper nested @media (min-resolution: 192dpi) also bubbles up. LESS intelligently combines it with its parent @media query, resulting in @media screen and (min-width: 768px) and (min-resolution: 192dpi) { ... }.
  • Similarly, the @supports (display: grid) directive nested within .component-button bubbles up, wrapping the .component .component-button selector.
  • Other directives like @document (less common) or @keyframes also exhibit this bubbling behavior. For @keyframes, the entire animation definition bubbles to the top level.
  • Co-location of Styles: Keeps all styles related to a component, including its responsive and feature-query variations, in one place in your LESS files, improving organization and readability.
  • Contextual Styling: Makes it easier to understand how a component behaves under different conditions without searching through separate @media blocks.
  • Reduced Repetition: Avoids repeating parent selectors within multiple top-level @media blocks.

Bubbling is a powerful feature for writing organized and maintainable responsive stylesheets. It’s important to understand how directives are combined (especially multiple @media queries) to predict the final CSS output accurately.