Подтвердить что ты не робот

LESS CSS: злоупотребление & Operator при вложенности?

Меньше использует оператор & для расширения возможностей для вложенности.

.header        { color: black;
  .navigation  { font-size: 12px;
    &.class    { text-decoration: none }
  }
}

который вызывает подстановку & родительским селектором и приводит к объединению фактического селектора справа от родительского селектора: .header .navigation.class вместо обычного добавления, что приведет к тому, что .class будет декомпенсацией: .header .navigation .class.

Теперь возможно также следующее (см. также здесь):

.header        { color: black;
  .navigation  { font-size: 12px;
    #some-id & .foo   { text-decoration: none }
  }
}

что приведет к следующему: #some-id .header .navigation .foo попробуйте здесь. Подстановка имеет место, и у меня есть добавленный селектор (#some-id) для моего родительского селектора.

Помимо того факта, что я никогда не буду кодировать этот путь, так как это, вероятно, бесполезно разрушает вашу таблицу стилей, мой вопрос:

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

4b9b3361

Ответ 1

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

Однако перед логическим аргументом я нашел еще одну короткую, простую цитату (в разделе "вложенные правила" ), которая кажется указывают, что это по крайней мере не непреднамеренно: "& представляет текущий родитель селектора". Это. Поскольку BoltClock утверждает, что добавление или добавление кажется несущественным. Все, что было предназначено, было то, что он был заполнителем для этого "родителя-селектора", который является текущим до этого момента. Тот факт, что он всегда упоминается в сочетании с использованием "гнездования" языка, подразумевает, что он предназначен для обозначения полной селекторной строки гнезда до точки гнезда, в которой он находится. Как эта строка используется (для предварительного или добавления), казалось бы, для кодера.

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

Настройка HTML для иллюстрации

Предположим, что для иллюстрации существует динамическая настройка трех возможных классов ( "светлые", "средние", "темные" темы) в элементе body, которые изменяют "внешний вид" сайта. У нас есть два столбца и некоторые типы ссылок, которые мы хотим по стилю (textLink, picLink, textWithIconLink) по-разному в каждом столбце для каждой темы.

<body class="light">
  <div class="leftCol">
     <a class="textLink"></a>
     <a class="picLink"></a>
     <a class="textWithIconLink"></a>
  </div>
  <div class="rightCol">
     <a class="textLink"></a>
     <a class="picLink"></a>
     <a class="textWithIconLink"></a>
  </div>
</body>

Теперь вопросы, которые нужно задать, - это просто посмотреть на ссылки двух следующих методов, которые...

  • меньше кода в LESS
  • Лучший органз код в МЕНЬШЕ
  • Выводит меньше кода в CSS
  • Лучший способ организовать вывод CSS

"Лучший" может быть несколько субъективным. Я позволю тебе взвесить это доказательство снизу.

Вариант №1 Типичное вложение

МЕНЬШЕ (около 99 строк кода)

/*Light Color Theme */
    .light {
      .leftCol {
        .textLink {
          color: fooL1;
          &:hover { color: barL1;}
        } 
        .picLink {
          background-image: url(/fooL1.jpg);
          &:hover { background-image: url(/barL1.jpg);}
        }
        .textWithIconLink {
          color: fooL2;
          background-image: url(/fooL2.jpg);
          &:hover { color: barL2; background-image: url(/barL2.jpg);}
        }   
      }
      .rightCol {
        .textLink {
          color: fooL3;
          &:hover { color: barL3;}
        } 
        .picLink {
          background-image: url(/fooL3.jpg);
          &:hover { background-image: url(/barL3.jpg);}
        }
        .textWithIconLink {
          color: fooL4;
          background-image: url(/fooL4.jpg);
          &:hover { color: barL4; background-image: url(/barL4.jpg);}
        }   
      }
    }
/*Medium Color Theme */
    .medium {
      .leftCol {
        .textLink {
          color: fooM1;
          &:hover { color: barM1;}
        } 
        .picLink {
          background-image: url(/fooM1.jpg);
          &:hover { background-image: url(/barM1.jpg);}
        }
        .textWithIconLink {
          color: fooM2;
          background-image: url(/fooM2.jpg);
          &:hover { color: barM2; background-image: url(/barM2.jpg);}
        }   
      }
      .rightCol {
        .textLink {
          color: fooM3;
          &:hover { color: barM3;}
        } 
        .picLink {
          background-image: url(/fooM3.jpg);
          &:hover { background-image: url(/barM3.jpg);}
        }
        .textWithIconLink {
          color: fooM4;
          background-image: url(/fooM4.jpg);
          &:hover { color: barM4; background-image: url(/barM4.jpg);}
        }   
      }
    }
