Grow your CSS skills. Land your dream job.

Sass Style Guide

Published by Chris Coyier

With more people than ever writing in Sass, it bears some consideration how we format it. CSS style guides are common, so perhaps we can extend those to cover choices unique to Sass.

Here are some ideas that I've been gravitating toward. Perhaps they are useful to you or help you formulate ideas of your own.

Use Your Regular CSS Formatting Rules / Style Guide

This post is about Sass-specific stuff, but as a base to this, you should follow a whatever good CSS formatting guidelines you are already following. If you aren't yet, this roundup of style guides may help you. This includes things like:

  1. Be consistant with indentation
  2. Be consistant about where spaces before/after colons/braces go
  3. One selector per line, One rule per line
  4. List related properties together
  5. Have a plan for class name naming
  6. Don't use ID's #hotdrama
  7. etc

List @extend(s) First

.weather {
  @extends %module; 
  ...
}

Knowing right off the bat that this class inherits another whole set of rules from elsewhere is good.

List "Regular" Styles Next

.weather {
  @extends %module; 
  background: LightCyan;
  ..
}

List @include(s) Next

.weather {
  @extends %module; 
  background: LightCyan;
  @include transition(all 0.3s ease-out);
  ...
}

This visually separates the @extends and @includes as well as groups the @includes for easier reading. You might also want to make the call on separating user-authored @includes and vendor-provided @includes.

Nested Selectors Last

.weather {
  @extends %module; 
  background: LightCyan;
  @include transition(all 0.3s ease);
  > h3 {
    border-bottom: 1px solid white;
    @include transform(rotate(90deg));
  }
}

Nothing goes after the nested stuff. And the same order as above within the nested selector would apply.

All Vendor Prefixes Use @mixins

Vendor prefixes are a time-sensitive thing. As browsers update over time, the need for them will fall away. You can update mixins (or the libraries you use will update) to reflect those changes. Even if the mixin ends up being a one-liner, that's OK.

The only time I wouldn't @mixin a vendor prefix is when it's super proprietary, unlikely to be standardized as is, and so including other vendor prefixes or the non-prefixed version is likely to cause more harm that good. I'm thinking of things like -webkit-line-clamp or -ms-content-zoom-chaining or things like that that.

Maximum Nesting: Three Levels Deep

.weather {
  .cities {
    li {
      // no more!
    }
  }
}

Chances are, if you're deeper than that, you're writing a crappy selector. Crappy in that it's too reliant on HTML structure (fragile), overly specific (too powerful), and not very reusable (not useful). It's also on the edge of being difficult to understand.

If you really want to use tag selectors because the class thing is getting too much for you, you may want to get pretty specific about it to avoid undesired cascading. And possibly even make use of extend so it has the benefit on the CSS side of re-usability.

.weather
  > h3 {
    @extend %line-under;
  }
}

Maximum Nesting: 50 Lines

If a nested block of Sass is longer than that, there is a good chance it doesn't fit on one code editor screen, and starts becoming difficult to understand. The whole point of nesting is convenience and to assist in mental grouping. Don't use it if it hurts that.

Global and Section-Specific Sass Files Are just Table of Contents

In other words, no styles directly in them. Force yourself to keep all styles organized into component parts.

List Vendor/Global Dependancies First, Then Author Dependancies, Then Patterns, Then Parts

So the "table of contents" things comes together like:

/* Vendor Dependencies */
@import "compass";

/* Authored Dependencies */
@import "global/colors";
@import "global/mixins";

/* Patterns */
@import "global/tabs";
@import "global/modals";

/* Sections */
@import "global/header";
@import "global/footer";

The dependencies like Compass, colors, and mixins generate no compiled CSS at all, they are purely code dependancies. Listing the patterns next means that more specific "parts", which come after, have the power to override patterns without having a specificity war.

Break Into As Many Small Files As Makes Sense

There is no penalty to splitting into many small files. Do it as much as feels good to the project. I know I find it easier to jump to small specific files and navigate through them than fewer/larger ones.

...

@import "global/header/header/";
@import "global/header/logo/";
@import "global/header/dropdowns/";
@import "global/header/nav/";
@import "global/header/really-specific-thingy/";

I'd probably do this right in the global.scss, rather than have global @import a _header.scss file which has its own sub-imports. All that sub-importing could get out of hand.

Globbing might help if there starts to be too many to list.

Partials are named _partial.scss

This is a common naming convention that indicates this file isn't meant to be compiled by itself. It likely has dependancies that would make it impossible to compile by itself. Personally I like dashes in the "actual" filename though, like _dropdown-menu.scss.

Locally, Compile Expanded with Line Mapping

See here. This means dev tools can tell you exactly what file and on what line rules are coming from, even if it is an imported partial.

In Deployment, Compile Compressed

Live websites should only ever have compressed CSS.

Don't Even Commit .css Files

This might take some DevOps work, but it's pretty nice if .css files aren't even in your repository. The compilation happens during deployment. So the only thing you see in the repo are your nicely formatted hand authored Sass files. This makes the diffs useful as well. A diff is a comparison view of what changed provided by version control providers. The diff for a compressed CSS file is useless.

Be Generous With Comments

It is rare to regret leaving a comment in code. It is either helpful or easily ignorable. Comments get stripped when compiling to compressed code, so there is no cost.

