css - 扩展功能不适用于嵌套选择器

标签 css less extend

我在使用 Less 的 extend 函数时遇到了一些问题。在某些情况下它不起作用,我不明白为什么。有一段有问题的代码:

.page-header {
    .bar:extend(.fixedElement) { // it works
        ...
    }
    .menu:extend(.fixedElement) { // it works
        ...
    }
    // some other stuff
    .menu-list {
        ...
        .btnStyle {
            padding: 18px 20px;
            min-height: 60px;
            width: 100%;
            display: block;
            border-bottom: 1px solid @light2;
        }
        .linkStyle:extend(.btnStyle) { // doesn't work
            //.btnStyle;
            background-color: @light1;
            .remCalc(14);
            &:active {
                background-color: transparent;
            }
        }
        .chosen {
            background-color: transparent;
            &:after {
                color: @primaryColor;
            }
        }
        ...
        .level-2 {
            & > ul {
                a:extend(.linkStyle) { // doesn't work
                    //.linkStyle;
                }
            }
        }
        .level-3 {
            ...
            & > ul > li {
                .btn-menu {
                    &.shown:extend(.chosen) { // doesn't work
                        //.chosen;
                    }
                }
                & > a:extend(.linkStyle) { // doesn't work
                    //.linkStyle;
                }
            }
            .selected {
                .btn-menu:extend(.chosen) { // doesn't work
                    //.chosen;
                }
            }
        }
        .btn-menu:extend(.btnStyle) { // doesn't work
            //.btnStyle;
            ...
        }
    }
}

和:

.gradientBg {
    background: rgb(200, 200, 200);
    background: -webkit-linear-gradient(295deg, rgb(200, 200, 200) 10%, rgb(255, 255, 255) 90%);
    background: -o-linear-gradient(295deg, rgb(200, 200, 200) 10%, rgb(255, 255, 255) 90%);
    background: linear-gradient(25deg, rgb(200, 200, 200) 10%, rgb(255, 255, 255) 90%);
    border: 1px solid @light2;
}

.gr-box, .btn-1 {
    &:extend(.gradientBg); //it works
}

.fixedElement.gradientBg 扩展的元素可以正常编译为 CSS,但不能通过 .btnStyle.linkStyle.chosen (它们只是不在 CSS 中;现在它只在每次放置 mixin 时起作用)。编译过程中没有任何错误。

我使用带有 Less Autocompile 1.1.9 扩展的 Brackets 1.3。我做错了什么?

最佳答案

原因:

Quoting Less Website: emphasis is mine

Extend by default looks for exact match between selectors. It does matter whether selector uses leading star or not. It does not matter that two nth-expressions have the same meaning, they need to have to same form in order to be matched. The only exception are quotes in attribute selector, less knows they have the same meaning and matches them.

下面的代码会起作用,因为 extend 函数的参数与另一个已定义的选择器完全匹配。 (注意:为了简单起见,我删除了一些属性。)

.gradientBg { background: rgb(200, 200, 200); }
.gr-box, .btn-1 { &:extend(.gradientBg); }

但下面的代码将不起作用,因为嵌套选择器的编译选择器路径将是 .parent .gradientBg 并且提供给 extend 函数的参数不是精确的匹配。

.parent{
  .gradientBg { background: rgb(200, 200, 200); }
}
.gr-box, .btn-1 { &:extend(.gradientBg); }

在上述情况下,Less 编译器甚至不会抛出错误,因为当没有匹配项时它会自动失败。


解决方案:

当使用extend 特性来扩展嵌套选择器时,应该提供一个完全匹配的选择器(完整的选择器路径)(或者)应该使用all 关键字。

下面的内容将作为完整的匹配选择器路径提供给 extend 函数。

.parent{
  .gradientBg { background: rgb(200, 200, 200); }
}
.gr-box, .btn-1 { &:extend(.parent .gradientBg); }

或者,根据您的需要,即使这样也可以工作,因为使用了 all 关键字。

.parent{
  .gradientBg { background: rgb(200, 200, 200); }
}
.gr-box, .btn-1 { &:extend(.gradientBg all); }

但请注意输出选择器如何具有结构 .parent .gr-box.parent .btn-1。这是因为 Less 仅用新选择器替换选择器的匹配部分。在 .parent .gradientBg(原始选择器)中,匹配部分(作为参数提供给 extend)只是 .gradientBg,因此是输出选择器在 extend 之后将是 .parent .gr-box

Here is what the Less website says about extend "all": emphasis is mine

When you specify the all keyword last in an extend argument it tells Less to match that selector as part of another selector. The selector will be copied and the matched part of the selector only will then be replaced with the extend, making a new selector.

使用 all 关键字时还应注意的另一件事是,Less 会扩展所有具有匹配部分的选择器的属性。因此,例如,如果我们考虑以下 Less 代码。

.parent{
  .gradientBg { background: rgb(200, 200, 200); }
}
.parent2{
  .gradientBg{ color: red; }
}
.gr-box, .btn-1 { &:extend(.gradientBg all); }

输出如下,因为 .gradientBg 选择器在 .parent.parent2 中使用。

.parent .gradientBg, .parent .gr-box, .parent .btn-1 {
  background: #c8c8c8;
}
.parent2 .gradientBg, .parent2 .gr-box, .parent2 .btn-1 {
  color: red;
}

关于css - 扩展功能不适用于嵌套选择器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31367799/

相关文章:

css - 在两个边框之间制作平滑的 Angular 线

html - 与 IE7 的兼容性问题?

html - 如何设计一个在 Firefox、Chrome 和 IE11 中看起来一样的单选按钮

javascript - 具有多个对象的 jquery extend() 如何工作?

symfony - FOS UserBundle -> 无法创建新用户

java - 为父类(super class)的方法重写分配较弱的访问权限

html - 基于其他div动态高度的动态div高度

css - 配置 WebStorm/PHPStorm 以了解路径

javascript - less 文件的语法验证器

css - 在 Less 选择器中使用 function/mixin