Less 映射 #

Maps(映射)是 Less 3.5+ 引入的数据结构,类似于 JavaScript 中的对象,用于存储键值对集合。

定义映射 #

基本语法 #

less
@colors: {
  primary: #007bff;
  secondary: #6c757d;
  success: #28a745;
  danger: #dc3545;
  warning: #ffc107;
  info: #17a2b8;
};

嵌套映射 #

less
@theme: {
  colors: {
    primary: #007bff;
    secondary: #6c757d;
  };
  fonts: {
    base: 16px;
    small: 14px;
    large: 18px;
  };
};

访问映射 #

使用 [] 语法 #

less
@colors: {
  primary: #007bff;
  secondary: #6c757d;
};

.button {
  background: @colors[primary];  // #007bff
}

.text {
  color: @colors[secondary];     // #6c757d
}

访问嵌套映射 #

less
@theme: {
  colors: {
    primary: #007bff;
    secondary: #6c757d;
  };
  fonts: {
    base: 16px;
  };
};

.body {
  font-size: @theme[fonts][base];        // 16px
  color: @theme[colors][primary];        // #007bff
}

映射函数 #

length() #

获取映射的键值对数量:

less
@colors: {
  primary: #007bff;
  secondary: #6c757d;
  success: #28a745;
};

.count {
  total: length(@colors);  // 3
}

extract() #

通过索引获取值(索引从 1 开始):

less
@colors: {
  primary: #007bff;
  secondary: #6c757d;
  success: #28a745;
};

.first {
  color: extract(@colors, 1);  // #007bff
}

each() #

遍历映射:

less
@colors: {
  primary: #007bff;
  secondary: #6c757d;
  success: #28a745;
};

each(@colors, {
  .text-@{key} {
    color: @value;
  }
  .bg-@{key} {
    background: @value;
  }
});

编译结果:

