Less.js: : расширить миксины

Созданный на 12 февр. 2013  ·  112Комментарии  ·  Источник: less/less.js

Этот запрос функции был предложен как решение этой проблемы https://github.com/cloudhead/less.js/issues/1155

Это синопсис

Самое замечательное в миксинах то, что они ускоряют разработку, поддерживают чистоту моей рабочей поверхности, мне нужно написать их только один раз, и я знаю, каким будет полученный результат. Однако недостатком миксинов является то, что они не СУХИЕ. Особенно, когда вы часто используете «служебные» миксины, такие как clearfix. Вот где extends _ может быть намного лучше. Фактически, это отличный конкретный вариант использования для расширения миксинов . В основном это будет работать как расширение вложенных селекторов с помощью миксинов. Таким образом, миксины вообще не менялись, они все равно работали бы. Если у вас есть миксин, который вы не используете, он не будет отображаться в скомпилированном CSS. Если вы его используете, его свойства все равно будут отображаться в скомпилированном коде в каждом селекторе, где он использовался. И если вы _ расширяете _ миксин, селектор (или селекторы), расширяющий миксин, появится вместо миксина. Итак, если вы сделаете это:

.clearfix() {
    // stuff
}
.navbar {
    &:extend(.clearfix());
}
.banner {
    &:extend(.clearfix());
}

и скомпилированный результат будет:

.navbar,
.banner {
   // clearfix stuff
}

Таким образом, свойства миксинов по-прежнему наследуются расширяющими их селекторами, но сам миксин (селектор) не отображается в скомпилированном результате.

Это сделало бы и расширения, и миксины намного более мощными, чем они есть сами по себе.

feature request medium priority up-for-grabs

Самый полезный комментарий

Объявление государственной службы

В любой момент вы можете отправить запрос на перенос или поработать с разработчиком, чтобы получить его, и очень вероятно, что эта функция будет объединена. Библиотеке Less.js требуется больше регулярных вкладов от людей, таких как люди в этом потоке . Это не ответственность какого-либо одного человека. Это полностью зависит от одного человека, который видит эту цепочку или нуждается в этой функции и не торопится, чтобы это произошло.

Если вы ответили, что вы не разработчик, то есть много ДРУГИХ способов поддержать этот проект в ролях, не связанных с разработкой, будь то предоставление необходимой документации для новых функций или поддержка дизайна на веб-сайте, выполнение тестов, предоставление отзывов. о проблемах, управлении проектами, ответах на вопросы о переполнении стека, написании сообщений в блогах, твитах о Less, участии в CSS и веб-сообществах и написании библиотек Less.

Многие из этих задач выполняются людьми, которые являются разработчиками, поэтому время, которое они могли бы внести в разработку, тратится на эти другие задачи.

Если вы _ разработчик и ваш ответ: «У меня нет времени», то это точная причина того, почему эта проблема не решена. Это на 100% зависит от вас, будет ли функция завершена, поэтому спрашивать, почему она не была завершена «кем-то», бесполезно. _Вы тот кто-то ._ Это произойдет, я _гарантируюсь_, что это произойдет, если и когда вы примете участие в этом проекте. Вы можете стать участником одного из самых популярных инструментов с открытым исходным кодом в Интернете. Вы можете изменить жизнь ... тысяч? Сотни тысяч? Миллионы? И в качестве дополнительного преимущества вы можете быть уверены, что ваши любимые функции появятся раньше, чем позже.

Если вы хотите, чтобы это или какая-то особенность произошла, сделайте это . Мы будем рады видеть вас. Мы будем рады сотрудничать с вами! Чем меньше растет это сообщество, тем меньше может становиться все лучше и лучше!

И, послушайте, я понимаю, что иногда у людей действительно совсем нет времени вносить свой вклад, и тем не менее они очень хотят, чтобы появилась какая-то особенность. Хорошо. Я бы просто сказал, что если вы находитесь в таком сценарии, вы стремитесь к сочувствию и благодарности людям, которые жертвуют свое время (а иногда и деньги), чтобы помочь вам, и я уверен, что другие люди в сообществе Less сделают все возможное, чтобы продолжают делать так, как могут.

Искренне,
Мэтью Дин, член основной группы Less.js

Все 112 Комментарий

Мне это нравится, но для ясности ... это не позволяет вам делать то, что вы не могли делать раньше, это просто означает, что вы получаете ...

.navbar,
.banner {
    // clearfix stuff
}

скорее, чем

.navbar {
    // clearfix stuff
}
.banner {
    // clearfix stuff
}

или я неправильно понял?

Я бы хотел иметь как параметрические, так и обычные миксины, чтобы иметь

.navbar,
.banner {
    // clearfix stuff
}
.....

или

.clearfix,
.navbar,
.banner {
    // clearfix stuff
}
....

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

конечно

.clearfix,
.navbar,
.banner {
    // clearfix stuff
}

короче чем

 .clearfix {
    // clearfix stuff
  }
 .navbar{
    // clearfix stuff
 }
.banner {
    // clearfix stuff
}

и для более сложных примеров, которые могут иметь решающее значение, и я знаю, что некоторые люди перешли на SASS только из-за этой нехватки

Обычные миксины не могли измениться. Они в значительной степени приспособлены для Less. @agatronic , да, я тоже так считаю. Однако здесь есть проблемы, например, сможем ли мы расширить параметрические миксины? И если да, то как это будет работать? Предполагая, что это поддерживается, допустим, вы дважды расширяете параметрический миксин, но каждый раз используете разные переменные, например:

.transition(@transition) {
  -webkit-transition: @transition;
     -moz-transition: @transition;
       -o-transition: @transition;
          transition: @transition;
}
.navbar {
    &:extend(.transition(opacity .2s linear));
}
.banner {
    &:extend(.transition(opacity .3s linear));
}

Я предполагаю, что он может создать две копии миксина, что не меньше кода и не имеет преимущества перед обычными миксинами:

.navbar {
  -webkit-transition: opacity .2s linear;
     -moz-transition: opacity .2s linear;
       -o-transition: opacity .2s linear;
          transition: opacity .2s linear;
}
.banner {
  -webkit-transition: opacity .3s linear;
     -moz-transition: opacity .3s linear;
       -o-transition: opacity .3s linear;
          transition: opacity .3s linear;
}

Однако вы можете часто использовать этот конкретный миксин, поэтому, когда вы снова используете миксин для .dropdown с теми же переменными, что и .banner , это может привести к следующему:

.navbar {
  -webkit-transition: opacity .2s linear;
     -moz-transition: opacity .2s linear;
       -o-transition: opacity .2s linear;
          transition: opacity .2s linear;
}
.banner,
.dropdown {
  -webkit-transition: opacity .3s linear;
     -moz-transition: opacity .3s linear;
       -o-transition: opacity .3s linear;
          transition: opacity .3s linear;
}

И это то, что меня интересует. было бы хорошо услышать отзывы и от других

@jonschlinkert да, это даже лучшая иллюстрация, спасибо. как я уже сказал обеими руками! но поймите, хотя это добавляет еще один уровень сложности, и это нужно делать / не делать вдумчиво

Расширение метода, на который вы ссылаетесь, может быть довольно легко достигнуто с помощью этого шаблона:

.transition(@transition) {
    -webkit-transition: @transition;
     -moz-transition: @transition;
       -o-transition: @transition;
          transition: @transition;
}

.quickOpacity1(){
    .transition(opacity .2s linear);
}

.quickOpacity2(){
    .transition(opacity .3s linear);
}

.navbar{
    .quickOpacity1();
}

.banner,
.dropdown{
    .quickOpacity2();
}

Вышеупомянутое вводит полурасширенные миксины в 2 новых объявления.

Для clearfix также легко использовать аналогичный шаблон ниже, который не только создаст clearfix как класс, но и внедрит эти стили clearfix в новое объявление.

.clearfix{
  //clearfix stuff
}
.navbar,
.banner {
    .clearfix;
}

@krismeister Я думаю, здесь может быть путаница. Описываемый вами шаблон на самом деле является просто вложенными миксинами или шаблоном наследования миксинов. Увеличивает работу наоборот.

@jonschlinkert Mixin наследование - отличное имя. Казалось, что в обоих приведенных выше примерах пытались наследовать выходные данные от родителя, что является основной особенностью расширения. Вы, вероятно, согласитесь, что результат моего примера был вашим ожидаемым результатом.

Однако я понял, перечитав ваш исходный комментарий - вы хотите, чтобы результат был объединен в одно правило CSS. Хотя изначально было написано как 2.

На самом деле :extend довольно круто. Я собираюсь стать полным ботаником, но все сводится к тому, «что и куда перемещается». Думайте о миксине как о «передаче свойств миксина селектору, который его использовал». И подумайте о :extend как о инверсии, «передаче селектора, который использовал его, до самого миксина». Не свойства _selector, а только сам селектор. Итак, если вы сделали это:

.some-mixin() {
    padding-top: 100px;
    background: #f7f7f7;
}


