Функция расширения не работает с вложенными селекторами

У меня есть некоторые проблемы с Меньше 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; теперь это работает только каждый раз, когда размещаются миксины). Во время компиляции ошибок нет.

Я использую скобки 1.3 с расширением Less Autocompile 1.1.9. Что я делаю неправильно?

1 ответ

Решение

Причина:

Цитировать меньше сайта: акцент мой

Расширение по умолчанию ищет точное соответствие между селекторами. Не имеет значения, использует ли селектор ведущую звезду или нет. Неважно, что два n-го выражения имеют одинаковое значение, они должны иметь одинаковую форму, чтобы их можно было сопоставить. Единственным исключением являются кавычки в селекторе атрибутов, меньше знает, что они имеют одинаковое значение, и соответствует им.

Следующее будет работать, потому что параметр к 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); }

Меньше компилятор не будет даже выдавать ошибку в вышеупомянутом сценарии, потому что он молча терпит неудачу, когда нет соответствия.


Решение:

Когда используешь 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,

Вот что говорит веб-сайт Less о расширении "всего": мой акцент

Когда вы указываете ключевое слово all последним в аргументе расширения, оно говорит Less, чтобы сопоставить этот селектор как часть другого селектора. Селектор будет скопирован, и соответствующая часть только затем будет заменена расширением, создав новый селектор.

Еще одна вещь, которая также должна быть отмечена при использовании 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;
}
Другие вопросы по тегам