Skip to content

Instantly share code, notes, and snippets.

@bcherny
Last active August 29, 2015 14:02
Show Gist options
  • Save bcherny/7a8296e4f154d145ee51 to your computer and use it in GitHub Desktop.
Save bcherny/7a8296e4f154d145ee51 to your computer and use it in GitHub Desktop.
SASS style guide

Contents

Hoisting

  • Hoist style definition when possible for performance and maintainability:
// good
.foo {
   ul {
      list-style: none;
      text-align: center;
   }
   li {}
}

// bad
.foo {
   ul {}
   li {
      list-style: none;
      text-align: center;
   }
}

Nesting

  • Avoid excessive nesting and overspecified selectors:
// good
.foo {

   heading {
      ...
   }
   
   h1 {
      ...
   }
   
   .title {
      ...
   }
   
}

// bad
.foo {
   heading {
      ...
      
      h1 {
         ...
         
         > span.title {
            ...
         }
      }
   }
}

Variables

Colors and Dimensions

  • Define colors in terms of one another whenever possible:
// good
div {
   $color-danger: #f00;

   border-color: lighten($color-danger, 3%);
   color: $color-danger;
}

// bad
div {
   border-color: #ff1515;
   color: #f00;
}
  • Avoid variables named after the color, use semantic color names instead:
// good
$color-danger: #f00;
$color-subtle: #ccc;

// bad
$red: #f00;
$light-grey: #ccc;

Cursors

  • Use global variables for cursor definitions, so that designers can more easily modify cursor styles:
// good
$CURSOR_POINTER: pointer;
$CURSOR_RESIZE: resize;

.link {
   cursor: $CURSOR_POINTER;

   &.resize {
      cursor: $CURSOR_RESIZE;
   }
}

// bad
.link {
   cursor: pointer;

   &.resize {
      cursor: resize;
   }
}

Fonts

  • Font families should be defined once as global variables. This is to avoid a proliferation of similar font declarations, and to let designers to easily tweak font faces across the site:
// good
$FONT_SANS_SERIF: Helvetica, Arial, sans-serif;

div {
   font-family: $FONT_SANS_SERIF;
}

.foo {
   font-family: $FONT_SANS_SERIF;
}

// bad
div {
   font-family: Helvetica, Arial, sans-serif;
}

.foo {
   font-family: Helvetica;
}

Prefixing

  • Variables should pre prefixed with their type, when it makes sense:
// good
$color-danger: red;
$width-container: 800px;

// bad
$danger: red;
$container: 800px;

Scope

  • Variables names should be SNAKE_CASED globals if they are used across top-level selectors (eg. brand colors or input widths), or as dash-cased local variables if they are used multiple times locally:
// good
$COLOR_DANGER: #f00;
$INPUT_WIDTH: 400px;

div {
   color: $COLOR_DANGER;
}

.foo {
   $border-color: lighten($COLOR_DANGER, 3%);

   border-color: $border-color;
   width: $INPUT_WIDTH;

   &:hover {
      border-color: lighten($border-color, 5%);
   }
}

// bad
div {
   color: #f00;
}

.foo {
   border-color: #ff1515;
   width: 400px;
}

Vendor prefixing

  • Since we use autoprefixer to add vendor prefixes for us, avoid using vendor prefixing mixins:
// good
.foo {
   box-shadow: 1px 1px 1px $shadow;
   transition: all .1s ease-in;
}

// bad
.foo {
   @include box-shadow(1px 1px 1px $shadow);
   @include transition(all .1s ease-in);
}

// bad
.foo {
   -webkit-box-shadow: 1px 1px 1px $shadow;
      -moz-box-shadow: 1px 1px 1px $shadow;
       -ms-box-shadow: 1px 1px 1px $shadow;
        -o-box-shadow: 1px 1px 1px $shadow;
           box-shadow: 1px 1px 1px $shadow;

   -webkit-transition: all .1s ease-in;
      -moz-transition: all .1s ease-in;
       -ms-transition: all .1s ease-in;
        -o-transition: all .1s ease-in;
           transition: all .1s ease-in;
}
@2013gang
Copy link

Local variable may still be worth to exist even it is ONLY used once locally. Because we may use it in higher/lower hierarchy in the future. e.g.

div {
   $SOME_COLOR: #f00;
   color: $SOME_COLOR;  // Only used once, seems not worthy to make a variable $red
}

but later we may have this:

div {
   $SOME_COLOR: #f00;
   color: $SOME_COLOR; 
   .some-new-class {
        color: $SOME_COLOR;
    }
}

@bcherny
Copy link
Author

bcherny commented Jun 18, 2014

@2013gang I think we should refactor when necessary, to avoid clutter when it's not needed.

@chriszheng81
Copy link

one thing that gets discussed frequently is nesting all vs nesting where necessary vs no nesting. I personally prefer nesting where necessary + indentation. I think this will help keep our styles readable but also improve the quality of the css it produces. Let me know your thoughts.

@chriszheng81
Copy link

For global variables, it may make sense to keep them in one separate file so it is more maintainable

@bcherny
Copy link
Author

bcherny commented Jun 18, 2014

@chriszheng81 can you give examples for what you mean?

@chriszheng81
Copy link

For example, instead of doing
body {
.wrapper {
.content {
.title {
a {
/* STYLES HERE */
}
}
}
}
},

we may want to do
body {
}
.wrapper {
}
.content {
}
.title {
a {
/* STYLES HERE */
}
}

@chriszheng81
Copy link

damn it removed my indentation

@chriszheng81
Copy link

anyway, the point is that, we should only nest when it's necessary. We shouldn't strictly follow the same structure as the HTML when we do nesting. We could use proper indentations to indicate the structure for readability. We should also try to keep nesting to no more than 3 levels. Anything more than that probably means your css is overly specific and not very reusable.

@hannaxbear
Copy link

I agree with Boris about the refactoring when necessary for variables and I agree with Chris about the nesting.

Let's also decide on a standard for using "px" or not. I don't really have a preference, but I suspect Boris likes not using "px".

@bcherny
Copy link
Author

bcherny commented Jun 19, 2014

@chris

I agree about less nesting. How would you phrase it, given it's less cut and dry than the other rules?

Also, you can use three backticks for code in comments - see https://help.github.com/articles/github-flavored-markdown :)

@Hanna

According to the spec it's optional. So,

pros:

  • helps maintain context for what units should be used

cons:

  • clutter
  • semantically no difference between 0px, 0%, or 0cm, so the unit is arbitrary

Copy link

ghost commented Jun 19, 2014

Should global variable be all uppercase charactors? $sans-serif -> $SANS-SERIF?

@bcherny
Copy link
Author

bcherny commented Jun 19, 2014

@wei updated

@ryancat
Copy link

ryancat commented Jun 22, 2014

**Avoid variables named after the color, use semantic color names instead

I think it's hard to describe all use cases with semantic color names. A good way to define color might be using class-like way:

$color-body-background: #CCC;
$color-module1-title: #E1E1E1;
$color-font: black;

@bcherny
Copy link
Author

bcherny commented Jun 25, 2014

@ryan

i think $color-module1-title is too specific, and can't be reused. prefixing variables with their type is probably a good idea.

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