如何用scss选择父项

时间:2018-05-30 08:23:46

标签: css css3 sass scss-mixins

我有以下HTML:

#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;
          }
        }
      }
    }
  }
}

以下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 { // here something to actually select .nav-item.active .navlink.nav-materials
            background: red;
          }
        }
      }
    }
  }
}

这是有效的,但我希望它更易于维护/更容易阅读。如果可能的话,我希望它是这样的:

{{1}}

2 个答案:

答案 0 :(得分:0)

说实话,我不认为你可以真正改进你提供的原始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;
          }
        }
      }
    }
  }
}

答案 1 :(得分:0)

我认为以可维护的方式在中的父选择器之间插入部分选择器 ,但可能......

首先,有用的文档:the Sass Ampersand (and the 3 articles at the end!)来自CSS-Tricks引用using a mixin之后,可以使用&的公知案例(以及它不能使用的地方)以及{{1}当你想要使用#{&}两次时(我不知道后者,我尝试使用&&&多次失败,叹息 )。

This mixin 原样对你的情况无济于事,但这是我的看法:

Scss mixin ,它将采用3个参数来构建一个或另一个选择器以及任何规则块

➡️ Codepen

li&

如果您的目标是尽可能可维护,我建议您彻底改变嵌套选择器的方式并降低其特异性
这是我如何重写你的块:

➡️ Less specificity (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;
}

我也会用类替换该id,即使对于您确定只会在页面上存在一次的组件也是如此。在这种情况下,我抵抗了几年,而且与其他案件一样,它几乎和瘟疫一样......

CSSWizardry的

Keep your CSS selectors short是一个好的开始(从2012年到2016年扫描他的档案更多) 缩放©:

的CSS方法