我有一个.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个嵌套选择器!”的讨论。但它真的有害吗?它是否对页面加载有明显影响?我所做的基准说不,但有什么我想念的吗?
答案 0 :(得分:29)
这取决于页面加载后DOM和样式的动态操作量。初始布局上的页面加载(主要是)或slow selectors不是问题,而是重新绘制/回流。
现在,Steve Souders说on the average site it's simply not a real concern。但是,在Web应用程序或高度交互的网站上,CSS规则can make your repaints slower执行效果不佳。如果你有很多重绘......
Nicole Sullivan,Paul Irish和Steve Souders等知名专家介绍了CSS与JavaScript交互的方式以及如何编写高性能的CSS选择器。它比深度更复杂,但一个好的经验法则是限制深度以避免麻烦 - 但不要那么多性能问题,请继续阅读。
然而,正如jankfree.org所指出的那样,后代选择器并不是因为它是certain properties in certain contexts(html5rocks.com)而使油漆变得昂贵。我认为长选择器更多为a maintainability issue(Nicolas Gallagher)而不是性能问题 - 请记住可维护性与性能相互作用。高度可维护的代码可以更快地迭代并且更容易调试(帮助您查找和修复性能问题)。
现在,关于Sass优化。是的,Sass可以优化您的CSS。但它无法优化您的 选择器 。 4级嵌套块将作为4级嵌套选择器输出。 Sass无法在不使CSS无效的情况下改变它。作为作者,您必须优化编写Sass的方式以优化输出。我个人来说,只能以有限的方式使用嵌套(Sass中的杀手级功能是@extend
和占位符。但是,如果你真的喜欢嵌套,你可以使用Sass parent selector reference(或更新的@at-root)在一定程度上调整输出。
据我所知,Sass和Compass都没有内置工具来分析选择器并警告它们。使用AST创建一个工具(设置最大深度并让预处理器发出警告)可能是可能的。更直接地,Google Page Speed does具有提供某些信息的现有功能。 SCSS Lint有一个嵌套选项。还有CSS Lint。 (如果您还没有使用像Grunt或Gulp这样的东西,理论上可以在Compass配置的on_stylesheet_saved
中添加这些。)
答案 1 :(得分:9)
想想你将如何编写实际的css选择器。不要仅仅因为它是元素的子元素而嵌套所有内容。
nav li ul li a {
/* over specific, confusing */
}
.sub-menu a {
/* add a class to nested menus */
}
一旦你开始链接那么多选择器,覆盖就会变得很痛苦,并且会导致特异性问题。
答案 2 :(得分:5)
不要嵌套CSS。我们觉得嵌套css很舒服,因为这与我们在HTML中所做的非常相似。嵌套为我们提供.some-child
位于.some-parent
内的上下文。它让我们可以控制级联。但其他并不多。
正如SMACSS建议的那样,我会在类名中嵌套。即,使用.child-of-parent
代替.parent .child
或.parent > .child
在实践中严重嵌套会导致页面速度极慢。看看github如何加速他们的差异页面。你应该做的最少的就是遵循inception rule,它指出你不应该嵌套超过4个级别。
但是,我会更进一步说我们不应该嵌套CSS。我用我的意见写了一篇blog post。希望这很有用。
答案 3 :(得分:4)
只是为了加入并强制执行别人所说的话。这不是一个糟糕的做法,不一定是从性能的角度来看(从可移动性的角度来看,可能会因为去除模糊/阴影和圆角而不是优化选择器而获得更好的绘制时间增加)。
嵌套的选择器越多,生成的CSS规则(您已经知道)就越具体。因此,当你想在某个时刻“胜过”这条规则时,你必须在级联中进一步写出一个相等(或更高)特异性的规则来否决第一个规则。如果你有一个ID,那么它也会更加具体(所以除非你需要它们并且知道你不需要重写这一行)。
要遵循这个逻辑结论,除非你需要,否则不要嵌套。没有这样的规则:
.selector .another .yeah-another {}
当这会做同样的工作时:
.yeah-another {}
它让每个人(包括你)的生活变得更轻松。
答案 4 :(得分:4)
我的意见:
你告诉我 哪个更糟糕
来自op
nav li ul li a {color: $textColor;}
或按照建议
.nav-menuitem-menu-menuitem-link {color: $textColor;}
因此...
问题是“在SCSS中是否是最严重的做法?” (或者是SASS?)我说不。 但这是一个辅助论点。
WORSE 的做法在于将SASS(或SCSS?)输出留在机器驱动状态下进行生产。
S * SS只是你技巧包中的一个工具,与Notepad ++或Git或Chrome没什么区别。它的作用是通过引入一些非常通用的编程概念来构建一些css,从而使您的生活更轻松。 它的作用不是构建你的CSS。你不能指望它为你完成你的工作并创建完全可用,可读,性能的输出。
......之后会通过你的css和手调整。使用高性能输出进行测试,构建等。当S * SS在上面创建我的第一个例子时,给该锚点一个类并用nav .class
调用它。
答案 5 :(得分:1)
虽然不能直接回答您的问题,但您可以为自己的目的保留高度嵌套的sass,但仍使用@at-root
。请查看here。
.parent {
@at-root {
.child1 { ... }
.child2 { ... }
}
}
// compiles to ...
.child1 { ... }
.child2 { ... }