.overlay {
  /* modals are 6000, saving messages are 5500, header is 2000 */
  z-index: 5000; 
}

And speaking of comments, you may want to standardize on that. The // syntax in Sass is pretty nice especially for blocks of comments, so it is easier to comment/uncomment individual lines.

Variablize All Common Numbers, and Numbers with Meaning

If you find yourself using a number other than 0 or 100% over and over, it likely deserves a variable. Since it likely has meaning and controls consistency, being able to tweak it enmasse may be useful.

If a number clearly has strong meaning, that's a use case for variablizing as well.

$zHeader: 2000;
$zOverlay: 5000;
$zMessage: 5050;

.header {
  z-index: $zHeader;
}
.overlay {
  z-index: $zOverlay;
}
.message {
  z-index: $zMessage;
}

Those numbers are probably in a separate file @import-ed as a dependency. That way you can keep track of your whole z-index stack in one place.

Variablize All Colors

Except perhaps white and black. Chances are a color isn't one-off, and even if you think it is, once it's in a variable you might see uses for it elsewhere. Variations on that color can often be handled by the Sass color functions like lighten() and darken() - which make updating colors easier (change in one place, whole color scheme updates).

Nest and Name Your Media Queries

The ability to nest media queries in Sass means 1) you don't have to re-write the selector somewhere else which can be error prone 2) the rules that you are overriding are very clear and obvious, which is usually not the case when they are at the bottom of your CSS or in a different file.

.sidebar {
  float: right;
  width: 33.33%;
  @include bp(mama-bear) {
    width: 25%;
  }
}

More on this and the importance of naming them well.

Shame Last

In your global stylesheet, @import a _shame.scss file last.

@import "compass"

...

@import "shame"

If you need to make a quick fix, you can do it here. Later when you have proper time, you can move the fix into the proper structure/organization. See more.

Final Output Is On You

Sass doesn't do anything you don't tell it to do, so claiming that Sass output is bloated is just claiming that you write bloated code. Write Sass such that the final CSS output is just as you would have written it without Sass.

