使用 Less 反转悬停状态

Reverse states on hover with Less

我有以下 LESS 代码:

.favourite-action-link {
    &:after {
        color:@grey;
        content: '\e836';
    }
    &.is-favourite:after {
        color:@red;
        content: '\e811';
    }
    &:hover {
        &:after {
            color:@red;
            content: '\e811';
        }
        &.is-favourite:after {
            color:@grey;
            content: '\e836';
        }
    }
}

基本目标是有一个正常状态和一个悬停状态,当另一个 class 存在时,它们会颠倒过来。我将在其他操作中重复此操作(例如 .share-action-link.review-action-link 等),这看起来很乱。有没有办法创建一个 mixin,这样我就可以像这样提供它:

.favourite-action-link {
    &:after {
        color:@grey;
        content: '\e836';
        &:hover {
            color:@red;
            content: '\e811';
        }
        .reverseOnClass(is-favourite);
    }
}

或者类似的东西?到目前为止我能想到的唯一方法是:

.favourite-action-link {
    &:after {
        color:@grey;
        content: '\e836';
    }
    &.active:after {
        color:@red;
        content: '\e811';
    }
}

然后使用 jQuery 代替悬停 - 在 (isHovering XOR hasClass(is-favourite)) 上切换 .active - 但是将 LESS 变成 LESS + jQuery 与固定 a 相反mess/maintainability 问题。

我真的建议像下面这样写,因为它使代码简单易读。

.favourite-action-link {
  &:after, &.is-favourite:hover:after {
    color: @grey;
    content: '\e836';
  }
  &:hover:after, &.is-favourite:after {
    color: @red;
    content: '\e811';
  }
}

但是如果你真的想使用mixin来避免重复选择器那么你可以像下面这样写。此 mixin 将两个规则集作为输入,并将它们应用于所需的选择器。

.favourite-action-link {
  .rules-gen(
    {
      color: @grey;
      content: '\e836';
    };
    {
      color: @red;
      content: '\e811';
    }
  );
}

.rules-gen(@rule1; @rule2){
  &:after, &.is-favourite:hover:after {
    @rule1();
  }
  &:hover:after, &.is-favourite:after {
    @rule2();
  }
}

在这两种方法中,选择器也被分组,这也意味着减少了代码行数。

Demo


或者,如果额外的 class 并不总是 is-favourite 并且它也可能是其他东西,那么您也可以将它作为参数传递给 mixin,如下所示:

.favourite-action-link {
  .rules-gen(
    {
      color: grey;
      content: '\e836';
    };
    {
      color: red;
      content: '\e811';
    };
    ~"is-favourite"
  );
}

.share-action-link {
  .rules-gen(
    {
      color: yellow;
      content: '\e836';
    };
    {
      color: gold;
      content: '\e811';
    };
    ~"active"
  );
}

.rules-gen(@rule1; @rule2; @addedClass){
  &:after, &.@{addedClass}:hover:after {
    @rule1();
  }
  &:hover:after, &.@{addedClass}:after {
    @rule2();
  }
}

Demo