// a selector that is extending the mixin
.alert:extend( .some-mixin() ) {
    border: 1px solid #e5e5e5;
}
// another selector extending the mixin
section:extend(.some-mixin()) {
    margin: 20px 0;
}

Это приведет к следующему:

// The selectors that extended the mixin are now where the mixin used to be.
.alert,
section {
    padding-top: 100px;
    background: #f7f7f7;
}

// And the properties of the mixin did not get copied down below
// so we saved a line or two of code.
.alert {
    border: 1px solid #e5e5e5;
}
section {
    margin: 20px 0;
}

Надеюсь, в этом есть больше смысла. Я рада помочь в любое время.

@agatronic , @matthewdl , @DesignByOnyx , просто :extend[N] .

Я думаю, что при расширении миксинов тоже легче для глаз:

section:extend[.some-mixin(), .another-mixin()] {
    margin: 20px 0;
}

Я в любом случае в порядке, но что-то вроде квадратных скобок кажется правильным.

@jonschlinkert - [] означает атрибут в css, а не массив, где в качестве :extend() был выбран

хороший момент, согласен.

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

большой палец вверх для синтаксиса extension (N), больше похоже на природный CSS, по той же причине, что и @agatronic

Расширение миксинов - неплохая идея. Не уверен в синтаксисе примера, @jonschlinkert. Не то чтобы мне это не нравилось; Я просто не понимаю, что вы написали.

Я думаю, вы имеете в виду, что вы хотите определить классы, которые «втягивают» одно и то же содержимое миксина, но фактически не повторяются в результирующем CSS. Я бы не стал называть это расширяющими миксинами. То есть вы не изменяете определение миксина (точно так же, как определение расширения применимо к селекторам), вы фактически изменяете (расширяете) полученные классы.

Итак, поправьте меня, если я ошибаюсь, но разве ваш пример навигационной панели / баннера / раскрывающегося списка не будет поддерживаться:

.navbar {
  .transition(opacity .2s linear);
}
.banner {
  .transition(opacity .3s linear);
}
.dropdown:extend(.banner) { }

То есть расширение классов, как обычно? Я просто пытаюсь осмыслить ваш шаблон использования, и использование расширения для миксинов кажется противоречащим его использованию и номенклатуре для расширения селекторов. Можете ли вы предоставить дополнительные сведения о том, почему вам нужно / вы хотите ссылаться на миксин в вызове расширения, а не расширять селектор, который ссылается на миксин?

Вот как я это понимаю

ЖЕЛАЕМЫЙ ОКОНЧАТЕЛЬНЫЙ ВЫВОД CSS

.sometingShared,
.anotherClass,
.anotherYetClass,
.yetClass {
    // amount of shared code here
}

.anotherClass,
.anotherYetClass {
    // did something dynamic with a
}

.yetClass {
    // did something dynamic with b
}

.anotherClass {
    // native another class code
}

.anotherYetClass {
    // native another yet class code
}

.yetClass {
    // native yet class code
}

КАК ВЫ ДОЛЖНЫ ПОЙТИ С ТЕКУЩЕЙ ВЕРСИЕЙ МЕНЬШЕ, ЧТОБЫ ПОЛУЧИТЬ ЖЕЛАЕМЫЙ РЕЗУЛЬТАТ

.somethingShared,
.anotherClass,
.anotherYetClass,
.yetClass {
    // amount of shared code here
}

.someMixin(@val) {
    // do something dynamic with val
}

.anotherClass,
.anotherYetClass {
    .someMixin(a);
}

.yetClass {
    .someMixin(b);
}

.anotherClass {
    // native another class code
}

.anotherYetClass {
    // native another yet class code
}

.yetClass {
    // native yet class code
}

ПРЕДЛАГАЕМЫЙ МЕНЬШЕ СИНТАКСИСА

.somethingShared {
    // amount of shared code here
}

.someMixin(@val) {
    // do something dynamic with val
}

.anotherClass:extend(.sometingShared, .someMixin(a)) {
    // native another class code
}

.anotherYetClass:extend(.sometingShared, .someMixin(a)) {
    // native another yet class code
}

.yetClass:extend(.sometingShared, .someMixin(b)) {
    // native yet class code
}

Хотя расширения могут быть полезны только тогда, когда у вас действительно много общего кода, в других случаях использование обычных миксинов имеет преимущество.

И, в некотором роде, живой манекен, нацеленный на простую игру.

http://jsbin.com/opekon/1/edit
http://jsbin.com/opekon/2/edit
http://jsbin.com/opekon/3/edit
http://jsbin.com/opekon/4/edit

как уже говорилось, в определенных обстоятельствах может быть действительно повышение производительности для таких ленивых людей, как я :), чтобы оптимизировать LESS-код только потому, что это влияет на дальнейшую гибкость

Вот хороший пост в блоге о расширениях, в котором рассказывается о нескольких вещах, касающихся того, как SASS обрабатывает расширения, и, вероятно, для нас будет разумным поучиться на опыте других. http://designshack.net/articles/css/semantic-grid-class-naming-with-placeholder-selectors-in-sass-3-2/

В частности, я считаю, что мое предложение о расширении миксинов по существу приведет к тому же конечному результату, что и «заполнители» SASS, но без необходимости создавать бесполезные, лишние классы, содержащие только заполнители.

РЕДАКТИРОВАТЬ: да, вот еще один пост, в котором красиво суммируются заполнители. Это именно то, что я предлагаю с расширением миксинов http://maximilianhoffmann.com/article/placeholder-selectors

Я лично предпочел бы это всем другим функциям, связанным с расширением. Без вопросов. Это сильное заявление, но я думаю, что не очень хорошо его объясняю, если другие не согласны. Это довольно мощная штука.

Я чувствую, что САСС

 %tile {
  width: 200px;
  height: 200px;
  margin-right: 20px;
}

совпадает с параметрическим миксином, предназначенным исключительно для расширений, что, вероятно, не так уж и плохо с точки зрения разделения задач. но да, это CSS, и разве он не должен быть настолько простым, насколько это возможно?

@agatronic, пока мы говорим, что это за расширение https://github.com/agatronic/less.js/blob/master/lib/less/tree/extend.js должно быть? отметил, что это уже в основной менее ветке. извините за вопрос о нубе.

@ dmi3y это первая версия расширения, которая была извлечена из запроса на перенос, готового для 1.4.0 - она ​​представляет собой узел расширения

спасибо @agatronic , теперь вижу, сколько я пропустил;)

@ dmi3y, пожалуйста, не стесняйтесь продолжить обсуждение, давайте постараемся оставить эту проблему на более высоком уровне, чтобы мы могли подвести ее к завершению. Также не стесняйтесь писать мне лично, я буду рад обсудить с вами, как работают миксины и расширения (моя контактная информация находится в моем профиле). Также быстрый комментарий, чтобы избежать путаницы в этой теме. Ваш пример:

%tile {
    width: 200px;
    height: 200px;
    margin-right: 20px;
}

Это синтаксис для «заполнителя» SCSS, который был реализован в спецификации SCSS для выполнения чего-то подобного тому, что я предлагаю с расширяющими миксинами. Но это не имеет ничего общего с параметризацией. Параметрические миксины - это просто миксины, которые принимают параметры, что означает, что их значения могут изменяться каждый раз, когда они используются.

@matthewdl

Я думаю, вы имеете в виду, что вы хотите определить классы, которые «втягивают» одно и то же содержимое миксина, но не повторяются в результирующем CSS.

а также

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

Нет, упускают оперативный пункт, совсем наоборот. Возможно, путаница была вызвана тем, что я сделал ошибку, сосредоточившись на параметрических миксинах в моем примере.

Итак, во-первых, я считаю важным подчеркнуть, что не все миксины являются параметрическими, многие созданы для _не_ принятия параметров. Некоторые миксины, такие как clearfix, используются снова и снова без изменения каких-либо переменных при их использовании. Это идеальный пример того, почему расширение миксинов было бы выгодно.

Параметрические или нет, миксины во всей их красе имеют недостаток в том, что каждый раз, когда они используются, его свойства дублируются . Итак, позвольте мне попытаться объяснить, как расширение миксинов будет работать, используя только «обычные миксины», и продолжу с примера, который вы использовали выше.

Учитывая ваш пример, необходимо отметить два полностью независимых и не связанных между собой момента:

  1. класс баннера по-прежнему будет отображаться в скомпилированном CSS независимо от того, был он расширен или нет, но если класс баннера был миксином, он отобразился бы в результирующем CSS только в том случае, если он был использован (расширен или смешан). Одно это ценно. А также
  2. Когда вы _расширяете миксин_, вместо того, чтобы копировать одни и те же свойства снова и снова, мы копируем сами фактические селекторы на место миксина.

Но это лишь один пример. Учтите, что в какой-то момент в Twitter Bootstrap один миксин .clearfix() использовался более 20 раз внутри других селекторов, И он также был вложен в 4 или 5 других структурных миксинов, таких как .container-fixed() , .make-row() и #grid > .core() . Это означает, что эти миксины _также_ дублировали свойства миксина clearfix каждый раз, когда они использовались. И это не уникально для этой структуры.

