How Bad Is It in Practice to Over-Nest Selectors in SASS/Scss

How bad is it in practice to over-nest selectors in SASS/SCSS?

It depends on how much dynamic manipulation of the DOM and styles will go on after page load. It's not page loads (mostly) or slow selectors on initial layout that are at issue, it's repaints/reflows.

Now, Steve Souders says that on the average site it's simply not a real concern. However, on a web app or highly interactive site, poorly performing CSS rules can make your repaints slower than they have to be. If you have a lot of repaints...

Experts such as Nicole Sullivan, Paul Irish, and Steve Souders have covered the way CSS interacts with with JavaScript and how to write highly performant CSS selectors. It's more than depth (different selectors have different performance), but a good rule of thumb is to limit both depth and complexity to keep yourself out of trouble--but not so much performance trouble, read on.

However, as jankfree.org notes, it's not so much descendant or specific selectors as it is certain properties in certain contexts (html5rocks.com) that make paints expensive. I see long or complicated selectors more as a maintainability issue (Nicolas Gallagher) than a performance issue--keeping in mind that maintainability interacts with performance. Highly maintainable code can iterate faster and is easier to debug (helping you find and fix performance issues).

Now, as to Sass optimization. Yes, Sass can optimize your CSS. But it cannot optimize your selectors. A 4 level nested block will be output as a 4 level nested selector. Sass cannot change it without possibly making your CSS not work. You, as the author, have to optimize the way you write Sass to optimize your output. I, personally, use nesting only in a limited way (a killer feature in Sass for me is composing styles with @extend and placeholders). However, if you really love nesting you might be able to tweak your output to some degree using the Sass parent selector reference (or the newer @at-root).

So far as I know, neither Sass nor Compass has a built-in tool to analyze selectors and warn about them. It's probably possible to create a tool to do that (set a max depth and have your pre-processor warn you) utilizing an AST. More directly, Google Page Speed does have an existing feature that provides some information. SCSS Lint has a nesting option. There's also CSS Lint. (These can theoretically be added to run in your Compass config's on_stylesheet_saved if you're not already using something like Grunt or Gulp).

Should I always nest selectors in other selectors when using sass?

You should actually avoid nesting selectors in Sass if you don't have good reason to. See Avoid Nested Selectors for more Modular CSS and Beware of Selector Nesting in Sass for why you should be more selective about nesting.

Regarding your formatting, what you're doing is functionally equivalent to nesting, but you really shouldn't be formatting your line breaks and indentations to mimic nesting when that's not what your intent is.

header
nav
.myclass {...}

and

header {
nav {
.myclass {...}
}
}

both produce:

header nav .myclass {...}

So even though scss-lint might be getting tripped up by your formatting, it's probably not something you want to be doing anyway. And if you simply aren't concerned with your nesting or selector depth, just disable or override the linters.

SASS nesting(for readability), is it a bad practice?

I would try not to directly nest them in a way that's identical to the nesting of the HTML as you're quite right, you would have an unnecessary amount of selectors in your CSS.

There is a great book on https://smacss.com/ that teaches you to split your code into modules instead. I would recommend sectioning your HTML to blocks/modules and nesting relevant selectors rather than all selectors.

Rule of thumb: the more selectors you include, the stronger priority it holds when styling.

Note: I would recommend looking into stylus as I think this improves readability over SCSS.

Nested selectors performance impact and LESS

That is correct. Browsers evaluate selectors from right to left. It will try to find a span inside a li.pinfo-box and so on.

One rule of thumb to folllow when writing LESS is: do not nest more than 3-4 levels.

This will prevent your selectors from growing to big, while you will still be able to benefit from the nesting feature in LESS.

A good example of "useless" nesting is when styling lists. Sometimes I write the selectors like this:

#wrapper .blog-post ul, #wrapper .blog-post ul li

Is it really necessary to specify that the li must be inside a ul? It will probably be enough writing:

#wrapper .blog-post li

All of this is good to know. BUT: This is not the first thing to dive into when trying to optimize your sites performance. Spend some time lower the number of request or something else instead.

SCSS: Improve performance

Good principle to remember when using the nesting feature in SASS/SCSS: Just because you can, doesn't mean you should. It's best to keep your specificity as low as possible, meaning only nest when you NEED to.

Is there any way you could pull this apart and have the rules on separate lines instead of nesting? Your error would be gone.

In terms of SCSS performance, don't worry about it. That's the point of it being a pre-processor: it does the hard work before hitting the browser. You SHOULD start worrying, though, if you use bad practice and end up bloating your CSS for the user in the browser. But I don't really see that being a concern here.

Sass .scss: Nesting and multiple classes?

You can use the parent selector reference &, it will be replaced by the parent selector after compilation:

For your example:

.container {
background:red;
&.desc{
background:blue;
}
}

/* compiles to: */
.container {
background: red;
}
.container.desc {
background: blue;
}

The & will completely resolve, so if your parent selector is nested itself, the nesting will be resolved before replacing the &.

This notation is most often used to write pseudo-elements and -classes:

.element{
&:hover{ ... }
&:nth-child(1){ ... }
}

However, you can place the & at virtually any position you like*, so the following is possible too:

.container {
background:red;
#id &{
background:blue;
}
}

/* compiles to: */
.container {
background: red;
}
#id .container {
background: blue;
}

However be aware, that this somehow breaks your nesting structure and thus may increase the effort of finding a specific rule in your stylesheet.

*: No other characters than whitespaces are allowed in front of the &. So you cannot do a direct concatenation of selector+& - #id& would throw an error.

Sass nth-child nesting

I'd be careful about trying to get too clever here. I think it's confusing as it is and using more advanced nth-child parameters will only make it more complicated. As for the background color I'd just set that to a variable.

Here goes what I came up with before I realized trying to be too clever might be a bad thing.

#romtest {
$bg: #e5e5e5;
.detailed {
th {
&:nth-child(-2n+6) {
background-color: $bg;
}
}
td {
&:nth-child(3n), &:nth-child(2), &:nth-child(7) {
background-color: $bg;
}
&.last {
&:nth-child(-2n+4){
background-color: $bg;
}
}
}
}
}

and here is a quick demo: http://codepen.io/anon/pen/BEImD

----EDIT----

Here's another approach to avoid retyping background-color:

#romtest {
%highlight {
background-color: #e5e5e5;
}
.detailed {
th {
&:nth-child(-2n+6) {
@extend %highlight;
}
}

td {
&:nth-child(3n), &:nth-child(2), &:nth-child(7) {
@extend %highlight;
}
&.last {
&:nth-child(-2n+4){
@extend %highlight;
}
}
}
}
}

Nesting with SASS does not seem to work for me?

Answer

So after a good night sleep i found the asnwer,
you guys were all right in some way and it encouraged me to look somewhere else.

The problem was that i was linking the wrong stylesheet, that i found out only after looking at the Network requests in the DevTools.

There i saw that it was loading the style.scss file, while the browser cannot read this of course. it should have been the CSS file.

So i changed the folder and file from:

<link rel="stylesheet" href="../stylesheets/scss/style.scss">

To:

<link rel="stylesheet" href="../stylesheets/css/style.css">


Related Topics



Leave a reply



Submit