/*Dark Color Theme */
    .dark {
      .leftCol {
        .textLink {
          color: fooD1;
          &:hover { color: barD1;}
        } 
        .picLink {
          background-image: url(/fooD1.jpg);
          &:hover { background-image: url(/barD1.jpg);}
        }
        .textWithIconLink {
          color: fooD2;
          background-image: url(/fooD2.jpg);
          &:hover { color: barD2; background-image: url(/barD2.jpg);}
        }   
      }
      .rightCol {
        .textLink {
          color: fooD3;
          &:hover { color: barD3;}
        } 
        .picLink {
          background-image: url(/fooD3.jpg);
          &:hover { background-image: url(/barD3.jpg);}
        }
        .textWithIconLink {
          color: fooD4;
          background-image: url(/fooD4.jpg);
          &:hover { color: barD4; background-image: url(/barD4.jpg);}
        }   
      }
    }

Выход CSS (около 87 строк вывода, организованных темой, конечно)

 /*Light Color Theme */
.light .leftCol .textLink { color:fooL1; }
.light .leftCol .textLink:hover { color:barL1; }
.light .leftCol .picLink { background-image:url(/fooL1.jpg); }
.light .leftCol .picLink:hover { background-image:url(/barL1.jpg); }
.light .leftCol .textWithIconLink {
  color:fooL2;
  background-image:url(/fooL2.jpg);
}
.light .leftCol .textWithIconLink:hover {
  color:barL2;
  background-image:url(/barL2.jpg);
}
.light .rightCol .textLink { color:fooL3; }
.light .rightCol .textLink:hover { color:barL3; }
.light .rightCol .picLink { background-image:url(/fooL3.jpg); }
.light .rightCol .picLink:hover { background-image:url(/barL3.jpg); }
.light .rightCol .textWithIconLink {
  color:fooL4;
  background-image:url(/fooL4.jpg);
}
.light .rightCol .textWithIconLink:hover {
  color:barL4;
  background-image:url(/barL4.jpg);
}
/*Medium Color Theme */
.medium .leftCol .textLink { color:fooM1; }
.medium .leftCol .textLink:hover { color:barM1; }
.medium .leftCol .picLink { background-image:url(/fooM1.jpg); }
.medium .leftCol .picLink:hover { background-image:url(/barM1.jpg); }
.medium .leftCol .textWithIconLink {
  color:fooM2;
  background-image:url(/fooM2.jpg);
}
.medium .leftCol .textWithIconLink:hover {
  color:barM2;
  background-image:url(/barM2.jpg);
}
.medium .rightCol .textLink { color:fooM3; }
.medium .rightCol .textLink:hover { color:barM3; }
.medium .rightCol .picLink { background-image:url(/fooM3.jpg); }
.medium .rightCol .picLink:hover { background-image:url(/barM3.jpg); }
.medium .rightCol .textWithIconLink {
  color:fooM4;
  background-image:url(/fooM4.jpg);
}
.medium .rightCol .textWithIconLink:hover {
  color:barM4;
  background-image:url(/barM4.jpg);
}
/*Dark Color Theme */
.dark .leftCol .textLink { color:fooD1; }
.dark .leftCol .textLink:hover { color:barD1; }
.dark .leftCol .picLink { background-image:url(/fooD1.jpg); }
.dark .leftCol .picLink:hover { background-image:url(/barD1.jpg); }
.dark .leftCol .textWithIconLink {
  color:fooD2;
  background-image:url(/fooD2.jpg);
}
.dark .leftCol .textWithIconLink:hover {
  color:barD2;
  background-image:url(/barD2.jpg);
}
.dark .rightCol .textLink { color:fooD3; }
.dark .rightCol .textLink:hover { color:barD3; }
.dark .rightCol .picLink { background-image:url(/fooD3.jpg); }
.dark .rightCol .picLink:hover { background-image:url(/barD3.jpg); }
.dark .rightCol .textWithIconLink {
  color:fooD4;
  background-image:url(/fooD4.jpg);
}
.dark .rightCol .textWithIconLink:hover {
  color:barD4;
  background-image:url(/barD4.jpg);
}