В этом больше смысла? Таким образом, вместо того, чтобы дублировать свойства миксина clearfix более 20 раз, мы сгруппируем селекторы, которые используют миксин clearfix, вместо самого миксина, и свойства будут объявлены только один раз . И снова, это всего лишь один миксин, представьте чистую выгоду от увеличения потерь обычных миксинов по сравнению с дублированием их свойств. Как я упоминал где-то выше, обычные миксины все равно нужно будет использовать без их расширения, для специфичности и переопределения, но это не умаляет ценности расширения тех, которые этого не делают. Фактически, я лично создал бы дополнительные миксины, которые будут использоваться специально с расширением, которые я бы не использовал в противном случае.

И мой второй пример выше был посвящен тому, как extension будет работать с параметрическими миксинами, так что, надеюсь, это завершает картину и теперь имеет больше смысла? В противном случае статьи, на которые я ссылался выше, должны устранить любую путаницу. Расширение миксинов - это чрезвычайно мощный и полезный инструмент, который позволит вам достичь того же конечного результата, что и расширение вложенных селекторов, но с помощью миксинов вместо любых вложенных селекторов. Это позволяет вам организовать селекторы таким образом, чтобы с наибольшей вероятностью получить желаемые результаты и избежать непредвиденных последствий. @DesignByOnyx , @agatronic , @matthewdl , я что-то

Спасибо. Я думаю, что понимаю этот вариант использования, и я думаю, что эта строка лучше всего говорит об этом:

класс баннера был миксином, он будет отображаться в результирующем CSS, только если он был использован (расширен или смешан)

Это имеет смысл для меня. Вероятно, я зацикливаюсь на том, что общий синтаксис :extend еще не окончен. Но вы приводите убедительные доводы.

Я бы сказал, что после того, как мы завершим работу над блоками селекторов, если поведение расширяемых миксинов в конечном итоге совпадет с поведением расширяющихся селекторов (с ключевым отличием в той строке, которую вы только что сказали, в CSS не выводится селектор для расширенного ЕСЛИ там не было начального использования), то это интуитивно для меня.

То есть, если бы я мог также сделать что-то вроде этого (или эквивалентный синтаксис):

.facebook-button:extend( .button() all ) {
    border: 1px solid #e5e5e5;
}

... затем поднял палец вверх. Но для меня все зависит от того, что / как / если мы разрешаем :extend для селекторов. Но, помимо синтаксиса, как идея функции, вы правы, это звучит.

@jonschlinkert, спасибо, очень признателен за вашу поддержку и, конечно же, постараюсь изо всех

Да, в этом примере я должен был быть откровенным в моем предыдущем посте.

%tile {
   width: 200px;
   height: 200px;
   margin-right: 20px;
 }

взято из руководств по SASS, предоставленных Джоном, и его основная цель - избежать потери вывода в CSS из классов, которые не будут использоваться. Таким образом, в этом конкретном ракурсе это можно рассматривать как пустой параметрический миксин в LESS. Когда вы хотите использовать его, но не хотите, чтобы он выводился в конечную таблицу стилей.

Я сразу же вмешиваюсь в это обсуждение и хотел бы внести ясность в следующий комментарий:

если класс баннера был миксином, он будет отображаться в результирующем CSS только в том случае, если он был использован (расширен или смешан)

Итак, переходя к более общему примеру clearfix, это МЕНЬШЕ и результирующий CSS ?:

.clearfix() {
    &:before,
    &:after { content: " "; display: table; }

    &:after { clear: both; }
}
.something:extend( .clearfix() ) { }

/*
.clearfix:before,
.clearfix:after,
.something:before,
.something:after {
    content: " ";
    display: table;
}
.clearfix:after,
.something:after {
    clear: both;
}
*/

Изначально я ожидал, что класс .clearfix останется опущенным в скомпилированном CSS. Лично мне не нужен был бы класс в скомпилированном CSS, поскольку я бы не использовал его в разметке и лишних байтах в моем CSS. В любом случае у меня нет твердого мнения, но разъяснения по этому поводу помогут мне сделать более качественные комментарии в дальнейшем. Спасибо.

это ... результирующий CSS ?:

Я рад, что вы спрашиваете, но нет , в результирующем CSS будет отображаться только класс .something . Итак, вы оправдали свои первоначальные ожидания.

просто прочитайте ссылку на заполнители, и да, я думаю, что расширение миксинов - лучший и более простой способ делать что-то и получать ту же функциональность.

Чтобы укрепить вашу точку зрения

.clearfix() {
    &:before,
    &:after { content: " "; display: table; }
    &:after { clear: both; }
}
.something:extend( .clearfix() ) { }

/*
.something:before,
.something:after {
    content: " ";
    display: table;
}
.something:after {
    clear: both;
}
*/

