Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a .scss file that, among other things contains this:

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;
    }
  }
}

How bad/harmful it is in practice? I've heard many talks about "Don't go over 3 nested selectors!" But how harmful is it really? Does it have any visible impact on page loads? The benchmarks I've done say no, but is there anything I'm missing?

like image 569
Madara's Ghost Avatar asked Dec 10 '12 16:12

Madara's Ghost


People also ask

Is nesting SCSS bad?

As explained in Steven Bradley's article The Pros and Cons of Nesting Your Sass Code: There's nothing specifically wrong with nesting, but you can run into problems if you nest your code too many levels deep. For example say you have the following HTML and you want to style the link.

How many times can you nest in Sass?

A rule of the thumb is not to nest more than 4 levels. Less than four levels is preferable. Rather than so many levels of nesting, you can use it to name your selectors and still be specific.

Should you nest CSS?

Nesting will help to keep stylesheets modular and more maintainable. This is because with nesting, all styles related to a selector, children/parent selector, and even media queries can be nested in the same place. How and when you can use direct nesting and the @nest rule.

Can you nest CSS selectors?

Just like in HTML where you can have elements nested inside other elements, the same can be done in CSS. There are cases where you might want to style elements differently depending on what they are nested inside of. This is where nesting comes in handy.


3 Answers

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).

like image 149
morewry Avatar answered Nov 12 '22 22:11

morewry


Just think about how you would want to write the actual css selector. Don't nest everything just because it is a child of the element.

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

Once you start chaining that many selectors, it becomes a pain to override and can lead to specificity issues.

like image 40
ferne97 Avatar answered Nov 12 '22 23:11

ferne97


Don't nest CSS. We feel comfortable nesting css because that closely mirrors what we do in HTML. Nesting gives us context that .some-child is inside .some-parent. It gives us some control over the cascading. But not much else.

As SMACSS suggests, I would nest in class names instead. i.e, use .child-of-parent instead of .parent .child or .parent > .child

Nesting badly in practice can lead to extremely slow pages. See how github speeded up their diff pages.The least you should do is follow the inception rule which states that you shouldn't be nesting beyond 4 levels.

However, I would go one step further and say that we shouldn't nest CSS at all. I wrote a blog post with my opinions. Hope this is useful.

like image 8
user1164682 Avatar answered Nov 13 '22 00:11

user1164682