实际上,在SASS / SCSS中过度嵌套选择器有多严重?

css CSS

西门泡芙

2020-03-24

我有一个.scss文件,其中包含以下内容:

nav {
  font-size: 0;
  ul {
    margin: $padding/3;
  }
  li {
    z-index: 10;
    position: relative;
    display: inline-block;
    font-size: $fontSize;
    /**
     * If we want separated, Uncomment!

    margin: $padding/3;
    @include border-radius(5px);

    */
    &:first-child {
      @include border-radius(0 5px 5px 0);
    }
    &:last-child {
      @include border-radius(5px 0 0 5px);
    }
    padding: $padding/3 0;
    @include background(linear-gradient(lighten($textColor, 10%), $textColor));
    border: 1px solid lighten($textColor, 20%);
    a {
      color: $brightColor;
      padding: $padding/3 $padding;
      font-weight: bold;
      text-decoration: none;
      @include transition(.2s all);

    }
    //Nested menues
    ul {
      opacity: 0;
      //display: none;
      position: absolute;
      margin: 0;
      top: 0;
      left: 0;
      right: 0;
      z-index: 5;
      pointer-events: none;
      @include transition(.2s all);
      li {
        @include background(linear-gradient(darken($brightColor, 10%), darken($brightColor, 30%)));
        display: block;
        border: 1px solid lighten($textColor, 20%);
        &:first-child {
          @include border-radius(0);
        }
        &:last-child {
          @include border-radius(0 0 5px 5px);
        }
        a {
          color: $textColor;
        }
      }
    }
    &:hover ul {
      pointer-events: all;
      top: 100%;
      opacity: 1;
      //display: block;
    }
  }
}

在实践中有多糟糕/有害?我听过很多关于“不要超过3个嵌套选择器!”的讨论。但是它到底有多有害?它对页面加载有明显影响吗?我已经完成的基准测试拒绝了,但是我缺少什么吗?

第3451篇《实际上,在SASS / SCSS中过度嵌套选择器有多严重?》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

6个回答
小小 2020.03.24

尽管不是直接回答您的问题,但是您可以出于自己的目的保留高度嵌套的sass,但仍可以使用@at-root检查它在这里

.parent {
  @at-root {
   .child1 { ... }
   .child2 { ... }
  }
} 

// compiles to ... 

.child1 { ... }
.child2 { ... }
飞云 2020.03.24

只是为了凑合别人的意见。从性能的角度来看,这并不是一个好习惯(从优化的选择器来看,消除模糊/阴影和圆角可能会增加绘画时间,而优化选择器则不行),而是从可维护性的角度来看。

选择器嵌套得越重,生成的CSS规则(您已经知道的)就越具体。因此,当您想在某个时候“压制”该规则时,您必须在级联的下游编写一个相等(或更高)特异性的规则,以否决第一个规则。如果您在其中有一个ID,那也会使其FAR更具体(因此,请避免使用,除非您需要它们,并且知道您无需覆盖该行)。

要遵循其逻辑结论,除非需要,请不要嵌套。没有这样的规则:

.selector .another .yeah-another {}

当这将执行相同的工作时:

.yeah-another {}

它只会使所有人(包括您)的生活变得更加轻松。

小卤蛋 2020.03.24

我的想法:

你告诉你的眼睛哪一个更糟

从操作

nav li ul li a {color: $textColor;}

或已建议

.nav-menuitem-menu-menuitem-link {color: $textColor;}

所以...

问题是“在SCSS中夸大其词是不明智的做法?” (或者是SASS?)我拒绝。但这是一个辅助论点。

更糟糕的做法在于离开SASS(或者是SCSS?)输出,在它的机驱动的状态下,进行生产。

S * SS是您所有技巧中的唯一工具,与Notepad ++或Git或Chrome没什么不同。它的作用是通过引入一些非常通用的编程概念来构建一些CSS,从而使您的生活更加轻松。它的作用不是建立CSS。您不能指望它能为您完成您的工作并创建完全可用,可读,执行的输出。

尽可能多地嵌套,然后按照良好做法进行...

...之后会经过您的CSS并手动调整。使用您的超嵌套输出进行测试,构建等。当S * SS在上面创建我的第一个示例时,给该锚定一个类,并使用调用它nav .class

番长猴子 2020.03.24

不要嵌套CSS。我们感觉嵌套CSS很舒服,因为它与我们在HTML中所做的工作非常相似。嵌套为我们提供了.some-child内部的上下文.some-parent它使我们可以控制级联。但是没有其他。

正如SMACSS建议的那样,我将嵌套在类名中。即,使用.child-of-parent代替.parent .child.parent > .child

在实践中严重嵌套会导致页面非常慢。看看github如何加速他们的差异页面,至少应该做的是遵循初始规则规则规定您不应嵌套超过4个级别。

但是,我将更进一步,说我们根本不应该嵌套CSS。我写了一篇博客,发表了自己的见解。希望这是有用的。

Stafan路易 2020.03.24

只要考虑一下如何编写实际的CSS选择器即可。不要仅仅因为它是元素的子元素而嵌套所有内容。

nav li ul li a { 
    /* over specific, confusing */
}
.sub-menu a {
    /* add a class to nested menus */
}

一旦开始链接那么多选择器,就很难进行覆盖并可能导致特异性问题。

Gil 2020.03.24

这取决于页面加载后将对DOM和样式进行多少动态操作。并不是页面加载(主要是)或初始布局上出现问题的缓慢选择器,而是重涂/重排。

现在,史蒂夫·索德斯(Steve Souders)说,在一般站点上,这根本不是真正的问题但是,在Web应用程序或高度交互的网站上,性能不佳的CSS规则会使重新绘制的速度比必须的如果您有很多重涂...

Nicole SullivanPaul IrishSteve Souders这样的著名专家介绍了CSS与JavaScript交互的方式以及如何编写高性能CSS选择器。它比深度更复杂,但是一个很好的经验法则是限制深度以使自己免于麻烦,但请继续阅读,而不要涉及太多性能问题。

但是,正如jankfree.org所指出的,与其说是后代选择器,还不如说是某些上下文中的某些属性(html5rocks.com)使绘画变得昂贵。我认为长选择器更多地是可维护性问题(Nicolas Gallagher),而不是性能问题-请记住,可维护性与性能相互作用。高度可维护的代码可以更快地进行迭代,并且更易于调试(帮助您查找和修复性能问题)。

现在,关于Sass优化。是的,Sass可以优化您的CSS。但是它不能优化您的选择器4级嵌套块将作为4级嵌套选择器输出。Sass无法更改它,而不必使CSS无法工作。作为作者,您必须优化编写Sass的方式以优化输出。我个人仅以有限的方式使用嵌套(对我而言,Sass的杀手级功能是@extend占位符)。但是,如果您真的喜欢嵌套,则可以使用Sass父选择器引用(或更新的@ at-root某种程度上调整输出

据我所知,Sass和Compass都没有内置的工具来分析选择器并发出警告。可能可以创建一个工具来利用AST来做到这一点(设置最大深度并让预处理器警告您)更直接地,Google Page Speed确实具有提供某些信息的现有功能。 SCSS Lint具有嵌套选项。还有CSS Linton_stylesheet_saved如果您尚未使用Grunt或Gulp之类的工具,可以从理论上将其添加到您的Compass配置中运行)。

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android