и, предположительно, если .clearfix() { определение равно .clearfix { то его вызов с скобками или без них внутри определения расширения не повлияет на вывод ..

Использование синтаксиса псевдокласса для функции расширения совершенно НЕПРАВИЛЬНО,
поскольку «extension sth» НЕ равно «match sth», это ничего не значит о структуре DOM, которую должен выполнять селектор.

Вы МЕНЬШЕ, ребята, «изобрели» много плохих идей. Самая известная из них - это «повторное использование» .xxx (селектор класса) в качестве нотации миксинов. По крайней мере, это упрощает переход от простого CSS к препроцессору. Но: расширение синтаксиса - худшая идея, которую я когда-либо слышал.

Я не хочу с достоинством разглагольствовать о наших Проблемах, но это не первый раз, когда я слышу такие вещи, так что давайте поговорим о CSS и проясним ситуацию.

Вы МЕНЬШЕ, ребята, «изобрели» много плохих идей. Самая известная из них - это «повторное использование» .xxx (селектора класса) в качестве нотации миксинов ....: расширенный синтаксис - худшая идея, которую я когда-либо слышал.

.xxx называется неявным миксином. Это работает, и это легко понять. Фактически, этот синтаксис не так "агрессивен" в спецификации CSS, как, скажем, использование at-rules для актуального стиля. @keyframes ближе всего к тому, что можно было бы описать как стиль, и _могут_ считаться исключением из того, что я говорю, поскольку используются идентификаторы, которые соответствуют производству идентификаторов в синтаксисе CSS. Помимо ключевых кадров, как правило, at-правила CSS зарезервированы в основном для конфигурации более высокого уровня и управления стилями или таблицами стилей на основе «внешней» информации, то есть вне самих стилей, например кодировки символов ( @charset ) или реагирование на специфические для устройства условия ( @media ).

Кроме того, я могу придумать и похуже. Подобно тому, как использование at-rules для стилизации - одно из них, использование двух at-правил для одной и той же функции - другое. Конечно, все зависит от ваших целей: если вы хотите программно манипулировать стилями, не касаясь их лично, тогда, вероятно, есть преимущества в использовании более тупых и очевидных грамматических конструкций, которые может быть проще для синтаксического анализатора. Похоже, вы используете Stylus, поэтому мне интересно услышать вашу точку зрения о преимуществах других синтаксисов.

"extend sth" НЕ равно "match sth", это ничего не значит о структуре DOM, которую должен селектор.

Верный. Псевдоклассы с nth _something_ описываются спецификацией CSS как « структурные » псевдоклассы. Однако существует 6 других типов псевдоклассов: «динамический», «отрицание», «цель», «пустой», «состояния элемента пользовательского интерфейса» и «язык». Если бы спецификация CSS действительно описывала функцию «расширения», она могла бы довольно элегантно находиться в качестве категории между псевдоклассами «отрицание» и «цель».

Псевдоклассы допускают выбор на основе информации в дереве документа, но это, вероятно, не оптимальное использование функции расширения.

совершенно НЕПРАВИЛЬНО

Сообщество, которое больше, чем все остальные препроцессоры вместе взятые, не может ошибаться. Что тут еще можно сказать?

@hax - :extend . После нескольких недель различных предложений и обсуждений между очень опытными разработчиками интерфейса и активными пользователями LESS мы пришли к удовлетворительному решению с синтаксисом :extend . Если у вас есть предложение получше, поверьте мне - мы все слышим.

Чтобы добавить к @jonschlinkert , .this:not(.that) { } и .this:matches(.that) { } и .this:extend(.that) { } категорически похожи. То есть: «Для данного селектора 'this' свяжите его с селектором 'that' определенным образом». Поскольку LESS часто расширяет концепции и синтаксис, представленные в CSS, это довольно логичное расширение языка. Мы уделяем пристальное внимание спецификации CSS и, как следствие, отражаем ее особенности. Если в концепции есть странность, то, надеюсь, сначала она начинается с CSS. Вот почему в нашей защите миксинов «И» представлено словом «и», а «ИЛИ» представлено запятой: потому что так оно и есть в медиа-запросах. Наша цель не в том, чтобы исправлять или изменять CSS, а в том, чтобы упростить работу с CSS и сделать МЕНЬШЕ всего знакомого для авторов CSS. :extend - пример этого. Если вы знаете, как использовать :not , вы знаете, как использовать :extend .

Что, если бы мы использовали для этого более «неявный» синтаксис, чтобы избежать вложенных пар и упростить расширение параметрических миксинов?

Сегодня мы используем параметрический миксин вроде этого:

.square {
  .border-radius(9px);
}

Вместо того, чтобы расширять миксин таким образом (как вы могли бы расширить обычный класс):

.square {
  &:extend(.border-radius);
}

Мы могли бы расширить его так:

.box {
  .border-radius:extend(9px);
}
.square {
  .border-radius:extend(9px);
}
.rectangle {
  .border-radius:extend(4px);
}

Различие в том, что «расширенный миксин» заканчивается точкой с запятой и объявляет значение или значения внутри скобок, .border-radius:extend(9px); , вместо того, чтобы перечислять классы для расширения внутри скобок и начинать новый блок селектора фигурными скобками, .border-radius:extend(.some-class) {} . ИМХО, это не менее тонко, чем неявные миксины ( .border-radius; ), которые, опять же, ИМХО, являются одной из самых крутых функций LESS.

В визуализированном выводе любой «расширенный параметрический миксин» будет отображаться на месте исходного миксина, например:

.box, 
.square {
    -webkit-border-radius: 9px;
    -moz-border-radius: 9px;
    border-radius: 9px;
}
.rectangle {
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    border-radius: 4px;
}
.some-other-class, 
.another-class, 
.and-another {
    -webkit-border-radius: 2px;
    -moz-border-radius: 2px;
    border-radius: 2px;
}

Так что мне лично это нравится, потому что достаточно отклонения от «нормального» синтаксиса расширения внутри блоков селектора, чтобы сделать достаточно очевидным, что происходит, и это согласуется с тонкостью существующих меньших соглашений, где нет необходимости чрезмерно объяснять, что вы пытаетесь достичь в коде. Эта функция определенно стоит на первом месте в моем личном списке желаний.

Используя пример clearfix, который я привел в моем первоначальном запросе, вот как это будет выглядеть с моим измененным синтаксисом:

.clearfix() {
    // ...
}
.navbar {
    .clearfix:extend(); // instead of &:extend(.clearfix());
}
.banner {
    .clearfix:extend();
    &:extend(.some-class); // "implicit mixin" being extended
}

Мне нравится, к чему вы клоните. Я думаю, что более дружелюбный подход - использовать :extend в конце синтаксиса _existing_ миксина как таковой:

.box {
  .border-radius(9px):extend;
}
.square {
  .border-radius(9px):extend;
}
.rectangle {
  .border-radius(4px):extend;
}

Что-то об опускании скобок после :extend дает ощущение, что это служит другой цели, чем существующий синтаксис расширения.

Я мог бы пойти любым путем, но я предпочитаю .border-radius:extend(9px); потому что он соответствует синтаксису расширения, IMO все еще очевидно, что это миксин, но это также подразумевает, что параметры / значения расширяются, что поможет объяснить почему вывод «сгруппирован».

@jonschlinkert - на данный момент я очень высоко отношусь к вашему мнению и поддержу любое решение, которое вы считаете лучшим. Я скажу, что ваш метод чувствует себя так, как будто 9px передаются для «расширения», а не в сам миксин ... но меня это устраивает.

@DesignByOnyx спасибо за добрые слова. То, что вы говорите, имеет большой смысл, моя "линза" extends (в ​​Less) была чем-то вроде:

.this:extend(.that) {}

так что ваша точка зрения согласуется с моей собственной точкой зрения. @matthewdl или @lukeapage есть ли у кого-либо из вас какое-либо мнение / мнение по этому

Почему компилятор Less не может автоматически «делать правильные вещи»? Другими словами, если в моем коде объявлен этот миксин:

.someMixin {
    color: red;
}

А потом я использую это так:

#someElement {
    .someMixin;
}

Почему компилятор не может быть достаточно умен, чтобы оптимизировать этот код Less в этот CSS:

.someMixin,
#someElement
{
    color:red;
}

Почему я, как пользователь, должен вручную добавлять ключевое слово: extends, чтобы добиться такого поведения? Компилятор должен быть достаточно умен, чтобы понимать, что эту оптимизацию можно провести, а затем делать это.

Лично я считаю, что идея расширения сбивает с толку. Само понятие ключевого слова extends означает: «Возьмите эту вещь X и добавьте к ней A, B и C». Но в этом контексте вы предлагаете переопределить extends: «Эта вещь X на самом деле такая же, как Y, поэтому вы можете просто объявить Y и X равными и записать это один раз». Это идет вразрез со стандартным понятием «расширения» чего-либо.

Да, я думал о том же самом раньше и собирался опубликовать это, но, подумав об этом, решил, что автоматическое применение «расширенного поведения» к миксинам слишком самоуверенно для Less.js. В частности, даже несмотря на то, что наследование селекторов (расширение) - это потрясающая концепция, которая очень полезна для сокращения кода, подавляющее большинство жалоб, которые я читал по поводу этой функции, заключается в том, что она добавляет уровень абстракции, который затрудняет прочесывание кода. и отлаживать при возникновении проблем.

Так что великие умы думают одинаково, но я лично отвергаю эту идею, потому что а) мы не должны вообще связываться с «нормальными» миксинами, пока функция extend станет полностью стабильной и спецификация не станет более полной, б) Я думаю, что многие разработчики хотят сделать этот призыв для себя, и c) часто вещи кажутся такими очевидными и шаблонными, хотя суть в том, что мы забываем о многих эксцентричностях миксинов, которые сделали бы ваш предложение сложно реализовать, как минимум, и, вероятно, невозможно реализовать, в то же время позволяя разработчикам использовать все «миксин-хаки», которые мы ... кхм, они узнали и полюбили.

Синтаксис: extends () по-прежнему является довольно неуклюжим приемом, который не интуитивно понятен и сложен для объяснения новым пользователям.

Лучшее решение - просто заставить компилятор автоматически оптимизировать CSS, как описано выше, когда пользователь выбрал соответствующий стиль вывода (сжатый, оптимизированный и т. Д.). Если пользователь выбирает стиль вывода без сжатия, компилятор должен избегать этих оптимизаций и генерировать меньше СУХОГО кода.

Кроме того, вы можете решить проблемы с отладкой с исходными картами. Они могут легко указать расположение скомпилированного CSS, полученного из примеси Less.

@bdkjones создайте новый запрос функции для «автоматической оптимизации CSS» с вашими предложениями о том, как это сделать в коде. Такой вклад всегда приветствуется.

Дело принято! Я не хотел быть таким резким в своем последнем комментарии; Иногда я увлекаюсь.

Что касается кода, боюсь, я полностью занят CodeKit. Я позволил вам, ребята, избавиться от языков!

Нисколько! на самом деле, я видел, что вы участвуете в CodeKit, и хотел бы, чтобы вы продолжали вносить свой вклад. Не все функции понравятся всем, но обратная связь и твердое мнение - единственное, что заставляет крутиться колеса!

@bdkjones Проблема в каскаде. В вашем случае использования это работает, но группировка селекторов не будет иметь желаемого результата во всех случаях, поскольку она может переместить селекторы «раньше» в документе, предотвращая объявления, которые перезаписывают эти селекторы.

Но я согласен с вашими утверждениями против синтаксиса расширения миксина, поскольку он здесь развивался. Селектор X должен расширять Selector или mixin Y, поэтому это кажется странным:

.border-radius(9px):extend;

Я думаю, что мы неправильно используем синтаксис расширения. Если существующий синтаксис расширения не подходит для миксинов (что вполне правдоподобно), я бы посоветовал найти правильный синтаксис для миксинов, а не расширять синтаксис расширения таким образом, чтобы искажать метафору, как указывает @bdkjones из.

Я думаю, мы неправильно используем синтаксис расширения

Я не согласен. Если работает, пользуйтесь. Зачем создавать новые синтаксисы без причины? Я думаю, что у нас есть отличный прецедент для предлагаемого синтаксиса, я привожу множество примеров и подтверждающих аргументов в пользу своих предложений, но ваше мнение о предлагаемых синтаксисах кажется очень субъективным. И поскольку вы недавно сделали это заявление пару раз, можете ли вы объяснить, почему, по вашему мнению, злоупотребляют синтаксисом? Или объясните, в какой момент нарушается синтаксис? Или поделитесь своими мыслями о том, как следует расширять миксины, но без синтаксиса «расширения»?


В вашем случае использования это работает, но группировка селекторов не будет иметь желаемого результата во всех случаях, поскольку она может переместить селекторы «раньше» в документе, предотвращая объявления, которые перезаписывают эти селекторы.
...
Я думаю, что мы неправильно используем синтаксис расширения. Если существующий синтаксис расширения не соответствует миксинам (что вполне правдоподобно), я бы посоветовал найти правильный синтаксис для миксинов, а не расширять синтаксис расширения таким образом, чтобы искажать метафору, как указывает bdkjones. .

