注意!Less的命名空间和css 的namespace可不一样,Less的命名空间更像是封装一个包装类,你可以通过类名来访问内部的属性。

基本封装与使用

有时,出于组织结构或仅仅是为了提供一些封装的目的,你希望对混合(mixins)进行分组。你可以用 Less 更直观地实现这一需求。假设你希望将一些混合(mixins)和变量置于 #bundle 之下,为了以后方便重用或分发

  1. #bundle() {
  2. .button {
  3. display: block;
  4. border: 1px solid black;
  5. background-color: grey;
  6. &:hover {
  7. background-color: white;
  8. }
  9. }
  10. .tab { ... }
  11. .citation { ... }
  12. }

现在,如果我们希望把 .button 类混合到 #header a 中,我们可以这样做:

#header a {
  color: orange;
  #bundle.button();  // 还可以书写为 #bundle > .button 形式,当该类没有定义形参时,最后的小括号()可以不写
}

你可以神奇的发现,这种写法酷似JS中的对象,你可以将一些选择器和样式封装到一个混合类中,然后通过点( . )或者箭头 > 符号来引入封装好的某个选择器,而不需要引入整个类。

注意!:如果你不希望它们出现在输出的 CSS 中,例如 #bundle .tab,请将 () 附加到命名空间(例如 #bundle() )后面。

传递参数/混入守卫

和混入一样,如果你在定义某个某个选择器的时候加了小括号(),并且在括号中定义了形参,则其他选择器在混入时必须传入相应的参数!

#mix() {
  .but(@size) {  //在.but中要求传递一个size的参数
    font-size: @size px;  //在样式中应用这个形参
    color: aquamarine;
  }
}

.mixin {
  #mix.but(50); //传递参数给@size
}

编译为:

.mixin {
  font-size: 50 px;
  color: aquamarine;
}

注意!当你使用命名空间和访问符的时候,你就不可以在封装类处定义参数列表,这样会导致冲突!如果一定要传参,则你就无法通过访问符访问:

#mix(@size) {
  .but {  //在.but中要求传递一个size的参数
    font-size: @size px;  //在样式中应用这个形参
    color: aquamarine;
  }
}

.mixin {
  #mix(50).but; //这样写是错误的!less无法编译,有语义问题
}

如果一定要传参,则你就无法通过访问符访问,你只能这么写:
.mixin {
  #mix(50); //这样写会导致整个.but一起被导入,而不是只导入.but中的样式
}

最后!当一个混入类没有定义形参时,最后的小括号()可以不写。

命名空间守护

以上的参数你可以选择传或者不传,但是命名空间守护则是规定某一个变量的值,只有当变量的值正确是,才会生效,你可以通过 when 关键字来定义守护规则。

@mode;
#namespace when (@mode = huge) {
  .mixin() { /* */ }
}

#namespace {
  .mixin() when (@mode = huge) { /* */ }
}

同时,你也可以用逻辑判断关键字(and、or、not)来连接多个表达式或者将其取反。
注意!less中没有 != 符号,判断不相等时必须使用 not (名字=值)

// 命名空间守护,要求参数必须是规定的值时,才会生效
// 当有多个表达式时,需要用小括号括住,像这样:when(/*表达式*/)
#namespace when (not(@mode = huge) and (@mode) or not(@mode = small)) {
  .mixin() {
    /* */
  }
}