Вариант № 2 Конечная целевая группировка

Я назвал его "End Target Grouping", потому что это действительно так, как я вижу использование & другим способом добавления родительских селекторов. Один из них теперь кодируется на основе конечного конечного целевого элемента, который на самом деле оформлен в стиле.

МЕНЬШЕ (около 88 строк кода)

/*Links */
/*Text  Links*/
.textLink {
  .light .leftCol &  {
      color: fooL1;
      &:hover { color: barL1;}
    }      
  .light .rightCol &  {
      color: fooL3;
      &:hover { color: barL3;}
    } 
  .medium .leftCol &  {
      color: fooM1;
      &:hover { color: barM1;}
    } 
  .medium .rightCol &  {
      color: fooM3;
      &:hover { color: barM3;}
    } 
  .dark .leftCol &  {
      color: fooD1;
      &:hover { color: barD1;}
    } 
  .dark .rightCol &  {
      color: fooD3;
      &:hover { color: barD3;}
    } 
}
/*Picture Links */
.picLink {
  .light .leftCol &  {
      background-image: url(/fooL1.jpg);
      &:hover { background-image: url(/barL1.jpg);}
    } 
  .light .rightCol &  {
      background-image: url(/fooL3.jpg);
      &:hover { background-image: url(/barL3.jpg);}
    } 
  .medium .leftCol &  {
      background-image: url(/fooM1.jpg);
      &:hover { background-image: url(/barM1.jpg);}
    } 
  .medium .rightCol &  {
      background-image: url(/fooM3.jpg);
      &:hover { background-image: url(/barM3.jpg);}
    } 
  .dark .leftCol &  {
      background-image: url(/fooD1.jpg);
      &:hover { background-image: url(/barD1.jpg);}
    } 
  .dark .rightCol &  {
      background-image: url(/fooD3.jpg);
      &:hover { background-image: url(/barD3.jpg);}
    } 
}
/*Text with Icon Links */
.textWithIconLink {
  .light .leftCol &  {
      color: fooL2;
      background-image: url(/fooL1.jpg);
      &:hover { color: barL2; background-image: url(/barL1.jpg);}
    } 
  .light .rightCol &  {
      color: fooL4;
      background-image: url(/fooL3.jpg);
      &:hover { color: barL4;  background-image: url(/barL3.jpg);}
    } 
  .medium .leftCol &  {
      color: fooM2;
      background-image: url(/fooM1.jpg);
      &:hover { color: barM2; background-image: url(/barM1.jpg);}
    } 
  .medium .rightCol &  {
     color: fooM4;
      background-image: url(/fooM3.jpg);
      &:hover { color: barM4; background-image: url(/barM3.jpg);}
    } 
  .dark .leftCol &  {
     color: fooD2;
      background-image: url(/fooD1.jpg);
      &:hover { color: barD2; background-image: url(/barD1.jpg);}
    } 
  .dark .rightCol &  {
      color: fooD4;
      background-image: url(/fooD3.jpg);
      &:hover { color: barD4; background-image: url(/barD3.jpg);}
    } 
}

CSS (около 88 строк вывода [из-за одного дополнительного комментария], организованного конечным целевым элементом, но заметьте, что по-прежнему существует суборганизация по теме из-за структуры класса)