Нет. Он ничего не указывал, он убеждал нас упростить использование Less - в этом и заключалась его прибыль. Предложенный им способ сделать это был ошибочным, но намерение было правильным. Он не думал о каскаде, на который вы только что указали. При использовании расширения в целом вы должны учитывать каскад. Я думаю, что любой, кто использует расширение вместо миксина, знает об этом. Таким образом, поэтому Less.js предлагает вам на выбор либо использовать его, когда это имеет смысл, либо _не_, когда это не так. Тот факт, что первая буква «C» в CSS означает каскадирование, не отменяет преимущества объединения повторяющихся стилей, когда каскад не является материальным. Что мне здесь не хватает?

Не могли бы вы прояснить свое мнение? Вы против этой функции или против синтаксиса? Если вы против синтаксиса, пожалуйста, предложите что-нибудь еще, чтобы продолжить работу, иначе давайте не будем препятствовать развитию функции, которая является такой многообещающей для языка.

Вы против этой функции или против синтаксиса?

Я абсолютно за эту функцию. Это очевидное направление. Я снова рассмотрел синтаксис в этой ветке. Некоторые мысли:

Во-первых, мне неудобно:

.something:extend( .clearfix() ) { }

Двойные круглые скобки просто странные. Но это верное заимствование существующего синтаксиса расширения, так что достаточно справедливо. Вот почему я выступал за что-то еще, возможно, что-то кроме расширения.

Тогда есть то, что вы предложили, я думаю, по тем же причинам:

.border-radius(9px):extend;

... на который у меня была аллергическая реакция, потому что это кажется противоречащим существующим расширенным спецификациям. Вот где мне это показалось злоупотреблением.

НО

Я понял, что на самом деле есть два варианта. Во-первых, мы делаем что-то другое для миксинов. Но другой вариант - пересмотреть существующую спецификацию расширений для всех вещей, включая миксины, такие как:

#namespace {
  .box-template {
    .subelement {
      // we'll add the all flag to extend everything here
    }
  }
}
.clearfix() {
  // a clearfix mixin
}
.text-shadow(@shadow) {
  -moz-text-shadow: @shadow;
  text-shadow: @shadow;
}
.some .random .selector {
  // with properties
}
.mybox {
  .clearfix:extend;
  #namespace > .box-template:extend !all;
  .text-shadow:extend(2px 2px #ff0000);
  .some .random .selector:extend;
}

Но .... с полным селектором ( .some .random .selector ) он начинает читать неправильно. Похоже, что просто .selector имеет расширение. И слово «расширить» начинает теряться, когда оно является важным словом в этой декларации. Это не тот случай, когда он был написан как &:extend() (потому что он появился в начале), но этот синтаксис, похоже, ломается из-за миксинов.

Итак, я бы предложил один из этих вариантов:

// Migrating existing syntax, but ommitting a parens requirement when used with &:

.mybox {
  &:extend .clearfix;
  &:extend #namespace > .box-template !all;
  &:extend .text-shadow(2px 2px #ff0000);
  &:extend .some .random .selector;
}

// Adopting something similar to the SASS approach

.mybox {
  <strong i="24">@extend</strong> .clearfix;
  <strong i="25">@extend</strong> #namespace > .box-template !all;
  <strong i="26">@extend</strong> .text-shadow(2px 2px #ff0000);
  <strong i="27">@extend</strong> .some .random .selector;
}

Я думаю, что обсуждение расширения миксинов и медиа-запросов показало, что наш исходный синтаксический подход к :extend не так гибок, особенно когда мы хотим расширить несколько селекторов и миксинов.

Я думаю, что важно получить: правильно расширять. Если мы хотим использовать «расширение» для миксинов, я думаю, нам нужно пересмотреть синтаксис расширения.

Я не предлагал .border-radius(9px):extend; , это сделал .border-radius:extend(9px);

Но меня устраивает любой синтаксис. Или мы могли бы сделать .border-radius(9px) !extend; или .border-radius:shamallamadingdongscoobiedoo(9px):extendmyass (jk), для меня это не имеет значения, потому что ничего не меняется в поведении миксинов или вообще не расширяется.

Так что я не уверен, откуда у вас возникла необходимость делать все это, вы, вероятно, слишком усложняете себе ситуацию.

Этот запрос функции прямо связан с возможностью копировать унаследованные свойства миксина _ на место миксина_, и он будет следовать правилам, которые уже были хорошо установлены с текущим поведением миксина, и теперь также имеют приоритет и идентичное поведение с функция <strong i="14">@import</strong> (reference) (которую, кстати, я довольно часто использовал на практике и очень люблю). В двух словах:

  • Когда вы используете миксин, его свойства копируются в место селектора, вызывающего миксин.
  • Когда вы используете extension, селектор _extended_ копируется на место класса _extended_.
  • Таким образом, когда вы расширяете миксин, вызывающий селектор копируется на место миксина.

Я не уверен, почему вы вообще хотите перефразировать дебаты о синтаксисе на продление после двух лет дебатов,> 100 сообщений, большого количества исследований и уже было доказано, что он _ намного_ более гибкий, чем @extend .

Кстати, я не уверен, что вы здесь имеете в виду:

с полным селектором (.some .random .selector) он начинает читать неправильно. Похоже, что просто .selector имеет расширение. И слово «расширить» начинает теряться, когда оно является важным словом в этой декларации.

Я не согласен с тем, что это сбивает с толку, поскольку именно так это сейчас и работает. Разве это не похоже на высказывание «разработчики CSS не знают, как работают сгруппированные селекторы»? А как насчет :hover или :after ? Я думаю, что разработчики CSS могут понять это нормально, потому что он работает так же, как и другие псевдонимы.

.some .random .selector:extend(.something) {}

Мне нравится гибкость, которую это дает, поскольку я могу либо (или оба) применить расширение к селектору, то есть .some .random .selector , а не .selector , либо я могу вставить его в блок селектора.

Я думаю, что обсуждение расширения миксинов и медиа-запросов

Я закрыл проблему с медиа-запросами, потому что понял, что ее можно решить с помощью расширяющих миксинов. «Все дороги ведут к _____» расширяющимся миксинам. ;-)

Я хотел бы добавить свои два цента, чтобы сказать, что скобки внутри паренсы - :extend( .some-mixin() ) - меня не особо беспокоят, тем более что :extend( .some-selector ) уже установлен и обсуждался до тошноты. Я согласен с тем, что двойные скобки никоим образом не идеальны, и это кажется странным. Но я считаю, что важно, чтобы миксины и селекторы обрабатывались одинаково с точки зрения "расширения", почти так же, как они обрабатываются одинаково в классическом Less:

header {
    .some-selector;
    .some-mixin;
    .some-mixin();
}

Таким образом, я не чувствую себя слишком плохо (или ограниченно), делая это:

header {
    &:extend( .some-selector );
    &:extend( .some-mixin );
    &:extend( .some-mixin() );
}

Но я считаю, что важно, чтобы миксины и селекторы обрабатывались одинаково с точки зрения "расширения", почти так же, как они обрабатываются одинаково в классическом Less

Я на той же странице по этому поводу.

Я не уверен, почему вы вообще хотите перефразировать дискуссию о синтаксисе для продления после двух лет дебатов,> 100 сообщений

Дело не в желании. Нет, не хочу. Тем не менее, в то время мы как бы перемешали миксины, чтобы разобраться с ними позже. Я просто хочу задать вопрос, уверены ли мы, что этот синтаксис работает так, как мы хотим, чтобы он работал для всего. Нет ничего плохого в том, чтобы вернуться к этому вопросу, если мы чувствуем, что он не работает или неуместен для некоторых целей. LESS существует долгое время без ограничений. Более важно сделать это правильно, чем сделать это быстро.

Итак, мы в порядке с этим?

.mybox {
  &:extend(.clearfix());
  &:extend(#namespace > .box-template all);
  &:extend(.text-shadow(2px 2px #ff0000));
  &:extend(.some .random .selector);
}

паренсы внутри паренсов -: extend (.some-mixin ()) - меня не особо беспокоят, тем более что: extend (.some-selector) уже установлен

Да, правда, и на самом деле у нас уже есть прецедент двойных скобок в Less.js, И с существующим расширенным синтаксисом. И прецедент, который уже был создан, не так прост для глаз, как то, что мы предлагаем с миксинами. В настоящее время мы можем это сделать:

.one:nth-child(5) {
  color: red;
}
// We can extend psuedos
.two:extend(.one:nth-child(5)) {
  background: blue;
}
// And attributes
.two:extend(.one, [hidden]) {
  width: 2px;
}

Вы даже найдете вложенные скобки в существующем синтаксисе CSS .

Итак, здесь у нас есть синтаксис _nested parens_ и _nested pseudo-class_. И у меня с этим проблем нет, это ясно ИМО.

Итак, я согласен с @DesignByOnyx , это было мое первоначальное предложение, и по какой-то причине оно показалось другим неприятным, поэтому я пытался найти другой синтаксис. Но я полностью за то, чтобы просто использовать обычный старый синтаксис миксинов прямо внутри расширений.

Фактически, исходный синтаксис позволил бы расширить несколько классов или миксинов, разделенных запятыми.

.banner {
    &:extend(.clearfix(), .border-radius(4px), .alert, .navbar-fixed-top, [hidden]); 
}

Он выполняет свою работу, и он плотный. Никаких претензий здесь нет.

Итак, мы в порядке с этим?

Ага. полностью. Так уже и в CSS. Так что я хорошо с этим справляюсь.

Ага. полностью. Так уже и в CSS. Так что я хорошо с этим справляюсь.

ТАК БУДЕТ ПРОЙТИ.

Вопрос, я не думаю, что в настоящее время у нас есть поддержка нескольких селекторов в: extend, поэтому мне интересно, где ключевое слово «all» поместится в этом формате, но это, вероятно, должно быть частью отдельной проблемы.

Вы сделали свое дело, мистер Шлинкерт. Тебе следовало обратиться в суд. ;)

Я не думаю, что в настоящее время у нас есть поддержка нескольких селекторов в: extend

Но мы это делаем ;-) Я много этим занимался. Только что сделал это раньше:

.global-nav {
  // Extend and override bootstrap styles
  &:extend(.navbar, .navbar-fixed-top all, .navbar-inverse); // this works, and it's pretty handy
  &.hidden:extend(.navbar.hidden) {}
  &.visible:extend(.navbar.visible) {}
  &:hover {
    background: lighten(@brand-primary, 5%);
  }
  .navbar-brand {
    padding-left: 20px; 
  }
  .navbar-nav > .active > a {
    &, &:hover, &:focus {
      background-color: darken(@brand-primary, 5%);      
    }
  }
}

Вы сделали свое дело, мистер Шлинкерт. Тебе следовало обратиться в суд. ;)

Пфф, лол, остановись!

Я просто хочу добавить, что думаю такой синтаксис:

.foo {
  &:extend( .bar() );
}

отлично. Я не считаю круглые скобки неудобными.

Но в основном я просто хочу, чтобы вы, ребята, поторопились, чтобы я мог делать все классные вещи, над которыми я работаю в SASS, в моем любимом препроцессоре: D

Спасибо за отзыв, @mgerring !

+1 Жду эту фичу. Продолжайте хорошую работу :)

К исходному сообщению:

.clearfixed {
   // stuff
}
.clearfix() {
    &:extend(.clearfixed);
}
.navbar {
  .clearfix();
}
.banner {
  .clearfix();
}

Может, это не сработало во время публикации? Но в результате получается что-то очень близкое к тому, что вы хотели:

.clearfixed,
.navbar,
.banner {
  // stuff
}

@aaronmw , Да, конечно, ваш пример делает то же самое, но ключевым моментом этого предложения является возможность расширить миксин, определенный в другом месте (т.е. когда вы не можете или не хотите изменять сам миксин, например, другой файл, совместно используемый библиотека и т. д.)

Да, по мнению @ seven-phase-max, это можно сделать так, как вы описываете, но это не идиоматично.

Правильно - извините, я прочитал больше в этой ветке и посмотрел, к чему мы стремимся. Класс «скелет», который я использовал, - это просто мусор в скомпилированном выводе, потому что на класс .clearfixed никогда не будет явных ссылок вне миксина. &: extend (.clearfix ()) теперь имеет для меня смысл, и это довольно увлекательно. А пока я займусь классами скелета, засоряющими мой CSS.

Отличное обсуждение здесь!

: +1:

Итак, когда мы можем ожидать эту функцию? Для таких концепций, как OOCSS, весьма полезно создавать такие конструкции, как «абстрактный класс».

  • решить, как мы справляемся с вложением / областью действия и миксином по сравнению с обычным классом, например
.a {
  color: green;
}
#thing {
  .a() {
    color: black;
   }
}

