Less 嵌套 #

嵌套是 Less 最直观的特性之一,它允许你按照 HTML 结构的层次关系来编写 CSS,使代码更加清晰易读。

基本嵌套 #

选择器嵌套 #

Less 允许将选择器嵌套在另一个选择器内部:

less
.nav {
  ul {
    list-style: none;
  }
  
  li {
    display: inline-block;
  }
  
  a {
    text-decoration: none;
    color: #333;
  }
}

编译结果:

css
.nav ul {
  list-style: none;
}
.nav li {
  display: inline-block;
}
.nav a {
  text-decoration: none;
  color: #333;
}

对比传统 CSS #

css
/* 传统 CSS */
.nav ul { list-style: none; }
.nav li { display: inline-block; }
.nav a { text-decoration: none; color: #333; }
.nav a:hover { color: #007bff; }
.nav a.active { font-weight: bold; }
less
// Less 嵌套
.nav {
  ul { list-style: none; }
  li { display: inline-block; }
  
  a {
    text-decoration: none;
    color: #333;
    
    &:hover { color: #007bff; }
    &.active { font-weight: bold; }
  }
}

父选择器 #

使用 & 符号引用父选择器:

基本用法 #

less
.button {
  color: #333;
  
  &:hover {
    color: #007bff;
  }
  
  &:active {
    color: #0056b3;
  }
  
  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
}

编译结果:

css
.button {
  color: #333;
}
.button:hover {
  color: #007bff;
}
.button:active {
  color: #0056b3;
}
.button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

伪元素 #

less
.clearfix {
  &::before,
  &::after {
    content: "";
    display: table;
  }
  
  &::after {
    clear: both;
  }
}

编译结果:

css
.clearfix::before,
.clearfix::after {
  content: "";
  display: table;
}
.clearfix::after {
  clear: both;
}

类名组合 #

less
.button {
  &-primary {
    background: #007bff;
    color: white;
  }
  
  &-secondary {
    background: #6c757d;
    color: white;
  }
  
  &-danger {
    background: #dc3545;
    color: white;
  }
  
  &-sm {
    padding: 4px 8px;
    font-size: 12px;
  }
  
  &-lg {
    padding: 12px 24px;
    font-size: 18px;
  }
}

编译结果:

css
.button-primary {
  background: #007bff;
  color: white;
}
.button-secondary {
  background: #6c757d;
  color: white;
}
.button-danger {
  background: #dc3545;
  color: white;
}
.button-sm {
  padding: 4px 8px;
  font-size: 12px;
}
.button-lg {
  padding: 12px 24px;
  font-size: 18px;
}

父选择器在后 #

less
.header {
  .sidebar & {
    background: #f5f5f5;
  }
}

编译结果:

css
.sidebar .header {
  background: #f5f5f5;
}

多级父选择器 #

less
.grand {
  .parent {
    & > & {
      color: red;
    }
    
    & & {
      color: green;
    }
    
    && {
      color: blue;
    }
  }
}

编译结果:

css
.grand .parent > .grand .parent {
  color: red;
}
.grand .parent .grand .parent {
  color: green;
}
.grand .parent.grand .parent {
  color: blue;
}

嵌套规则 #

属性嵌套 #

Less 不支持 Sass 的属性嵌套语法,但可以通过变量实现类似效果:

less
@border-prefix: border;

.box {
  @{border-prefix}: 1px solid #ccc;
  @{border-prefix}-radius: 4px;
  @{border-prefix}-color: #007bff;
}

媒体查询嵌套 #

less
.container {
  width: 100%;
  
  @media (min-width: 768px) {
    width: 750px;
  }
  
  @media (min-width: 992px) {
    width: 970px;
  }
  
  @media (min-width: 1200px) {
    width: 1170px;
  }
}

编译结果:

css
.container {
  width: 100%;
}
@media (min-width: 768px) {
  .container {
    width: 750px;
  }
}
@media (min-width: 992px) {
  .container {
    width: 970px;
  }
}
@media (min-width: 1200px) {
  .container {
    width: 1170px;
  }
}

使用变量的媒体查询 #

less
@breakpoint-sm: 576px;
@breakpoint-md: 768px;
@breakpoint-lg: 992px;
@breakpoint-xl: 1200px;

.container {
  width: 100%;
  
  @media (min-width: @breakpoint-md) {
    width: 750px;
  }
  
  @media (min-width: @breakpoint-lg) {
    width: 970px;
  }
}

嵌套深度 #

避免过度嵌套 #

less
// 不推荐:嵌套过深
.page {
  .header {
    .nav {
      .list {
        .item {
          .link {
            color: #333;
          }
        }
      }
    }
  }
}

编译结果:

css
.page .header .nav .list .item .link {
  color: #333;
}

推荐做法 #

less
// 推荐:使用 BEM 或扁平化命名
.page {
  // 直接引用子组件
  .nav-link {
    color: #333;
  }
}

// 或使用父选择器
.nav {
  &-link {
    color: #333;
  }
}

嵌套与 @ 规则 #

@keyframes 嵌套 #

less
.fade {
  animation: fade-in 0.3s ease;
  
  @keyframes fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
  }
}

编译结果:

css
.fade {
  animation: fade-in 0.3s ease;
}
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@supports 嵌套 #

less
.flexbox {
  display: block;
  
  @supports (display: flex) {
    display: flex;
  }
}

编译结果:

css
.flexbox {
  display: block;
}
@supports (display: flex) {
  .flexbox {
    display: flex;
  }
}

实用示例 #

卡片组件 #

less
.card {
  border: 1px solid #ddd;
  border-radius: 8px;
  overflow: hidden;
  
  &-header {
    padding: 16px;
    background: #f5f5f5;
    border-bottom: 1px solid #ddd;
  }
  
  &-body {
    padding: 16px;
  }
  
  &-footer {
    padding: 16px;
    background: #f5f5f5;
    border-top: 1px solid #ddd;
  }
  
  &-title {
    margin: 0 0 8px;
    font-size: 18px;
    font-weight: bold;
  }
  
  &-text {
    margin: 0;
    color: #666;
  }
  
  &.active {
    border-color: #007bff;
    
    .card-header {
      background: #007bff;
      color: white;
    }
  }
}

表单组件 #

less
.form {
  &-group {
    margin-bottom: 16px;
  }
  
  &-label {
    display: block;
    margin-bottom: 4px;
    font-weight: 500;
  }
  
  &-control {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid #ddd;
    border-radius: 4px;
    
    &:focus {
      border-color: #007bff;
      outline: none;
      box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1);
    }
    
    &:disabled {
      background: #f5f5f5;
      cursor: not-allowed;
    }
    
    &.is-invalid {
      border-color: #dc3545;
    }
    
    &.is-valid {
      border-color: #28a745;
    }
  }
  
  &-text {
    margin-top: 4px;
    font-size: 12px;
    color: #666;
    
    &.text-danger {
      color: #dc3545;
    }
  }
}

按钮组件 #

less
.btn {
  display: inline-block;
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
  
  &:hover {
    opacity: 0.9;
  }
  
  &:active {
    transform: translateY(1px);
  }
  
  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
  
  &-primary {
    background: #007bff;
    color: white;
  }
  
  &-secondary {
    background: #6c757d;
    color: white;
  }
  
  &-success {
    background: #28a745;
    color: white;
  }
  
  &-danger {
    background: #dc3545;
    color: white;
  }
  
  &-outline {
    background: transparent;
    border: 1px solid currentColor;
    
    &.btn-primary {
      color: #007bff;
    }
  }
  
  &-sm {
    padding: 4px 8px;
    font-size: 12px;
  }
  
  &-lg {
    padding: 12px 24px;
    font-size: 18px;
  }
  
  &-block {
    display: block;
    width: 100%;
  }
}

最佳实践 #

控制嵌套深度 #

less
// 推荐:最多 3 层嵌套
.component {
  .element {
    .sub-element {
      // 停止嵌套
    }
  }
}

使用 BEM 命名 #

less
// BEM + Less 嵌套
.block {
  // Element
  &__element {
    // Modifier
    &--modifier {
      color: red;
    }
  }
}

编译结果:

css
.block__element--modifier {
  color: red;
}

分离关注点 #

less
// 推荐:将复杂组件拆分
.card {
  // 基础样式
}

.card-header {
  // 头部样式
}

.card-body {
  // 内容样式
}

下一步 #

现在你已经掌握了嵌套语法,接下来学习 混合 来复用样式代码!

最后更新:2026-03-28