/*Links*/
/*Text  Links*/
.light .leftCol .textLink { color:fooL1; }
.light .leftCol .textLink:hover { color:barL1; }
.light .rightCol .textLink { color:fooL3; }
.light .rightCol .textLink:hover { color:barL3; }
.medium .leftCol .textLink { color:fooM1; }
.medium .leftCol .textLink:hover { color:barM1; }
.medium .rightCol .textLink { color:fooM3; }
.medium .rightCol .textLink:hover { color:barM3; }
.dark .leftCol .textLink { color:fooD1; }
.dark .leftCol .textLink:hover { color:barD1; }
.dark .rightCol .textLink { color:fooD3; }
.dark .rightCol .textLink:hover { color:barD3; }
/*Picture Links */
.light .leftCol .picLink { background-image:url(/fooL1.jpg); }
.light .leftCol .picLink:hover { background-image:url(/barL1.jpg); }
.light .rightCol .picLink { background-image:url(/fooL3.jpg); }
.light .rightCol .picLink:hover { background-image:url(/barL3.jpg); }
.medium .leftCol .picLink { background-image:url(/fooM1.jpg); }
.medium .leftCol .picLink:hover { background-image:url(/barM1.jpg); }
.medium .rightCol .picLink { background-image:url(/fooM3.jpg); }
.medium .rightCol .picLink:hover { background-image:url(/barM3.jpg); }
.dark .leftCol .picLink { background-image:url(/fooD1.jpg); }
.dark .leftCol .picLink:hover { background-image:url(/barD1.jpg); }
.dark .rightCol .picLink { background-image:url(/fooD3.jpg); }
.dark .rightCol .picLink:hover { background-image:url(/barD3.jpg); }
/*Text with Icon Links */
.light .leftCol .textWithIconLink {
  color:fooL2;
  background-image:url(/fooL1.jpg);
}
.light .leftCol .textWithIconLink:hover {
  color:barL2;
  background-image:url(/barL1.jpg);
}
.light .rightCol .textWithIconLink {
  color:fooL4;
  background-image:url(/fooL3.jpg);
}
.light .rightCol .textWithIconLink:hover {
  color:barL4;
  background-image:url(/barL3.jpg);
}
.medium .leftCol .textWithIconLink {
  color:fooM2;
  background-image:url(/fooM1.jpg);
}
.medium .leftCol .textWithIconLink:hover {
  color:barM2;
  background-image:url(/barM1.jpg);
}
.medium .rightCol .textWithIconLink {
  color:fooM4;
  background-image:url(/fooM3.jpg);
}
.medium .rightCol .textWithIconLink:hover {
  color:barM4;
  background-image:url(/barM3.jpg);
}
.dark .leftCol .textWithIconLink {
  color:fooD2;
  background-image:url(/fooD1.jpg);
}
.dark .leftCol .textWithIconLink:hover {
  color:barD2;
  background-image:url(/barD1.jpg);
}
.dark .rightCol .textWithIconLink {
  color:fooD4;
  background-image:url(/fooD3.jpg);
}
.dark .rightCol .textWithIconLink:hover {
  color:barD4;
  background-image:url(/barD3.jpg);
}

Заключительные мысли

Несколько других соображений:

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

Во-вторых, любой "стандартный" код для типа элемента определен выше любого кода темы. Мои примеры не показали этого, но говорят, что все элементы .textLink имеют text-decoration: none;. Это произойдет один раз в Параметре №2 без какого-либо дополнительного кода выбора и появится выше всех изменений темы ниже. Для варианта №1 мне нужно настроить новый, неинтересный селектор .textLink (по крайней мере, еще одну строку кода), чтобы применить его ко всем тематическим ссылкам, и что "базовый" код для класса снова будет где-то не связанный с тем, где находится остальная часть кода для информации о ссылке на тему.

В-третьих, как разработчик, если у меня возникают проблемы с моим picLinks (конкретным типом элемента на моей странице), опция № 2 упрощает анализ моего кода для элемента, с которым возникают проблемы, так как весь мой код для всех тем прямо в одном месте.

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

Ответ 2

Это не злоупотребление комбинатором &; вы можете поместить его где угодно во вложенном селекторе, и он будет заменен всем, что над ним (его так называемый родительский селектор):

[Комбинатор &] используется, когда вы хотите, чтобы вложенный селектор был объединен с родительским селектором вместо того, чтобы действовать как потомок.

Обратите внимание, что в нем сказано "конкатенировано"; он не говорит, что вы можете либо добавлять, либо добавлять родительский селектор к вложенному селектору. Конкатенация не работает только в каком-либо конкретном направлении.

Кроме того, слово "потомок" связано с тем, что природа вложенных селекторов обрабатывается по умолчанию, как если бы они были связаны комбинатором потомков. Ни в коем случае это не ограничивает использование только & только потомками, а также не подразумевает, что родительский селектор должен представлять родительский или предковый элемент таким образом, что вложенный селектор может быть добавлен к нему, а не добавлен или даже вставлен в середину.