.b:extend(#thing .a) {}  //
.b:extend(.a) {}  // and if so is the output wrapped by #thing?
.b:extend(.a()) {}  // do I need special format to say extend only that mixin?
  • мы обрабатываем аргументы? комбинировать примеси с одинаковыми аргументами?
  • измените to-css-visitor, чтобы не удалять определения миксинов
  • заставить расширенного посетителя посетить определения миксинов и создать новый набор правил с новым классом

Я думаю, что самое сложное - это действительно решить, как это должно работать.

решить, как мы справляемся с вложением / областью действия и миксином по сравнению с обычным классом, например

Я бы попытался интерпретировать расширение миксина следующим образом:
.b:extend(.a(1, 2, 3)) {} должен вести себя как создание анонимного непараметрического миксина (т.е. простого селектора) в области действия 'b', который вызывает внутри .a(1, 2, 3) и затем расширяет его обычным образом, то есть так:

.a(<strong i="11">@a</strong>, <strong i="12">@b</strong>, @c) {
    // ...
}

.b:extend(.a(1, 2, 3)) {}

должно быть равно этому:

.a(<strong i="16">@a</strong>, <strong i="17">@b</strong>, @c) {
    // ...
}

#__anon_a_1_2_3 {.a(1, 2, 3);}

.b:extend(#__anon_a_1_2_3) {}

за исключением того, что в выводе не появляется #__ anon_a_1_2_3. Я думаю, что такой подход должен сделать его менее или более простым без изобретения каких-либо специальных правил.

Итак, применив вышеуказанную концепцию к примеру #thing .a мы получим следующее:

.a {
  color: green;
}
#thing {
  .a() {
    color: black;
   }
}

.b:extend(#thing .a) {} // since we do ignore parens on mixin call and have ...
// no plans changing this (?), it should probably create .b {color: black} 

.b:extend(.a) {}  // there's only one .a in this scope so it's -> .b {color: green}

.b:extend(.a()) {}  // same as above -> .b {color: green}

С другой стороны, «необязательные скобки» - это довольно второстепенная вещь с практической точки зрения, так что можно было бы сделать ее более строгой и потребовать паренсы для параметрических миксинов внутри extend (нет никакого давления на extend чтобы унаследовать синтаксис вызова простого миксина, поскольку он в любом случае не будет полностью совместим).

комбинировать примеси с одинаковыми аргументами?

В идеале да, иначе это сделает все бесполезным, например:

.b:extend(.a()) {}
.c:extend(.a()) {}

должен создать:

.b, .c {color: green}

Хм, похоже, слияние будет сложнее всего.


Другая проблема - это область видимости, как недавно появилось в # 1730, миксины используют «относительный» путь к области видимости, а расширение использует «абсолютный», поэтому мы получаем своего рода конфликт при объединении обоих:

.div {color: green}

body {
   .div {color: red}

   p-a       {.div()}    // -> body p-a {color: red}
   p-b:extend(.div)   {} // -> body p-b {color: green}
   p-c:extend(.div()) {} // -> ???
}

И это еще больше сбивает с толку, если мы перепишем этот пример с параметрическими миксинами.

Я хотел бы предложить свои два цента, чтобы сказать, что это может быть хорошее время, чтобы сделать шаг назад и сказать «как следует использовать расширяющие миксины» - и я думаю, что @donaldpipowitch прав, говоря, что он дает немного возможностей OOCSS . Таким образом, я не думаю, что мы должны слишком увязнуть в том, как подклассы («свойства», если хотите) будут расширяться изнутри самого класса. Так, например, у пользователей будут определенные «классы» (компоненты) со «свойствами» (вложенные селекторы):

.dog() {
    .leg { ... }
    .ears { ... }
    .fur { ... }
}

Я не думаю, что нам следует сосредотачиваться на ситуациях, когда пользователь хотел бы сделать следующее:

.dog() {
    .leg { ... }
    .ears { ... }
    .fur { ... }
    .tail:extend( .leg() ) { 
        .toes { display:none; } 
    }
}

Мало того, что это случайный сценарий IMO, но пользователь в любом случае должен писать свои стили следующим образом:

.dog() {
    .leg, .tail { ... }
    .ears { ... }
    .fur { ... }
    .tail .toes { display:none; }
}

Сценарий использования 99,8% для расширения миксинов - позволить разработчикам иметь свои огромные библиотеки LESS, полные стилей, которые они накопили за эти годы. Эта огромная библиотека будет полна таких вещей, как:

.clearfix() { ... }
.modal() { ... }
.alert-box() { 
    &:extend( .modal() ); 
    &.message { ... } 
    &.warning { ... } 
    &.error { ... } 
}
.grid-wrap() { ... }
.form-input() { ... }
.form-select() { ... }
.button( <strong i="16">@bgColor</strong>, <strong i="17">@textColor</strong> ) { ... }
[... thousands more like this ...]

И они могли сосредоточиться на стилях письма:

.page-wrap:extend( .grid-wrap(), .clearfix() ) { ... }
input[type="text"]:extend( .form-input ) { ... }
textarea:extend( .form-input() );

Они могли бы даже сделать это, если бы захотели, и ни один из «модальных» стилей даже не присутствовал бы в окончательном выводе, потому что они не используются в этом проекте:

.inline-error:extend( .alert-box.error )

Да, я чувствую, что @DesignByOnyx прав . Я не думаю, что есть что-то плохое в том, чтобы позже разобраться в более сложных вещах. Фактически, я думаю, что на данный момент было бы лучше сначала реализовать расширение _just непараметрических_ примесей. Это будет охватывать, вероятно, 80-90% всех случаев использования (позволяя более объектно-ориентированную структуру таблиц стилей и т. Д.). Все остальное может подождать патч или два, имо.

@DesignByOnyx и @calvinjuarez мы не сможем понять это позже ... это должно быть так или иначе закодировано. Если мы переходим к решению, а потом решаем изменить его, мы вносим критические изменения, что нехорошо.

если мы сможем разработать подход, который не поддерживает второстепенные сценарии, я более чем счастлив, это отчасти то, что мы в конечном итоге сделали с основной расширенной поддержкой (при необходимости ее можно расширить, добавив больше ключевых слов), но нам нужен план того, что и как поддерживается.

@ seven-phase-max в вышеупомянутом ключе, я был бы счастлив пока игнорировать параметрические миксины.

Хм, похоже, слияние будет сложнее всего.

  • но это слияние? Я бы использовал тот же подход, что и существующие расширения, например, он находит совпадение и добавляется к нему ... поэтому он не сливается, а помещает оба расширения в третье место, миксин, который затем выводится как специальный дело в его genCSS

Я также думаю, что второй пример @ seven-phase-max в области видимости весьма вероятно повлияет на кого-то - вам просто нужен миксин и пустой параметрический миксин с тем же именем.

@lukeapage : +1: Верно, я могу это докопаться. Хороший звонок.

На самом деле, я думаю, что @ seven-phase-max все правильно. Итак: +1: тоже есть.

@lukeapage - я не пытался защищать "тот или иной" тип решения, а скорее подход, который (как вы сказали) не поддерживает крайние случаи. Фактически, мы уже миновали возможность «локальной» области видимости и вошли в фазу IMO «слишком поздно, чтобы возвращаться», потому что :extend работает следующим образом:

.block { color: green; }

.component {
  .block { color: red; }    
  div:extend( .block ) {};
}

/*
.block,
.component div {
  color: green;
}
.component .block {
  color: red;
}
*/

Я не вижу причин, по которым следующий код должен работать иначе, чем приведенный выше - преимущество в том, что в окончательном выводе нет класса .block :

.block() { color: green; }

.component {
  .block() { color: red; }  
  div:extend( .block() ) { };
}

/*
.component div {
  color: green;
}
*/

Между прочим, в наших соглашениях об именах есть небольшой дрейф :) например, для меня «параметрические миксины» означают любой миксин, определенный с помощью скобок, включая те, которые имеют 0 параметров (т.е. .mixin() {} является «параметрическим»). А «непараметрический» миксин - это всего лишь простой селектор (например, .mixin {} ). До сих пор я предполагаю, что этот дрейф не вызвал недоразумений (например, в большинстве приведенных выше примеров из контекста было ясно, упоминалось ли .mixin() {} как "непараметрический" миксин), но ...
Не пропустите, что в документации простой селектор также называется «миксином» (как только он добавляется), и он также является «непараметрическим» миксином по дизайну. Поэтому ссылка на .mixin() {} исключительно как на «непараметрический» может быть весьма неоднозначной (технически разница заключается в наличии или отсутствии скобок определения, а не в количестве аргументов).
Хорошо, это была моя обычная бу-бу-бу. :)