css
.text-primary { color: #007bff; }
.bg-primary { background: #007bff; }
.text-secondary { color: #6c757d; }
.bg-secondary { background: #6c757d; }
.text-success { color: #28a745; }
.bg-success { background: #28a745; }

实用示例 #

颜色系统 #

less
@colors: {
  primary: #007bff;
  secondary: #6c757d;
  success: #28a745;
  danger: #dc3545;
  warning: #ffc107;
  info: #17a2b8;
  light: #f8f9fa;
  dark: #343a40;
};

// 生成文本颜色类
each(@colors, {
  .text-@{key} {
    color: @value;
  }
});

// 生成背景颜色类
each(@colors, {
  .bg-@{key} {
    background: @value;
  }
});

// 生成按钮
each(@colors, {
  .btn-@{key} {
    background: @value;
    color: contrast(@value, #000, #fff);
    border: 1px solid darken(@value, 5%);
    padding: 8px 16px;
    border-radius: 4px;
    cursor: pointer;
    
    &:hover {
      background: darken(@value, 10%);
    }
  }
});

断点系统 #

less
@breakpoints: {
  xs: 0;
  sm: 576px;
  md: 768px;
  lg: 992px;
  xl: 1200px;
  xxl: 1400px;
};

// 生成容器
each(@breakpoints, {
  @media (min-width: @value) {
    .container-@{key} {
      max-width: @value;
      margin: 0 auto;
    }
  }
});

// 生成响应式显示类
each(@breakpoints, {
  @media (min-width: @value) {
    .d-@{key}-none { display: none; }
    .d-@{key}-block { display: block; }
    .d-@{key}-flex { display: flex; }
    .d-@{key}-inline { display: inline; }
  }
});

字体系统 #

less
@fonts: {
  family: {
    base: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto;
    heading: "Helvetica Neue", Arial, sans-serif;
    mono: "SFMono-Regular", Consolas, monospace;
  };
  size: {
    xs: 12px;
    sm: 14px;
    base: 16px;
    lg: 18px;
    xl: 20px;
    xxl: 24px;
    xxxl: 32px;
  };
  weight: {
    light: 300;
    normal: 400;
    medium: 500;
    semibold: 600;
    bold: 700;
  };
};

body {
  font-family: @fonts[family][base];
  font-size: @fonts[size][base];
  font-weight: @fonts[weight][normal];
}

h1, h2, h3 {
  font-family: @fonts[family][heading];
  font-weight: @fonts[weight][bold];
}

// 生成字体大小类
each(@fonts[size], {
  .text-@{key} {
    font-size: @value;
  }
});

// 生成字重类
each(@fonts[weight], {
  .font-@{key} {
    font-weight: @value;
  }
});

间距系统 #

less
@spacing: {
  0: 0;
  1: 4px;
  2: 8px;
  3: 12px;
  4: 16px;
  5: 20px;
  6: 24px;
  8: 32px;
  10: 40px;
  12: 48px;
};

// 生成 padding 类
each(@spacing, {
  .p-@{key} { padding: @value; }
  .pt-@{key} { padding-top: @value; }
  .pr-@{key} { padding-right: @value; }
  .pb-@{key} { padding-bottom: @value; }
  .pl-@{key} { padding-left: @value; }
  .px-@{key} { padding-left: @value; padding-right: @value; }
  .py-@{key} { padding-top: @value; padding-bottom: @value; }
});

// 生成 margin 类
each(@spacing, {
  .m-@{key} { margin: @value; }
  .mt-@{key} { margin-top: @value; }
  .mr-@{key} { margin-right: @value; }
  .mb-@{key} { margin-bottom: @value; }
  .ml-@{key} { margin-left: @value; }
  .mx-@{key} { margin-left: @value; margin-right: @value; }
  .my-@{key} { margin-top: @value; margin-bottom: @value; }
});

Z-Index 层级 #

less
@z-index: {
  dropdown: 1000;
  sticky: 1020;
  fixed: 1030;
  modal-backdrop: 1040;
  modal: 1050;
  popover: 1060;
  tooltip: 1070;
};

each(@z-index, {
  .z-@{key} {
    z-index: @value;
  }
});

// 使用
.modal {
  z-index: @z-index[modal];
}

.tooltip {
  z-index: @z-index[tooltip];
}

阴影系统 #

less
@shadows: {
  none: none;
  sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  base: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
  md: 0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06);
  lg: 0 10px 15px rgba(0, 0, 0, 0.1), 0 4px 6px rgba(0, 0, 0, 0.05);
  xl: 0 20px 25px rgba(0, 0, 0, 0.1), 0 10px 10px rgba(0, 0, 0, 0.04);
  inner: inset 0 2px 4px rgba(0, 0, 0, 0.06);
};

each(@shadows, {
  .shadow-@{key} {
    box-shadow: @value;
  }
});

.card {
  box-shadow: @shadows[base];
  
  &:hover {
    box-shadow: @shadows[lg];
  }
}

圆角系统 #

less
@border-radius: {
  none: 0;
  sm: 2px;
  base: 4px;
  md: 6px;
  lg: 8px;
  xl: 12px;
  xxl: 16px;
  full: 9999px;
};

each(@border-radius, {
  .rounded-@{key} {
    border-radius: @value;
  }
});

.button {
  border-radius: @border-radius[base];
}

.avatar {
  border-radius: @border-radius[full];
}

过渡时间 #

less
@transition: {
  none: none;
  all: all 0.2s ease;
  fast: all 0.15s ease;
  base: all 0.3s ease;
  slow: all 0.5s ease;
  colors: color 0.2s ease, background 0.2s ease, border-color 0.2s ease;
};

each(@transition, {
  .transition-@{key} {
    transition: @value;
  }
});

.button {
  transition: @transition[fast];
  
  &:hover {
    background: darken(#007bff, 10%);
  }
}

映射合并 #

Less 不直接支持映射合并,但可以通过变量覆盖实现:

less
@colors-base: {
  primary: #007bff;
  secondary: #6c757d;
};

@colors-extended: {
  success: #28a745;
  danger: #dc3545;
};

// 使用时合并
@colors: {
  primary: @colors-base[primary];
  secondary: @colors-base[secondary];
  success: @colors-extended[success];
  danger: @colors-extended[danger];
};

最佳实践 #

语义化命名 #

less
// 推荐
@colors: {
  primary: #007bff;
  secondary: #6c757d;
};

// 不推荐
@colors: {
  blue: #007bff;
  gray: #6c757d;
};

按功能分组 #

less
@theme: {
  colors: { };
  fonts: { };
  spacing: { };
  breakpoints: { };
};

使用嵌套组织 #

less
@config: {
  light: {
    bg: #fff;
    text: #333;
  };
  dark: {
    bg: #333;
    text: #fff;
  };
};

下一步 #

现在你已经掌握了映射,接下来学习 插件 来扩展 Less 功能!

最后更新:2026-03-28