在SASS/SCSS中过度嵌套选择器在实践中有多糟糕?

Mad*_*iha 16 css performance sass css-selectors

我有一个.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;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

它在实践中有多糟糕/有害?我听过很多关于"不要超过3个嵌套选择器!"的讨论.但它真的有害吗?它是否对页面加载有明显影响?我做过的基准说不,但有什么我想念的吗?

mor*_*wry 30

这取决于页面加载后DOM和样式的动态操作量.初始布局上的页面加载(大多数情况下)或缓慢的选择器都不是问题,它是重新绘制/回流.

现在,史蒂夫·索德斯说,在普通网站上,这根本不是一个真正的问题.但是,在Web应用程序或高度交互的站点上,执行效果不佳的CSS规则会使重新绘制速度变慢.如果你有很多重绘...

Nicole Sullivan,Paul 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 Lint.(on_stylesheet_saved如果您还没有使用像Grunt或Gulp这样的东西,理论上可以添加这些以在Compass配置中运行).


fer*_*e97 9

想想你将如何编写实际的css选择器.不要因为它是元素的子元素而嵌套所有东西.

nav li ul li a { 
    /* over specific, confusing */
}
.sub-menu a {
    /* add a class to nested menus */
}
Run Code Online (Sandbox Code Playgroud)

一旦你开始链接那么多的选择器,覆盖它会变得很痛苦并且可能导致特异性问题.


小智 6

不要嵌套CSS.我们觉得嵌套css很舒服,因为这与我们在HTML中所做的非常相似.嵌套为我们提供了.some-child内部环境.some-parent.它让我们可以控制级联.但其他并不多.

正如SMACSS建议的那样,我会在类名中嵌套.即,使用.child-of-parent而不是.parent .child.parent > .child

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

但是,我会更进一步说我们不应该嵌套CSS.我写了一篇博客文章和我的意见.希望这很有用.