提问人:Madara's Ghost 提问时间:12/11/2012 最后编辑:BoltClockMadara's Ghost 更新时间:7/20/2020 访问量:8496
在实践中,在 SASS/SCSS 中过度嵌套选择器有多糟糕?
How bad is it in practice to over-nest selectors in SASS/SCSS?
问:
我有一个 .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 个嵌套选择器”的讨论!但它到底有多有害?它对页面加载有任何明显影响吗?我所做的基准测试说不,但我缺少什么吗?
答:
这取决于页面加载后将对 DOM 和样式进行多少动态操作。问题不在于页面加载(大部分)或初始布局上的缓慢选择器,而是重绘/重排。
现在,史蒂夫·苏德斯(Steve Souders)说,在普通网站上,这根本不是一个真正的问题。但是,在 Web 应用程序或高度交互的网站上,性能不佳的 CSS 规则可能会使您的重绘速度比应有的速度慢。如果你有很多重绘......
Nicole Sullivan、Paul Irish 和 Steve Souders 等专家介绍了 CSS 与 JavaScript 的交互方式,以及如何编写高性能的 CSS 选择器。这不仅仅是深度(不同的选择器具有不同的性能),但一个好的经验法则是限制深度和复杂性,以免遇到麻烦——但不要有那么多的性能问题,请继续阅读。
然而,正如 jankfree.org 所指出的,与其说是后代或特定的选择器,不如说是某些上下文(html5rocks.com)中的某些属性使油漆变得昂贵。我认为冗长或复杂的选择器更像是一个可维护性问题(Nicolas Gallagher),而不是性能问题——请记住,可维护性与性能是相互作用的。高度可维护的代码可以更快地迭代,并且更易于调试(帮助您查找和修复性能问题)。
现在,关于Sass优化。是的,Sass 可以优化你的 CSS。但它无法优化您的选择器。一个 4 级嵌套块将作为 4 级嵌套选择器输出。Sass 无法在不使您的 CSS 无法正常工作的情况下更改它。作为作者,你必须优化你编写 Sass 的方式来优化你的输出。就我个人而言,我只以有限的方式使用嵌套(对我来说,Sass 的一个杀手锏是使用 和 占位符组合样式)。但是,如果您真的喜欢嵌套,则可以使用 Sass 父选择器引用(或较新的 @at-root)在一定程度上调整输出。@extend
据我所知,Sass 和 Compass 都没有内置工具来分析选择器并发出警告。也许可以创建一个工具来做到这一点(设置一个最大深度,并让你的预处理器警告你),利用 AST。更直接地说,Google Page Speed 确实有一个提供一些信息的现有功能。SCSS Lint 有一个嵌套选项。还有 CSS Lint。(理论上,如果您还没有使用 Grunt 或 Gulp 之类的东西,则可以将它们添加到您的 Compass 配置中运行)。on_stylesheet_saved
想想你想如何编写实际的css选择器。不要仅仅因为它是元素的子元素就嵌套所有内容。
nav li ul li a {
/* over specific, confusing */
}
.sub-menu a {
/* add a class to nested menus */
}
一旦你开始链接那么多选择器,覆盖起来就会变得很痛苦,并可能导致特异性问题。
只是为了插话并执行其他人所说的话。从性能的角度来看,这不一定是一种不好的做法(与优化选择器相比,去除模糊/阴影和圆角可能会获得更好的绘制时间增加),但从可维护性的角度来看。
选择器嵌套得越多,生成的 CSS 规则就越具体(您已经知道了)。因此,当你想在某个时候“胜过”该规则时,你必须在级联中进一步编写一个相同(或更大)特异性的规则来推翻第一个规则。如果你有一个 ID,那也会使它更加具体(所以除非你需要它们并且知道你不需要覆盖线路,否则请避免)。
为了得出合乎逻辑的结论,除非需要,否则不要嵌套。不要有这样的规则:
.selector .another .yeah-another {}
当它会做同样的工作时:
.yeah-another {}
它只是让每个人(包括您)的生活更轻松。
不要嵌套 CSS。我们觉得嵌套 css 很舒服,因为这与我们在 HTML 中所做的非常相似。嵌套为我们提供了内部的上下文。它为我们提供了对级联的一些控制。但仅此而已。.some-child
.some-parent
正如 SMACSS 所建议的那样,我会嵌套在类名中。即,用代替 或.child-of-parent
.parent .child
.parent > .child
在实践中,嵌套不当会导致页面速度极慢。了解 github 如何加快其差异页面的速度。你至少应该做的是遵循初始规则,该规则规定你不应该嵌套超过 4 个级别。
但是,我会更进一步说,我们根本不应该嵌套 CSS。我写了一篇博文,表达了我的观点。希望这是有用的。
评论
我的意见:
你告诉我你的眼睛哪个更糟
从 OP
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
评论
.if .your .nested div #is .too-deep
虽然不是直接回答你的问题,但你可以出于自己的目的保留高度嵌套的 sass,但仍然使用 .在这里查看。@at-root
.parent {
@at-root {
.child1 { ... }
.child2 { ... }
}
}
// compiles to ...
.child1 { ... }
.child2 { ... }
评论
上一个:MVC 路由如何工作?
评论
p{color:red} div{color:red}
p, div{color:red}