@lukeapage

Я был бы счастлив пока проигнорировать параметрические миксины.

Т.е. не поддерживает расширение для миксинов с ненулевыми параметрами? Я согласен с этим. Я просто пытался оценить, как это может быть реализовано (унифицированным образом без разделения миксинов с нулевыми и ненулевыми параметрами, так что это не будет препятствием, когда / если последний в конечном итоге появится).

но это слияние? Я бы использовал тот же подход, что и существующие расширения, например, он находит совпадение и добавляет к нему ..

Правильно, я думаю, что там я больше думал о возможных трудностях с объединением расширений миксинов с фактическими аргументами .: например:

.b:extend(.a(1, 2, 3)) {}
.c:extend(.a(1, 2, 3)) {}

С другой стороны, я подозреваю, что с миксинами с нулевыми параметрами тоже есть скрытые сюрпризы, например:

.a {color: red}
.a {width: 2px}

.b:extend(.a) {}   // creates two `.b` blocks (it is expected since there're two `.a` blocks anyway)

.c {.a}            // creates one `.c` block (OK, this is just how mixins work)

.d() {color: blue}
.d() {width: 10px}

.e {.d()}          // creates one `.e` block (OK, this is just how mixins work)

.f:extend(.d()) {} // tada! another room for complains if this creates two `.f` blocks :)

Что ж, может быть, это заходит слишком глубоко (и слишком незначительно, чтобы беспокоиться об этом в данный момент).

.f:extend(.d()) {} // tada! another room for complains if this creates two .f blocks :)

С мыслью о том, что «поскольку в этом примере .d() является параметрическим, он не должен создавать два блока .f »?

Да, я понимаю вашу точку зрения, учитывая, что миксин приведет к:

.f {
  color: #0000ff;
  width: 10px;
}

ИМХО, если есть смысл делать это поэтапно, возможно, просто объясните это, но я бы не стал _not_ реализовывать что-то, чтобы избежать жалобы как таковой. Конечно, это всего лишь мой 2с. И если это будет реализовано с описанным вами поведением, вы могли бы - во время добавления функции - также создать запрос функции для «слияния блоков CSS из расширенных селекторов», просто чтобы предотвратить жалобы ...?

но я бы не стал реализовывать что-то, чтобы избежать жалобы как таковой.

Абсолютно согласен. Я просто пытаюсь предсказать любые сюрпризы, которые могут стать одним из тех, которые «слишком поздно менять».

: +1: да, мне нравится как ты думаешь!

Мне нравится, что это обсуждение все еще продолжается. Позвольте мне вернуться к некоторым пунктам этого обсуждения. Во-первых, что касается общего использования, это было одинаково.

.mixin {} == .mixin() {}

За исключением того, что .mixin {} выводится как класс. Я знаю, что в парсере они, вероятно, обрабатываются по-другому, но при использовании они выгружают пары свойство / значение.

Имея в виду:

.mixin1() {
    color: red;    
}
.mixin2 {
    color: blue;
}
.use1 {
    .mixin1;
    foo:bar;
}
.use2 {
    .mixin2;
    foo:bar;
}

Из-за этой истории синтаксиса Less имеет смысл, что я мог бы сделать это:

.mixin1() {
    color: red;    
}
.mixin2 {
    color: blue;
}
.use1 {
    &:extend(.mixin1);
    foo:bar;
}
.use2 {
    &:extend(.mixin2);
    foo:bar;
}

Для меня это бесспорно, о чем мы часто говорили: расширение как прямая замена многих случаев использования оригинального миксина.

Для непрофессионала это, вероятно, было бы интуитивно идентично, потому что .mixin1 исторически может упоминаться следующим образом, независимо от того, написан он в круглых скобках или нет:

.use1 {
    &:extend(.mixin1);
    foo:bar;
}
.use1 {
    &:extend(.mixin1());
    foo:bar;
}

Итак, я ожидал этого:

.mixin1() {
    color: red;    
}
.use1 {
    &:extend(.mixin1());
    foo:bar;
}
.use2 {
    &:extend(.mixin1());
    bar:foo;
}

... выводить ...

.use1, .use2 {
    color: red;    
}
.use1 {
    foo:bar;
}
.use2 {
    bar:foo;
}

Если миксин определен дважды, он дважды заменяется при расширении, как и его сестра, селектор классов.

.mixin1() {
  color: red;
}
.mixin1() {
  width: 30px;
}
.use1 {
  &:extend(.mixin1);
  foo: bar;
}
.use2 {
  &:extend(.mixin1);
}
//output

.use1, .use2 {
  color: red;
}
.use1, .use2 { 
  width: 30px;
}
.use1 {
  foo: bar;
}

По сути, вот как теперь работает extension, если вы удалите круглые скобки в определениях миксинов, за исключением, конечно, того, что имя миксина появится в выводе, поэтому имеет смысл следовать существующему поведению расширения.

С параметрами (мой вариант использования 90%) то же самое, за исключением того, что они различаются по вводу:

.col(@width) {
  width: @width;
  display: table-cell;
}

.col1:extend(.col(10%)) { }
.col2:extend(.col(10%)) { }
.col3:extend(.col(80%)) { }

//output 

.col1, .col2 {
  width: 10%;
  display: table-cell;
}
.col3 {
  width: 80%;
  display: table-cell;
}

Для меня причина расширения миксинов состоит в том, чтобы сгруппировать их по параметрам, что приводит к созданию более мощных библиотек миксинов, которые могут производить очень сжатый вывод. Использование их для миксинов без параметров не так важно, так как сегодня я мог бы просто использовать существующие функции Less для получения желаемого результата.

Спасибо всем за то, что продолжаете продвигать это вперед. Я думаю, это могло бы быть довольно мощным дополнением.