Comments

  1. In higher-ed there are a ton of stakeholders, the potential for a lot of turnover, and there is a lot of inherited code. So we just recently made a CSS/SASS style guide just to keep us honest. There are still a ton of people who haven’t had the opportunity to use SASS, so while not really part of that style guide we do include a Getting Started with SASS markdown file, how we like to compile [we're all on Windows], sublime-text snippets, and so on in the anticipation that one day we’re going to move on and some poor sap will have to deal with all of our code – and what if the new person doesn’t recognize .scss?

    The other thing we did was really abstract all of our styles to the nth-degree so that a quick look at all of the _partials made it clear what the global stylesheet included. Like, you might look at the repo and see, “Oh, there’s a rule for alerts, buttons, forms, bread crumbs, but no tooltips.” This way no one actually has to crack open the stylesheet to determine if there’s a style for that.

  2. I really love the idea of the _shame.scss file, I often find myself having to shiv in ugly code hastily at the end of a project and I hate leaving it in my main styles. I definitely need to start limiting my nesting as well, it’s becoming the new “div-itis” for web designers.

    Great suggestions all around and I’ll definitely be reevaluating how I write SASS from now on!

    • Al Scott

      I like the idea of _shame.scss as well, though I find 90% of the time all my shameful things are in my _ie.scss anyway :P

    • Ha that’s too true. IE has been and continues to be the bane of my cbc existence. By the way I like the idea of being generous with comments. I was working for an SEO firm that claimed this was bad for the bots. As a programmer it just makes it easier to add notes that can easily be seen 6 months later if you need to make a quick change. Great post!

  3. Exactly how I do it funnily enough. Another point I’d make to do with nesting is try not to use tag selectors as the deepest wherever possible, just for performance reasons, even though in the nested format it can look elegant.

  4. Fantastic article, and I want to make stickers up with your closing paragraph on it and slap them on the keyboard of every developer who bitches about preprocessors producing crappy production code.

  5. Stephen

    I don’t really quite understand limiting your nesting. For exemple

    nav { 
      ul { 
        li { 
          a { 
          }
        } 
      } 
      // how is this not ok? 
    }
    
    • It makes the a at the bottom level of your next very specific which in the navigation example you mention may not be a huge problem, navigation being the one area where even in vanilla css a lot of us would write:

      nav ul li a {}. 

      But let’s say your client then adds a drop down, you will have to nest this as well and the code can quickly get confusing.

      Write some sample code, nest a few styles then try and override some of the nested styles further down the stylesheet and you’ll find the nested styles have become overly specific and cause you to either write long selectors everywhere or resort to even worse such as !important.

      Also (though less of an issue IMHO)

      It is also a slight performance hit as the browser reads styles from right to left so in this case it has to figure out

      OK this is an anchor
      and it is a subset of a list item
      and this is a subset of an unordered list
      which is a subset of a nav element

      Before it can assign the correct styles. This isn’t huge on most devices but if the browser in question is on an older phone and all your styles are nested it will make a small difference.

      By using classes and not nesting you are making your code run a bit faster which has to be a good thing.

      All that said a typical list based navigation is the one thing nesting can make sense on! Your code – your rules …

    • In addition to what Simon said, the continual nesting makes the selector unnecessarily specific. You should only nest as much as is absolutely necessary. Do the li styles REALLY depend on being inside a ul? They wouldn’t be appropriate inside an ol? And do the styles for the a tag really depend on being inside an li that’s inside a ul? You wouldn’t want those same styles if they were inside a div instead?

      If your markup is something like:

      <nav>
          <ul>
              <li>
                  <a href="#">Link</a>
               </li>
               ...
          </ul>
      </nav>
      

      Then you should try nesting your SCSS like this:

      nav {
          ul { ... }
          li { ... }
          a { ... }
      }
      

      You SCSS nesting doesn’t have to match your markup nesting exactly. It just needs to be specific enough to prevent code styles leaking into unintended elements and no more specific than that.

    • Good advice in the article, except for arbitrary nesting limit.

      I very strongly tend to think of document structure as a directed acylcic graph, which provides a formal basis for analogy with directed acyclic object graphs (a very common creature) in object-oriented programming. Limiting nesting to an arbitrary level, then, is no different than limiting the depth of an object graph to an arbitrary level. Both are nonsense.

      Dale Sande’s comment is the only justification for a nesting limit: modular CSS. The omission of that explanation in this article is glaring. However, using that approach, the nesting limit would be exactly 0 (no nesting). I dislike this approach, personally, since it doesn’t align with my DAG mental model, and instead forces a flattening of the HTML structure into the global CSS selector space.

      But the approach in the article he linked to is just one of many ways to achieve modular CSS, and it is not without it’s limitations. (I personally prefer an approach that leverages CSS’ saving grace, the child combinator, >, for performance and productivity—details on my blog, if interested.)

    • Fabrizio Calderan

      The problem here is that you’re creating a rule with an unnecessary high specificity so it’s hard to override later a rule so defined (unless you use !important, but is not a really good practice).

      Also consider the performance of what are you writing: the browser will parse that rule from right-to-left so in order to apply that style he will must check if an a element is nested into a li which is nested into an ul which is finally nested into a nav.

      Probably you might simply write

      
      nav {
            ul { ... }
            li { ... }
            a { ... }
      }
      

      if you can have more than one nav element per page you may want give that style to a specific nav, so you can assign it an idattribute or a role="navigation" attribute and you block becomes

      
      [role="navigation"] {
            ul { ... }
            li { ... }
            a { ... }
      }
      
    • Too deeply nested selectors also drops the performance of your web page/app.

  6. Great list.

    Re: Nesting – I am coming to the conclusion that “Never nest” is a good rule (in the same way and for the exact same reason “Never use IDs for style” is a good rule).

    As soon as you start nesting rules you are creating specificity headaches for your team / future self and limiting the re-useability of your styles.

    I’m also starting to try and use BEM class naming although it messes with your head at first I’m sure it is the future and nesting anything will make BEM impossible to get your head around.

    The exception to this is media queries – nesting them makes a lot of sense to me.

    I also love the commenting in sass. More and more I’ll write comments for every class:

    .classname { // Normally (if applicable), this style emphasises text etc..
    font-weight: bold;
    }

    Although this looks a pain it really forces you to think about the styles you are writing and how you may be able to reuse them in the future.

    I also keep most styles in the main .scss file with a few imports which are useful for all projects:

    _compass.scss
    _reset.scss (my own reset having tried and got frustrated with normalize too many times)
    _components.scss (a file with variables and mixins)
    _helpers.scss (things like .visuallyhidden from H5BP, clearfix etc)
    _grid.scss (my own grid based on Twitter bootstrap) if I’m using it
    _placeholders (a file full of invisible classes (%) still not sure about the best way of doing this)
    _shame.scss (such a brilliant idea!)

     

    Then put all the unique styles in one file. I tried splitting it out into Typography, structure etc but found it cost me time opening the files I needed and searching across files so went back to the one main file. If working in a team I’m sure splitting the file into partials would make a lot of sense.

    All that said I think the only thing that really matters is that your style guides / coding conventions make sense to you and your team.

  7. Using double slashes for comments also makes sure you don’t break the error messages SASS can output.

    If a block comment is near your error, it ends the block comment SASS uses for outputting the backtrace in your generated CSS file

    /*
    Syntax error: Invalid CSS after "  border": expected ";", was ": none"
            on line 5 of /var/www/claassen/uzb2/html/css/component/forms/_jobsearch.scss
            from line 35 of /var/www/claassen/uzb2/html/css/basic.scss
    
    1: /* General form styles */ <<< This comment ends the surrounding comment
    2: .form
    3: {
    4:   background: whiteSmoke
    5:   border: none
    6: }
    
    Backtrace:
    ...
    */
    
  8. Chances are, if you’re deeper than that, you’re writing a crappy selector.

    It’s so disappointing that this myth stays alive, especially in an article on sass/less (where style separation should be encouraged!). CSS will always be reliant on HTML and HTML has more responsibilities than just providing for easy css work.

    Make an abstraction of your styles and apply those abstractions to the right selector.

    • Call it a myth if you like, but I’ll call stuff like .main nav ul li a a crappy selector forever. That is the result of over nesting and it has been a pain in the ass for me many times and I’ve grown out of it.

    • cimmanon

      It’s one thing to say a selector like div.foo span a strong .bar is an awful selector because it is overly specific because div.foo .bar is just as efficient at matching the correct element. You should write the shortest selector possible to match exactly what you need. All those bytes you save add up.

      It’s another thing to say “don’t do it” because of premature optimization. Adding a class to all of your links because it’s 20ms faster than a selector like nav > ul > li > a to match the links in a top level list is just plain silly.

      Worth reading: http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/

    • Maciej Baron

      This is more about using descendant selectors rather than child selectors.

      Things like .main nav ul li a are considered bad (slow, might be problematic), however I’m not one of those people who suggest you add a class to every element in your HTML which I also consider bad.

      If you use child selectors however:

      .main>nav>ul>li>a

      (which we can now finally use because it is now safe to completely ignore IE6)

      ..then that’s better. It’s definitely a lot faster and lot clearer, and does not introduce potential unclear influences. However usually you shouldn’t have to use a selector which is that long.

      I always say, avoid extreme opinions. For instance, saying “never, never ever use ID selectors in CSS” is just stupid.

  9. Another fun thing to standardize is comment styles within your documents. Jumping into a new project where previous coders have used different comment styles to represent different sections of the code can be quite a headache.

    This style guide matches up pretty well with my own preferences, but even if someone doesn’t necessarily like it I’d still recommend sticking to some sort of guide. Consistency is important.

    /* This Could Represent A Section */
    
    /**
      * Or this 
      */
    
    // If you want your comments removed from compiled output
    
    /**
      *! This "loud comment" will stay where you added
      *! it once Sass compiles into CSS.
      */
    
  10. One quibble: @includes make more sense before plain css rules. If I’m including a button or grid mixin and want to tweak it for that style alone, I’ll need to add the rules after. Placeholder – mixin – styles arranges the code cascade from least specific to that selector to most.

    .weather {
      // Least specific. Just a block o' styles      
      @extends %module;
    
      // Semi-specific. Arguments can tailor the mixin output
      @include button(pink);
    
      // Most specific. These styles apply only to their selector, 
      // and should override everything else.
      padding: 0.9em;
      background: LightCyan;
      ..
    }
    
    • Leo Picado

      Agree 100%, mixins should come before first, leverage the cascade my friend!

    • I’d have to partly agree with you Rob. In most cases, we should take advantage of the cascade. My general rule is to actually treat includes just like regular selectors and logically group my selectors in a block, unless the includes call a mixin that I know generates a lot of rules, like the button mixin in your example.

      .weather {
        @extends %module;
        @include button(pink);
        padding: 0.9em;
        background: LightCyan;
        @include box-shadow( 0 2px 2px rgba(0, 0, 0, 0.2) );
        ...
      }
      
    • Mandy

      This is exactly what I came here to say. @extends, @includes, then your regular CSS, in alphabetical order for each. Include breaks in between if you need, but I find it easy enough to read without.

    • I agree with Mandy. I find adding CSS styles in alphabetically also helps me with organisation.

    • Yep. I go mixins first so if I need to override anything in the mixin I can. And I put extends last just so I feel like a rebel.

    • My normal case for styles first is backgrounds with gradients. Compass (as far as I know) doesn’t output a solid color fallback with gradients, so I do:

      background: #666;
      @include background(linear-gradient(#666, #333));
      
    • @Chris – If you write it as “background-color” you can put it anywhere. The order won’t matter.

    • Yeah that’s a good point. I often think of fallbacks as listed first — if the second/more progressive rule doesn’t work it falls back to previous selector. But in this case the gradient is really background-image (even as part of the background shorthand) and the solid color is background-color. So if the background-image fails it will go back to the background-color – which as you said can be set anywhere. And if the background-image succeeds, it will sit on top of the background-color anyway.

    • Good point, and clever fix.

      BTW, if you get on the autoprefixer train you won’t have to worry about that ever again :) :) :).

      https://github.com/ai/autoprefixer

    • Peter

      Kudos! I do it this way too.

  11. @Niels It was more a statement of probably than a rock-solid statement of fact hence the, “Chances are” prefix and disclaimer. A selector with more than three levels of hierarchy should be far and few between though. The navigation example, nav ul li a can be simplified to nav a. You don’t need to specify that the anchor is a descendant of a list item that is a descendant of an unordered list that is a descendant of a <nav> element.

    • @Martin Bean

      I don’t believe they are few and far between, in fact I believe they are very common. Once you start working with html components, things tend to get a lot more generic.

      Which is no problem if you make fair abstractions or your css styles (which is the point of css preprocessors). It certainly beats littering your html with useless classes that don’t carry over from project to project and only matches certain visualizations within a single project. In my eyes, that’s a bigger sin that a 6-element selector.

  12. Chad Schulz

    Isn’t there a difference in the comment used, /* comment */ vs. // comment, as to whether or not it will show up in the compiled CSS? I thought that was the case, but could be wrong.

    • Yes,
      /* this should show up when compiled */
      // this won’t

      but it depends on your chosen output type. I’d suggest minifying the CSS outputted so that it’s small going down the pipe :)

    • Todd J

      The typical /* comment */ will show up on nested, expanded, & compact outputs—but not on compressed…unless you use the !bang; e.g.

      /! Comment will be compiled in compressed output; i.e. Adding Copyright notices/

      Commenting info on sass-lang.com

  13. Nice write up. Why is it some devs always prefer classes over IDs? I’ve never fully understood this, and have personally always made a conscious effort to only use classes when those styles will be re-used somewhere else and if it’s prominent element like a sidebar or footer, or a section I might want to link to or bind an element to with jQuery, I would use IDs.

    Now that I’m writing my CSS in Sass and can use mixins, variables, and easily control the styles of the nested elements. I’m curious to what the pros/cons are of using classes over IDs?

    • Classes are preferred because CSS is for styling, and if you write your styles modularly then you’re writing them to be used potentially multiple times on a page. So, you would hook the style on a clash and not an ID.

      I know some developers swear blind to never use IDs (cough Harry Roberts cough) but I don’t mind using them in isolated cases, i.e. #content for my site’s main content wrapper.

      Also, you can hook JavaScript functionality on class names as well as IDs ;)

    • The biggest problem with using IDs in CSS is that they’re WAY too powerful in the specificity wars. If you ever write a selector that uses an ID, you’re pretty much unable to override it with any selector consisting purely of classes, unless you use 256 of them. And that would just be downright nutty.

      You might think that this is ok because “Why would I ever need to override styles on an ID? There’s only supposed to be one of them on the page!” In practice though, this often isn’t the case, especially with any kind of compound selector.

  14. Thanks for sharing this Chris. I’ve been trying to create a ‘styleguide’ that I should stick to on my repo for my starting point here – https://github.com/sturobson/a-slightly-bizarre-starting-point#sass

    I’ve also talked about how the structure of my Sass should be here –

    http://alwaystwisted.com/post.php?s=2013-01-07-structuring-my-sass-101-part-1

    http://alwaystwisted.com/post.php?s=2013-01-07-structuring-my-sass-101-part-2

    http://alwaystwisted.com/post.php?s=2013-01-08-structuring-my-sass-101-part-3

    great to see more discussion and thought on this

  15. brandon e

    Chris, if you dont commit your css files how do you compile on your development server?

    • You commit the .scss or .sass files

    • peter

      I agree, why would you want your production server to re-render the css file? I would rather have my prod not contain any sass/scss file that can be modified.

    • @peter Committing does not necessarily mean deploying. You’d ideally have a “build” process that takes care of things like compiling Sass or CoffeeScript, and doing things like concatenation, minification, asset versioning, etc. And then a “deploy” process that gets all the files to the right place.

      Jenkins (jenkins-ci.org) and CircleCI (circleci.com) are popular Continuous Integration tools for automation of such processes.

      Another option is to use something like deployhq.com

    • The major reason for us was because Git often chokes when it diffs compressed CSS files where the code is all on one line. So when two of us edit the same SASS file that then outputs different CSS and we have to merge those CSS files Git has a full-on conniption fit. Merging and maintaining master SASS files is much more manageable, and far less redundant. In addition, when individual members of a teamare using different libraries or different builds of SASS, etc., there can be issues. Compiling the CSS as a GIT post-hook ensures that everyone complies with the standard.

  16. Crispen Smith

    Always start with @includes… This seems logical up to a point. There seems to be some amount of pain that needs to be balanced between including rules within @includes that can be overridden by the places they are included. Sometimes it’s good to put them at the end to ensure that they are the last things called and don’t get overridden. While global style rules are very very good, I wonder if this is one thing to be reviewed on a case by case basis.

  17. peter

    What’s with all the >4 level deep nest hate? If this is such a huge problem, why can’t sass make a variable in config.rb that limits the top level to < 4?
    In my experience, it’s been horrible searching for a tage somewhere in a hastily named include file.

    Maybe the problem is people writing too much css.

  18. This is a great article that touches on some of the powerful features of Sass. But with great power comes great responsibility (who said that?). Anyway, I would highly suggest those who like this post to read Clean out your Sass junk-drawer.

    For many of us getting started with Sass, at one time or another have created a junk-drawer of files. For most, this was a rookie mistake, but for others, this is a continuing issue with our architecture and file management techniques. Sass doesn’t come with any real rules for file management so developers are pretty much left to their own devices.

    There is a slide deck too!

  19. I’ve gotten into the habit of keeping all z-indexes at the top of my master file right after all of my includes as they’re often the source of headache, and can get out of hand very quickly.

  20. cybercoder4life

    I’m not a fan of sass, my css is clean and efficient why reinvent the wheel, really …

  21. Good stuff. I’ve been compiling a list of best practices at http://betterfrontend.com – it’s open source so feel free to add your feedback.

  22. A note:
    You forgot the $ in front of
    zOverlay: 5000;
    zMessage: 5050;

    A suggestion:
    Use two levels of variables for colors , one to declare, and one to map.

    Example:

    /* color declarations */
    $red-1: #ff0000;
    $red-2: #890000;

    /* color mappings */
    $red-border: $red-1;
    $alert: $red-2;

    etc…

    That way you can more easily tweak colors later on without fear of how it may affect unrelated styles.

    Hope that helps!

  23. Mike

    I am a little confused, I have used SASS like this:

     h1
       font-size: 16px
    
     h2
       font-size: 13px
    
       span
          font-weight: bold
    

    Maybe it was how the developer set up the SASS… but I like this. Very clean.

    • The name of this article is a bit misleading – it says SASS where it should say SCSS.

      SASS has identical syntax to Haml but it seamed foreign to many CSS users so that in version 3 they introduced SCSS (Sassy CSS) which is the one Chris and most are using.

      You could apply most (if not all) of the concepts into your SASS workflow without to much hassle.

  24. Mike

    Ohhhhhhhhhhhhhhh.

    Title starts with “Sass Style Guide”, then the code is SCSS

    ; /

  25. Nice article Chris.

    Personally, I alphabetise my rules, so naturally my @extend goes first, @include comes second and then the rest of the styles are below. I kinda like that more than having the @include at the bottom, it separates the SASS methods from the normal pure CSS styles.

    Just a minor typo, in the code box under the ‘Variablize All Common Numbers, and Numbers with Meaning’ heading, the 2nd and 3rd variables are missing their dollar sign. They’re feeling left out.

  26. “Maximum nesting: three levels deep”. Parroting SMACSS, I would actually suggest tightening that restriction further: no selector should span more than three levels in the DOM.

    http://smacss.com/book/applicability

  27. Colby

    >

    Global and Section-Specific Sass Files Are just Table of Contents

    In other words, no styles directly in them. Force yourself to keep all styles organized into component parts.

    Could someone elaborate on this, please?

    • See the example right after the section you referenced. If you follow this guide your global (or main.scss or app.scss or whatever) should be little more than a list of imports of all the component scss files you’ve made:

      /* Vendor Dependencies */
      @import "compass";
      
      /* Authored Dependencies */
      @import "global/colors";
      @import "global/mixins";
      
      /* Patterns */
      @import "global/tabs";
      @import "global/modals";
      
      /* Sections */
      @import "global/header";
      @import "global/footer";
      

      Then your header section might have:

      @import "global/navigation"
      @import "global/logo"
      @import "global/search"
      

      If you keep your styles well organized in components, then the global and section stylesheets should act somewhat like a textbook’s table of contents, giving new coders a good idea where to find the styles they are looking for without making them dig through all of the CSS.

  28. Colby

    Dan, thank you. I got it now.

    for some reason I felt like the 2 sections contradicted each other but after you broke it down, it makes sense.

  29. chester

    What package to install to have text-highlighting for .scss in sublime text 2?
    Thanks..
    btw, on windows..

    • I recommend installing Package Control if you haven’t already. From there, just do a search for “scss” and it will pull up a number of tools, the first of which being syntax highlighting.

  30. Dan Boulet

    Variablize All Colors
    Except perhaps white and black.

    Use variables for black and white as well, even if you’re giving them values of the full #FFF and #000. You never know when you’ll want to later change it to an off-white or lighter black.

    Good related article: Design Tip: Never Use Black.

  31. I linked to this yesterday, seems to have not made the cut. I’ve written myself a ‘styleguide’ for SCSS as part of my own ‘boilerplate’.

    Basically, it’s like Chris’ here but a small variants –

    .element {
        $bg-color: #D90000;
    
        @extend .rounded-border;
    
        @include data-module;
    
        cursor: pointer;
        height: 300px;
        margin: 0 auto;
        padding: 0;
        width: 400px;
    
        &:hover {
            text-decoration:underline;
        }
    
        & > li {
            margin:10px;
        }
    
        & + ul {
            margin-left:10px;
        }
    }
    

    Also thinking about how I nest media queries I’ve decided upon this –

    .element {
        background: blue;
        display: block;
        margin: 0 auto;
        width: 44.15467%;
        h1 {
            color: green;
            font-size: 32px;
            font-size: 2rem;
        }
        .box {
            width: 80%;
            margin: 0 auto;
        }
        @media (min-width: 700px) {
            width: 100%;
            h1 {
                font-size: 48px;
                font-size: 3rem;
            }
            .box {
                width: 95%;
            }
        }
        @media (min-width: 900px) {
            h1 {
                font-size: 32px;
                font-size: 2rem;
            }
        }
    }
    

    There’s more info on how I’m doing it here – https://github.com/sturobson/a-slightly-bizarre-starting-point#sass

    I also wrote about how I’m structuring my SCSS folder back in January. The first article on that is here – http://alwaystwisted.com/post.php?s=2013-01-07-structuring-my-sass-101-part-1

  32. fchristant

    I agree with every suggestion in the article, except for one: nesting media queries. It could be just me, but I find it a horrible duplication of effort. By seperating all breakpoint-specific code in a dedicated partial, you only need to write the media query once, and you’ll have all styles specific for that breakpoint in a single file. I don’t see how fragmenting and duplicating all of that across files in any way is a best practise.

    • Smacd
      Permalink to comment#

      fchristant, it’s the type of situation where you simply need to decide which works best for you. Either fragmenting your styles for a particular element across multiple media queries, or fragmenting your media queries across multiple elements. You can’t really have both.

  33. andreas

    i have a question about the media-query.

    when you write it like in the text with a mixin, then you will have a lot of media-query in your css? when i check my styles, then this would produce approx 40 media-query in the css – as example to style the menu. isn´t that a little much overhead?

    i wouln´t suggest the @include at the end. i would make it after or before @extends. when you have it at the end, no have no choice to overwrite something if necessary.

    • The use of bubbled up media queries has been of much debate. Is this adding unnecessary code bloat? Are there performance issues? Are these issues negligible and I am simply bothered by this because my output CSS looks ugly?

      I would suggest reading Sass and Media Queries, an article I wrote last December where this argument is taken to task.

      I would also suggest listening to the interview with Chris where we discussed this topic as well. In short, when your CSS is minified, it doesn’t matter.

  34. One other thing we do, it leave a multi-line comment at the top of every partial. It makes debugging simple without having to go in and turn on line-comments on if there is an issue. Each partial then will be easy to identify when debugging later on.

    Great list of some good practices!

  35. Where do pseudo selectors go? Before or after other nested selectors?

    Also do you hold to the nested 3-levels deep rule when nesting media queries?

    Does a breakpoint media query count as another level deep?

    • What I generally do for pseudo-selectors, and any selector using the “&” symbol is write them after the descendant selectors. So, it would look something like this:

      li {  
          span { ... }
          & > a { ... }
          &:after { ... }
      }
      
      
  36. Thanks for a delightful read! And it’s good that I didn’t invest more time in writing my own SCSS style guide – it was in the making but this one says it all!

    One quick question though: How many files (patterns & sections) do you work with on a typical project?

  37. Mat

    One thing I thought of while reading this is having ‘layers’, by using mixins and variables of z-index. My zindex’s are always out control, and if I used a _shame file that’s where you’d find them!

  38. I’d submit that pseudo selectors go directly after styles pertaining to the parent selector. It’s still conceptually part of the selector itself, just wrapped in a pseudo element.

  39. Rob

    What I find useful in my CSS-LESS workflow (could also apply to SASS) is to use the deeply nested selectors to avoid !important.

    Here is a simple example:

    #elementID {
        ul {
            li {
                a {
                    // highly specific, structured to resemble the HTML
                    // only used for code that would normally be !important
                }
            }
        }
    
        // least specific, and shorter selectors
        // this is where the majority of my CSS/LESS code goes
        li {}
        a {}
    }
    

    Nesting, for me , is about code organization. Because of this, I structure the nests identical to my HTML, along with any pseudo selectors I may need. THEN, I place any selectors that can be broken out of the nest without any ill effects below the deep-nest. The “broken out” section is where I do my major coding, while keeping the nest for reference (because I don’t like switching between HTML and CSS in windows, or in my editor’s split view).

    The nice part is that any of the deep-nested selectors that I do not use (aka, they are empty), are not put into the resulting CSS file during compilation (I use WP-LESS with wordpress).

    The deep-nest acts nearly identical to !important, since they are specific. Also, since I rarely really have had the need for !important in my code (maybe 10 times at most across a whole wordpress theme), any performance issues are minimal.

    Keep in mind that this is ONLY when I am building stuff that I don’t need to reuse somewhere else in a page.

    Its really a balance that people need to find , not just for browser performance and reusability, but for personal workflow as well.

  40. Does anyone know why the SASS debugging in Chrome has stopped working?

    • Did you make sure Experimental Dev Tools was still enabled in chrome://flags and “Support for Sass” was still checked? I know one of my installs didn’t have Experimental Dev Tools enabled, and another one (which I had previously enabled Sass debugging) had Support for Sass unchecked. I don’t know if an update undid it or not, but it’s worth double-checking.

    • Permalink to comment#

      (Update, for those that find this page and haven’t gotten Chrome’s debugging working again.) I found the reason for this a couple of weeks ago. They switched to actual source mapping and no longer use the debug info or line comments. Sass, starting with 3.3.0 (which is currently in RC status) and the sourcemap branch of Compass, includes a flag to output source maps. Grab them and you can get source maps back.

      Google has a handy guide for enabling source map support, but I found it needed a browser restart to take effect (something the guide I used at the time didn’t mention).

  41. There is no penalty to splitting into many small files.

    That’s not entirely true, depending on how you’re breaking the files up.

    A good example is the structure the default Octopress theme takes. One of the ways it splits the files is by typography, theme, and layout. As such, there’s quite a bit of overlap in the selector patterns. Sass doesn’t combine these when compiling, so your final CSS can have quite a bit of selector duplication, which means the rendering engine has to find the same element(s) multiple times. This can ultimately result in a slow-down of rendering speed.

    Your fragmenting style seems less prone to it, but I. think it’s still worth remembering, so that you can continue to break up your files in ways to avoid duplicating the selectors

  42. How do you have it compiled expanded with line numbers locally and compressed on production?

    I know that in config.rb, you can specify the output_style, but that’s only for one environment. How do you accommodate both environments?

    • The config.rb file is a Ruby file, so you have access to the entire Ruby toolkit, this includes variables and if statements. Here’s the code I use in my config.rb file:

      
      output_style = (environment == :production) ? :compressed : :expanded
      line_comments = (environment == :production) ? false : true
      
      # Source Mapping
      sass_options = { 
          :debug_info => (environment == :production) ? false : true
      }
      

      Then, all you need to do is set the “environment” variable. Since this almost never changes, the quick and dirty way is just to have it declared in the file, and keep Git set as “assume-unchanged” for the config.rb file. The more robust way would be to set it elsewhere (say, a machine-level configuration), and tap into it, or if the environment isn’t set elsewhere, assume that it’s production and set it locally.

  43. Permalink to comment#

    Combining placeholders with @extend allows for very powerful design patterns that are really starting to resemble actual OO programming code.

    Consider the following Sass code :

    // Placeholder primitives
    //————————————————————————————————-
    // Placeholder primitives allow for optimal code reuse 
    // while positively impacting code readability compared
    // with native CSS code.
    
    // This sets a default border style without
    // actually drawing the border
    %border-init {
         border: 0 solid black;
    }
    
    // Draw the border
    %border-1px {
         border-width: 1px;
    }
    
    // Change the border color to red
    %border-red {
         border-color: red;
    }
    
    // Change the border color to green
    %border-green {
         border-color: green;
    }
    
    // Float to the right
    %float-right {
         float: right;
    }
    
    // Component placeholders
    //————————————————————————————————-
    // Sets default styles for the button element and
    // changes the default behavior with modifiers.
    // Each type of style is its own component placeholder
    // and references primitive placeholders
    
    // Defines borders for buttons
    %button-borders {
         @extend %border-init;
         @extend %border-1px;
    
         &.attention {
              @extend %border-red;
         }
    
         &.submit {
              @extend %border-red;
         }
    
         .sidebar & {
              @extend %border-green;
         }
    }
    
    // Defines floats for buttons
    %button-floats {
         &.submit {
              @extend %float-right;
         }
    }
    
    // Button component
    //————————————————————————————————-
    // Combines different component placeholders for the button
    
    button {
         @extend %button-borders;
         @extend %button-floats;
    }
    

    This gives the following output :

    button {
         border: 0 solid black; }
    
    button {
         border-width: 1px; }
    
    button.attention, button.submit {
         border-color: red; }
    
    .sidebar button {
         border-color: green; }
    
    button.submit {
         float: right; }
    

    Such techniques allow you to combine optimal CSS footprint and an optimal HTML footprint with easy maintenance and customisability.

    I’m currently experimenting with the codebase of [Cascade Framework](Cascade Framework “http://cascade-framework.com/”) to find the pattern most suitable for the project. The next version of Cascade Framework will probably contain a SASS version based on that pattern.

  44. sanjana
    Permalink to comment#

    I am new for SASS and stuck at one point need some help, below is my code

    .menu
    {
    Some properties
    ul li
    {
    some properties
    a
    {
    some properties
    }
    .l1 /*first item in the menu*/
    {
    background:rgba(0,0,0,3);
    }
    }
    }

    Here I am trying to give each item of menu a separate background color, but this code is not working. Please help and let me know where I am not correct.

    Thanks

    • Crispen Smith
      Permalink to comment#

      @sanjan…. looking at that I’m not sure if that’s a sass problem or an html problem. Are you planning on creating .l2, .l3 etc. and then mapping those to corresponding classes in the list items in html?

      If so, you may want to explore SASS lists as a solution, Chris has posted some great articles about that approach here at css-tricks.

  45. sanjana
    Permalink to comment#

    @Crispen: Thanks for your reply.
    Actually I am creating menu items with their class name as l1, l2 respectively and want to provide different background colors to each item. To get desire background color for each item in css file i have to write my code like this:
    .menu ul li.l1
    {
    background: red;
    }
    .menu ul li.l2
    {
    background: green;
    }

    in Sass i am trying to use nesting property and write my code like this:
    .menu
    {
    some properties
    ul li
    {
    some properties
    .l1
    {
    background: red;
    }
    }
    }

    On writing above mentioned code i am getting following css as output
    .menu ul li .l1
    {
    background: red;
    }

    and this is not setting my desired background , how can i access my menu items using sass.

  46. Permalink to comment#

    I completely disagree with your style recommendations regarding @include and @extend.

    In OOCSS it’s popular to couple the markup to the CSS rather than the CSS to the markup. This has the advantage of semi-modular code. However to couple the markup to CSS requires adding non-semantic class names to your markup. But with SASS it is possible to take these chunks of CSS and @include them into a semantic class or ID name on an element. I think the important thing is to understand what @include and @extend will do in terms of the outputted CSS, and put these lines wherever they make the most sense.

    • Johnslegers
      Permalink to comment#

      @Tom :

      “Wherever they make most sense” is vague and not very meaningful as a guideline.

      For OOCSS, SMACSS or Atomic design (which are pretty much the same design pattern with slight variations), IMO the most optimal pattern is this :

      Create an initial layer of DRY CSS with placeholders that contain a minimal amount of rules
      Add a second layer of placeholders on top to define your components, which extend the first layer.
      Add a third layer of selectors that extend the second layer. This could be both semantic or presentational selectors, depending on preference.

      That’s basicly the pattern I described hereabove, albeit in a very crude form…

    • Permalink to comment#

      @Johnslegers

      Right so my idea is basically take these 1st, 2nd, and 3rd level selectors and @include them into semantic class names as much as possible.

      This pattern of course leads to a slightly larger CSS file, but also slightly smaller HTML files. As for the “Wherever they make most sense” I guess that’s vague and not very meaningful as a guideline because I don’t think it should be part of a style guideline.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".