【问题标题】:how to select parent item with scss如何使用 scss 选择父项
【发布时间】:2018-05-30 21:53:26
【问题描述】:

我有以下 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;
          }
        }
      }
    }
  }
}

【问题讨论】:

  • 你不能,因为.active&lt;li&gt; 元素上的一个类。你不能用你的选择器向上遍历。
  • 恕我直言,这个问题是关于 Sass 父选择器 &amp; (以及 @at-root#{&amp;}),它存在而不是 CSS 父选择器(这个问题被关闭为欺骗和重新打开)

标签: css sass scss-mixins


【解决方案1】:

说实话,我认为您无法真正改进您提供的原始 SCSS。 Sass 父级选择器 (&amp;) 选择父级的整个链

这很尴尬,但是您可以使用@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;
          }
        }
      }
    }
  }
}

【讨论】:

    【解决方案2】:

    我认为不可能插入选择器的一部分在 Scss 中的父选择器之间以可维护的方式,但也许……

    首先,有用的文档:来自 CSS-Tricks 的the Sass Ampersand (and the 3 articles at the end!) 在众所周知的可以使用&amp; 的情况(以及不能使用的情况)和#{&amp;} 之后引用using a mixin,当你想使用@ 987654329@ 两次(我不知道后者,我用&amp;&amp;li&amp; 尝试+失败了很多次,sigh)。

    This mixin 原样对你的情况没有帮助,但这是我的看法:

    Scss mixin,它将采用 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;
    }

    如果您的目标是尽可能可维护,我建议您完全改变嵌套选择器的方式并降低它们的特异性
    以下是我将如何重写您的块:

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

    我也会用一个类来替换那个 id,即使对于你确定在页面上只存在一次的组件也是如此。在那种情况下,我抗拒了几年,这几乎和其他情况一样是一场瘟疫……

    Keep your CSS selectors short by CSSWizardry 是一个好的开始(扫描他从 2012 年到 2016 年的档案以获取更多信息) 可扩展的 CSS 方法©

    【讨论】:

      猜你喜欢
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      • 2017-12-18
      • 2019-09-22
      • 1970-01-01
      • 1970-01-01
      • 2019-01-08
      • 1970-01-01
      相关资源
      最近更新 更多