Это похоже на то, что должно быть каким-то образом осуществимо, но я просто нигде не могу найти ответ.
Можно ли с помощью SCSS указать вариант стиля элемента на основе его принадлежности к определенному предку?
Пример:
Что я хочу в CSS:
.parent1 .element,
.parent2 .element {
/* style for .element in both parents */
}
.parent1 .element {
/* special style for .element only when in parent1 */
}
Что бы я хотел делать в SCSS:
.parent1,
.parent2 {
.element {
/* style for .element in both parents */
[SOME SCSS MAGIC] {
/* special style for .element only when in parent1 */
}
}
}
В противном случае ближайшее место, где я могу разместить этот стиль, находится за пределами всего блока кода .parent1, parent2, что слишком далеко, чтобы быть удобным.






.parent1,
.parent2 {
.element {
/* common styles */
}
}
.parent1 .element {
/* parent 1 element overrides */
}
который компилируется в:
.parent1 .element,
.parent2 .element {
/* common styles */
}
.parent1 .element {
/* parent 1 element overrides */
}
Или используйте миксин для размещения общих стилей
@mixin commonStyles {
/* Common to both parent1 & parent 2 */
}
.parent1 {
.element {
@include commonStyles;
}
}
.parent2 {
.element {
@include commonStyles;
/* parent 2 specific styles */
}
}
Что компилируется в:
.parent1 .element {
/* Common to both parent1 & parent 2 */
}
.parent2 .element {
/* Common to both parent1 & parent 2 */
/* parent 2 specific styles */
}
Если вас мотивирует объединение двух наборов стилей, просто используйте два миксина.
@mixin baseStyles {
/* Common to both parent1 & parent 2 */
}
@mixin modifiedStyles {
/* parent 2 specific styles */
}
.parent1,
.parent2 {
.element {
@include baseStyles;
}
}
.parent2 {
.element {
@include modifiedStyles;
}
}
Да, @MattFryer прав. Проблема в том, что родительский стиль действительно длинный, и поэтому стиль для .element будет разделен на 100 строк между ними. Это кажется неправильным.
определите микс наверху со стилями, которые являются общими для обоих. Затем сделайте переопределения в .parent2 .element. См. Правки.
Это не отличается от определения стилей для обоих по отдельности, @IanPollak спрашивает, есть ли способ определить стили для обоих, а затем более конкретно, в одном блоке. К сожалению, я не думаю, что это возможно, сэкономило бы много времени на прокрутку :)
Другое дело, потому что рассматриваемые стили определяются только один раз.
Этого можно достичь, используя его текущую структуру и добавив конкретные стили после
Конечно, может. И без нахальства!
Дело в том, что он хочет сохранить актуальные стили вместе.
Я не буду обсуждать дальше, но это не так, потому что соответствующие стили теперь находятся в миксине (отдельно и вне блока). Проблема в ремонтопригодности, выгодно группировать стили как можно ближе друг к другу.
Интересный вопрос / обсуждение :)
Мне нравится миксин тем, что теперь у меня есть строка, в которой в основном говорится: «Посмотрите выше остальные стили этого элемента». Но в остальном у него такие же недостатки. Код разделен, и мне приходится повторять и поддерживать ту же структуру предков (.parentX .element), которая может быть намного сложнее в двух местах.
Вы можете использовать директиву @at-root:
Обновлено: удален & и заменен на .element после того, как была указана ошибка.
.parent1,
.parent2
{
.element
{
/* styles for .element in both parents */
@at-root .parent1 .element
{
/* styles for .element only when in parent1 */
}
}
}
Этот второй селектор компилируется в .parent1 .parent1 .element, .parent1 .parent2 .element?
Спасибо, я тоже это нашел, но повторяться кажется неправильным. Любые изменения в структуре предков придется вручную изменять везде, где используется @at-root. Но я думаю, это все же лучше, чем откладывать стиль в другое место. Надеюсь, что есть что-то получше.
@ksav true, & компилируется в полный селектор, поэтому его нельзя использовать. Правильным решением здесь будет @at-root .parent1 .element, который тоже кажется далеким от идеала.
Я думаю, это так близко, как вы собираетесь получить :)
@MattFryer да, не очень СУХОЕ, но, пожалуй, единственное решение.
@IanPollak По крайней мере, он сохраняет стили ближе друг к другу, поэтому вы добились некоторого улучшения (или, по крайней мере, еще один вариант, который следует рассмотреть). Однако использование этого метода может стать очень трудным для написания и сохранения специфичности в более крупных структурах, хотя простота сопровождения может перевесить это.
используйте @ корневое тело .parent1 .element
.parent1,
.parent2 {
.element {
/* style for .element in both parents */
background: yellow;
color: green;
@at-root body .parent1 .element {
color: red;
/* special style for .element only when in parent1 */
}
}
}
Да, это уже предлагалось, и пока это кажется единственным решением. Не идеально из-за повторяющегося кода.
Я бы посоветовал против этого * ... но вы можете использовать nth в списках селекторов - например:
* делает стиль менее читаемым
SCSS
.parent1,
.parent2 {
.element {
/* all items in selector list */
@at-root #{nth(&, 1)} {
/* first item in selector list */
}
@at-root #{nth(&, 2)} {
/* second item in selector list */
}
}
}
Вывод CSS
.parent1 .element,
.parent2 .element {
/* all items in selector list */
}
.parent1 .element {
/* first item in selector list */
}
.parent2 .element {
/* second item in selector list */
}
Обновлять
Чтобы сделать его более читабельным, вы можете создать вспомогательный миксин а-ля:
@mixin selector-contains($substring) {
@each $part in & {
@if str-index($part+'', $substring) {
@at-root #{$part}{ @content; }
}
}
}
.parent1,
.parent2 {
.element {
@include selector-contains('.parent1'){
/* first item in selector list */
}
@include selector-contains('.parent2'){
/* second item in selector list */
}
@include selector-contains('.parent'){
/* all elements */
}
}
}
Это то, чего OP пытался избежать.