Skip to content

Instantly share code, notes, and snippets.

@s10wen
Last active September 22, 2016 15:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save s10wen/0318e2cc46074eaae7a70fd27691abb4 to your computer and use it in GitHub Desktop.
Save s10wen/0318e2cc46074eaae7a70fd27691abb4 to your computer and use it in GitHub Desktop.
Sass Nesting using &
  1. Nesting:
.anElement {

  &_aBlock {
    …
  }

  &_anotherBlock {
    …
  }

  &_anotherBlockAgain {

    &:hover {
      …
    }
  }
}
  1. Limiting Nesting to Pseudo Elements:
.anElement {
  …
}

.anElement_aBlock {
  …
}

.anElement_anotherBlock {
  …
}

.anElement_anotherBlockAgain {

  &:hover {
    …
  }
}
@s10wen
Copy link
Author

s10wen commented Jun 8, 2016

My issue with Nesting is I find it harder to read, if it gets long, then you have to go back and forth to check you're in the right element, where as if you have it there, then you can see it straight away.

It makes & a lot easier to understand as "ah, this is a pseudo element" rather than having to decipher if it's a nested block or a pseudo element.

I think it helps with promoting over use of nesting which can cause CSS bloat.

It's one less process for a CSS processor to do, which with 2000+ partials in the current project I'm working on, will help compile times if it was used across the whole code base.

@jaikdean
Copy link

jaikdean commented Jun 8, 2016

I'm not strongly for or against, but I like that nesting gives you one instance of anElement in the SCSS. It feels safer from typos and easier to refactor.

@thebrainroom
Copy link

thebrainroom commented Jun 8, 2016

I add inline comments (//) above the nested selector to show the output class. This also helps you search a project for a whole class.

@davidcmoulton
Copy link

I prefer to restrict nesting to pseudo-elements. Wider usage, as in the Nesting example, I've found can make it harder to read, and harder to find instances of a specific class when searching across a code base.

@adamj88
Copy link

adamj88 commented Jun 8, 2016

I'm pretty strict on DRY, personally I'd avoid repeating anElement over and over for all the classes because of points @jaikdean mentioned.

It does trade off readability and doesn't make your code base searchable for the whole class name which can make it unwieldily for large scale projects.

Source maps usually resolve the search issue though and I'd use stylelint's max-nesting-depth rule to avoid over use.

@s10wen
Copy link
Author

s10wen commented Jun 8, 2016

@davidcmoulton agreed!

@adamj88 for some context, I'm working on a 10 year legacy project with 2000+ .scss partials, so searchability is a big plus for me.

@s10wen
Copy link
Author

s10wen commented Jun 8, 2016

@jaikdean "safer from typos and easier to refactor" yeah, that's a good point.

@shaundillon
Copy link

shaundillon commented Jun 8, 2016

@thebrainroom

add inline comments (//) above the nested selector to show the output class

Never thought of this, solves the problem while keeping it DRY. A little susceptible to typos but at least they won't break the output.
Definitely going to try that.

I personally use Nesting. I like to think of anElement as a Class in the truest sense, and the contents as extensions of it.

I can absolutely see why, on a large project, this would be horribly unwieldy though, in which case, nesting pseudo only is the best solution.

@benfrain
Copy link

benfrain commented Jun 8, 2016

As you asked for input I would simply point you to rule 1 here as it encapsulates (pun intended) the way I do/don't allow nesting in ECSS.io : http://ecss.io/chapter8.html

@csswizardry
Copy link

csswizardry commented Jun 8, 2016

There are arguments on either side of the fence, depending on your use case (and one should always optimise for your use-case).

If you’re working in large or existing projects:

Prefer the longhand, e.g.:

.foo {}

  .foo__bar {}

    .foo__baz {}

…for one pretty simple reason.

With nested version, the string foo__bar doesn’t exist in your (S)CSS project, so running:

~/project/css/ $ git grep "foo__bar"

…will not yield any results. Classes are much harder to find because we’re splitting strings in half. The longhand means this doesn’t happen.

Also note the indenting; this gives me the same visual cues that nesting would (i.e. this goes inside this), with none of the drawbacks.


If you’re working in a project with a high rate of change (e.g. very iterative, prototypes, PoC):

Perhaps prefer the shorthand, e.g.:

.foo {

  &__bar {}

    &__baz {}

}

This just means that if names of things are likely to change frequently, the task is much simpler.

I tend to find this use-case is less common, so I normally tell people to stick with the longhand (and changing names in the former method is just a simple find/replace).

@csswizardry
Copy link

csswizardry commented Jun 8, 2016

@thebrainroom

I add inline comments (//) above the nested selector to show the output class. This also helps you search a project for a whole class.

You mean like:

.foo {

  // .foo__bar
  &__bar {
  }

}

?

@DaveKin
Copy link

DaveKin commented Jun 8, 2016

LONGHAND ALL THE THINGS!

Seriously - production source code should be a work of art, in structure, conventions, comments, accuracy.

Source code will inevitably need to be picked up and worked on by other people at some point (unless it's a private project that you actually want to be unfathomable).
Optimisations change over time as the browser landscape, protocols and server technology changes, accurate source code means that build systems can handle the changing requirements for optimisation.

.foo {
  &__bar {
  }
}

is fine if you're just throwing some styles together but in a large project, if I jump to: &__bar { ... on line 250 of a file, I need to scroll to the top to check which block I'm working in.

@s10wen
Copy link
Author

s10wen commented Jun 8, 2016

@csswizardry agreed, being able to easily find an element is the biggest win for me for a large project.

@13twelve
Copy link

The ability to search a codebase for a class name is super important.

anElement will be repeated in your output a number of times anyways, so being DRY I'm not sure is really a concern here.

My vote - no nesting except pseudo selectors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment