как выбрать родительский элемент с помощью scss - PullRequest
0 голосов
/ 30 мая 2018

У меня есть следующий HTML-код:

<ul id="navbar-main" class="navbar-nav mr-auto">
    <li class="nav-item active">
        <a href="https://travian.dev/materials" class="nav-link nav-materials">
            <span class="invisible">Materials</span>
        </a>
    </li>
</ul>

И следующий SCSS:

#navbar-main {
  li {
    &.nav-item {
      .nav-link {
        width: 50px;
        height: 50px;
        background: no-repeat center;
        background-size: contain;

        &.nav-materials {
          background-image: url('../images/buttons/menu-materials.png');
        }
      }

      &.active {
        .nav-link {
          &.nav-materials {
            background: red;
          }
        }
      }
    }
  }
}

Это работает, но я бы хотел, чтобы его было легче обслуживать / легче читать.Если возможно, я бы хотел, чтобы это было так:

#navbar-main {
  li {
    &.nav-item {
      .nav-link {
        width: 50px;
        height: 50px;
        background: no-repeat center;
        background-size: contain;

        &.nav-materials {
          background-image: url('../images/buttons/menu-materials.png');

          .active { // here something to actually select .nav-item.active .navlink.nav-materials
            background: red;
          }
        }
      }
    }
  }
}

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Я не думал, что возможно вставить часть селектора между родительским селектором в Scss поддерживаемым способом , но, возможно, ...

Во-первых, полезная документация: амперсанд Sass (и 3 статьи в конце!) из ссылок CSS-Tricks с использованием миксина после хорошо известных случаев, когда можно использовать &(и там, где это невозможно), а также #{&}, когда вы хотите использовать & дважды (я не знал о последнем, и я много раз пытался + потерпеть неудачу с && и li&, вздох ).

Этот миксин как есть не поможет в вашем случае, но вот мое мнение:

Scssmixin , который будет принимать 3 параметра для построения того или иного селектора и любого блока правила

➡️ Codepen

@mixin nav-bg($parent, $active, $sel) {
  @at-root #{$parent} {
    &#{$active $sel} {
      @content;
    }
  }
}


#navbar-main {
  li {
    &.nav-item {
      .nav-link {
        width: 50px;
        height: 50px;
        background: no-repeat center;
        background-size: contain;
      }

      @include nav-bg(&, '', '.nav-materials') {
        background-image: url('../images/buttons/menu-materials.png');
      }

      @include nav-bg(&, '.active', '.nav-materials') {
        background: red;
      }
    }
  }
}


// output
#navbar-main li.nav-item .nav-link {
  width: 50px;
  height: 50px;
  background: no-repeat center;
  background-size: contain;
}
#navbar-main li.nav-item .nav-materials {
  background-image: url("../images/buttons/menu-materials.png");
}
#navbar-main li.nav-item.active .nav-materials {
  background: red;
}

Если ваша цель - максимально поддерживать 1043 *, я бы посоветовал вам полностью изменить способ размещения селекторов и уменьшить их специфичность .
Вот как я бы переписал ваш блок:

➡️ Меньше специфичности (Codepen)

#navbar-main {
  .nav-link {
    width: 50px;
    height: 50px;
    background: no-repeat center;
    background-size: contain;
  }

  .nav-materials {
    background-image: url('../images/buttons/menu-materials.png');
  }

  .active {
    .nav-materials {
      background: red;
    }
  }
}

Sass references: [@content](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#mixin-content), [@at-root](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#at-root)

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

Держите ваши CSS-селекторы короткими от CSSWizardry - хорошее начало (просканируйте его архивы из2012 - 2016 для более подробной информации) Методологии CSS , которые масштабируются * :

0 голосов
/ 30 мая 2018

Если честно, я не думаю, что вы действительно сможете улучшить оригинальную SCSS, которую вы предложили.Родительский выбор Sass (&) выбирает всю цепочку родителей.

Это довольно неудобно, но вы можете использовать @at-root, чтобы вернуться к корню таблицы стилей, изатем замените часть вашего селектора, например, так:

/// Replace `$search` with `$replace` in `$string`
/// @author Hugo Giraudel
/// @param {String} $string - Initial string
/// @param {String} $search - Substring to replace
/// @param {String} $replace ('') - New value
/// @return {String} - Updated string
@function str-replace($string, $search, $replace: '') {
  $index: str-index($string, $search);

  @if $index {
    @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
  }

  @return $string;
}

#navbar-main {
  li {
    &.nav-item {
      .nav-link {
        width: 50px;
        height: 50px;
        background: no-repeat center;
        background-size: contain;

        &.nav-materials {
          background-image: url('../images/buttons/menu-materials.png');

          @at-root #{str-replace(#{&}, ".nav-item", ".nav-item.active")} {
            background: red;
          }
        }
      }
    }
  }
}
...