: +1 Спасибо @ matthew-dean за исчерпывающий анализ - я согласен со всем, что вы рассказали. Не могли бы вы высказать свое мнение по поводу этого сценария, который является одной из тем недавнего обсуждения:

.mixin() { color: red; }

.component {
    .mixin() { color: blue; }

    > li:extend( .mixin() ) { ... }
}

Как сейчас работает LESS, расширяются только миксины в глобальной области видимости, то есть красные стили будут расширяться. Я лично согласен с таким поведением, и хотя кто-то, вероятно, напишет приведенный выше код и ожидает, что синие стили будут преобладать, я думаю, что «глобальное» поведение extends является однострочным в документации.

// this is ".mixin()", which is being extended
.mixin() { color: red; }

.component {
    // this is ".component .mixin()", which is not. 
    .mixin() { color: blue; }

    > li:extend( .mixin() ) { ... }
}

Я думаю, что «глобальное» поведение extends является однострочным в документации.

Полностью согласен. Я считаю, что вводить здесь серую зону - ужасная идея.

Для меня важна последовательность. Если текущее поведение не расширяет селекторы в локальной области видимости и не должно использовать миксины. Если позже мы расширим селекторы в local, то и миксины тоже должны. Люди должны иметь возможность доверять шаблону: extend, который распространяется на всю библиотеку.

(Хотя я мог бы просто сказать более кратко: «+1 к комментарию @jonschlinkert ». ;-)

Может ли кто-нибудь сейчас представить вариант использования, который запутал бы эту функцию? Пожалуйста, начните с этого всеобъемлющего обзора от @ matthew-dean и последующих ответов и попробуйте предложить реальную ситуацию, которая не была рассмотрена.

Счастливых праздников. Счастливого Рождества. Felices Fiestas!

Действительно хороший обзор. Я согласен с @ matthew-dean и каждым последующим комментарием. : +1:

Я также согласен с @ matthew-dean. Он кажется отличным парнем, и я хочу пожать ему руку.

(-Анонимный)

@ matthew-dean word. : +1:

С помощью этой функции мы могли бы сделать системный код сетки Bootstrap намного чище!

: +1: согласен @cvrebert! было бы здорово!

Просто возвращаюсь. Я думаю, что мы почти достигли консенсуса и просто нуждаемся в реализации, верно?

Я пытаюсь найти больше информации об этом, но это похоже на лабиринт, который все перебирает. Было ли это когда-либо реализовано? Если да, может кто-нибудь любезно указать мне на соответствующую область в документации.

@ josh18 Нет, когда запрос функции еще открыт, это обычно означает, что он не реализован.

Хорошо, спасибо, подумал, что просто дважды проверю на случай, если что-то упустил.

Я планирую в какой-то момент обобщить открытые / планируемые к реализации функции в Wiki, но у меня еще нет времени.

Я планирую в какой-то момент обобщить открытые / планируемые к реализации функции в Wiki, но у меня еще нет времени.

@ Мэтью-Дин +1

Привет, народ! Насколько я понимаю, эта функция будет чем-то похожа на заполнители SASS. Просто хотел знать, когда это будет реализовано?

Привет,
Мне сложно предсказать свое время, и других участников просто
реализовывать то, что им интересно, так что я не уверен. Все, что я могу сказать, это
что мы действительно считаем его приоритетным, это следующий важный пункт в моем списке.

Спасибо за ваш ответ. С нетерпением жду, когда это будет реализовано и заработает. :)

+1 за эту функцию. Это очень полезно для уменьшения размера CSS.

+1 за эту функцию.

+1 за эту функцию.

+1 с интересом смотрю, спасибо!

: +1:

С момента создания этой проблемы прошло ДВА ГОДА. Тег с высоким приоритетом с ноября 2014 г. Milestone - 1.6.0 или 2.0.0. Большой. Меньше сейчас 2,5.

@Grawl

Вы хотите сказать, что готовы устроить пиар?

@ seven-phase-max Это примерно то, о чем я думал. Такое проявление права. ;)

@ seven-phase-max lol нет, я просто фронтенд / дизайнер.
@Celc выглядит очень плохо 😅

С момента создания этой проблемы прошло ДВА ГОДА.

Да, вообще, за что я плачу вам, люди? ;-)

К сожалению, не могу помочь с участием, но я высоко оцениваю этот запрос!

Это чрезвычайно важная функция для построения сложных и эффективных фреймворков.

3 года и это еще не все. К счастью, скоро появится Sass v4 (с префиксными функциями sass-* ), и я могу избавиться от Less.

@stevenvachon Мы не

Конечно, запросы на включение приветствуются от кого угодно. Мы с радостью объединим функциональные запросы на вытягивание с этой функцией.

Я не пытаюсь никого обидеть, скорее, наверное, пытаюсь предотвратить такое. Я думаю, что лучше выразить то, что вы чувствуете, и новые направления, в которых они могут двигаться в результате. Я думаю, что лучше узнать раньше, чем позже; до того, как все уйдут. Например, Bootstrap v4 не будет использовать Less.js, и я уверен, что это сильно повлияет на вашу пользовательскую базу. Конечно, можно сколько угодно игнорировать такую ​​политику.

@stevenvachon почему такой оффтоп? Sass и Less великолепны. Я люблю чистый JS-код меньшего. node-sass требует установки компилятора ac, что может быть проблемой в зависимости от среды. Я использовал функцию: extend, которая уже встроена в LESS и удовлетворяет все мои потребности. Я даже не знаю, почему этот вопрос все еще открыт.

Черт возьми, я разработчик рельсов и использую gulp + LESS, когда это не проект Ruby.

Не по теме? Эта функция не была реализована в течение 3 лет и была бы очень полезной.

Я бы предпочел, чтобы Sass был написан на JS, но это не так, и это не самое главное. Его особенности есть. Sass позволяет нам расширять заполнители, но Less не позволяет нам расширять миксины.

Чувак это вообще не оффтоп, а долгожданная фича! (Хотя я бы предпочел меньше по разным причинам)

Это просто очень важно.

PS В моем случае я на самом деле дизайнер с некоторыми знаниями js, в основном связанными с dom вещами, очень далек от разработчика, который может внести свой вклад в кодовую базу less.js .. Что в любом случае печальная история)

Просто крайне заинтересованный сторонник проекта)

Объявление государственной службы

В любой момент вы можете отправить запрос на перенос или поработать с разработчиком, чтобы получить его, и очень вероятно, что эта функция будет объединена. Библиотеке Less.js требуется больше регулярных вкладов от людей, таких как люди в этом потоке . Это не ответственность какого-либо одного человека. Это полностью зависит от одного человека, который видит эту цепочку или нуждается в этой функции и не торопится, чтобы это произошло.

Если вы ответили, что вы не разработчик, то есть много ДРУГИХ способов поддержать этот проект в ролях, не связанных с разработкой, будь то предоставление необходимой документации для новых функций или поддержка дизайна на веб-сайте, выполнение тестов, предоставление отзывов. о проблемах, управлении проектами, ответах на вопросы о переполнении стека, написании сообщений в блогах, твитах о Less, участии в CSS и веб-сообществах и написании библиотек Less.

Многие из этих задач выполняются людьми, которые являются разработчиками, поэтому время, которое они могли бы внести в разработку, тратится на эти другие задачи.

Если вы _ разработчик и ваш ответ: «У меня нет времени», то это точная причина того, почему эта проблема не решена. Это на 100% зависит от вас, будет ли функция завершена, поэтому спрашивать, почему она не была завершена «кем-то», бесполезно. _Вы тот кто-то ._ Это произойдет, я _гарантируюсь_, что это произойдет, если и когда вы примете участие в этом проекте. Вы можете стать участником одного из самых популярных инструментов с открытым исходным кодом в Интернете. Вы можете изменить жизнь ... тысяч? Сотни тысяч? Миллионы? И в качестве дополнительного преимущества вы можете быть уверены, что ваши любимые функции появятся раньше, чем позже.

Если вы хотите, чтобы это или какая-то особенность произошла, сделайте это . Мы будем рады видеть вас. Мы будем рады сотрудничать с вами! Чем меньше растет это сообщество, тем меньше может становиться все лучше и лучше!

И, послушайте, я понимаю, что иногда у людей действительно совсем нет времени вносить свой вклад, и тем не менее они очень хотят, чтобы появилась какая-то особенность. Хорошо. Я бы просто сказал, что если вы находитесь в таком сценарии, вы стремитесь к сочувствию и благодарности людям, которые жертвуют свое время (а иногда и деньги), чтобы помочь вам, и я уверен, что другие люди в сообществе Less сделают все возможное, чтобы продолжают делать так, как могут.

Искренне,
Мэтью Дин, член основной группы Less.js

Я уже поддерживаю свои собственные проекты и прислушиваюсь к их пожеланиям. Честно говоря, у меня нет времени копаться в ядре Less.js.

Для тех, кто пришел сюда за поддержкой sass placeholder (или "тихого класса"), прочтите этот комментарий . Это не поможет вам полностью (из-за # 1851 и наличия таких классов не в "ссылочном" файле), но это лучше, чем ничего.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги