Sass & CSS Style Guide

The following is a guide on how I author and organize style sheet files in websites and web applications.

Tools

My preferred CSS development environment consists of the following tools and methodologies:

Folder structure

A typical project's folder structure is based on recommendations on how to divide different types of styles in the SMACSS methodology.

  • File and folder names are typically plural.
  • Style base HTML elements within bases/_elements.scss.
  • Store general layout styles within _layouts.scss.
  • Modules should be stored in modules/. Use subfolders liberally to group related modules together.
  • The end goal is to have Sass compile everything to a file called app.min.css. Where this file is stored depends on the framework you're using, how you configure your build tools, etc.
  • scss
    • bases
      • _elements.scss
      • _fonts.scss
    • modules
      • _footers.scss
      • _global-navs.scs
      • _headers.scss
    • non-modular
      • _home.scss
    • vendor
      • _font-awesome.scss
    • _layouts.scss
    • _settings.scss
    • app.scss

Asset manifest files

The file at scss/app.scss should be used to tie all of the different bases, layouts, modules, and other configurations together. Of course, create additional manifest files if different parts of your website or application call for it.

A typical asset manifest file will look like this:

This file is split into several parts:

Fonts
Style sheets for embedding @font-face declarations for web fonts.
Settings
Import Sass files containing global variables and mixins. Libraries like ZURB Foundation also have a global settings file that would be appropriate to include in this section.
Vendor Dependencies
Style sheets related to 3rd party libraries like ZURB Foundation, Twitter Bootstrap, CSS resets, etc. When including the source code for the library directly in a project, store the files in the appropriate vendor/ folder, or include the files needed from the bower_components/ folder if you're using Bower.
Bases
Styles for base elements without any class or id selectors.
Layouts
Styles for general layouts. If you have simple layout needs, you may be able to store all layout styles in a single _layouts.scss file in the root scss folder.
Modules
Styles for individual modules.
Non-modular
A “junk drawer” of page-based styles. Contents in here should eventually be refactored into modules.

General formatting

I agree mostly with GitHub's and Google's general rules for CSS formatting.

Use soft-tabs with a 2 space indent.

tab characters can end up displaying funkily in some contexts. Spaces are consistent.

Stricly use class names to style elements.

Only style via id selectors when absolutely necessary (for example, if you're using 3rd party code that makes heavy use of ids).

This keeps selectors mostly on even ground with regards to specificity.

Use lowercase for everything possible.

Avoid trailing whitespace at the ends of lines.

This causes issues with diffs in version control.

Put spaces after : in property declarations.

Put spaces before { in rule declarations.

Use hex color codes #000 unless using rgba.

When possible, use the abbreviated 3-character version of the hex code.

Use // for comment blocks (instead of /* */).

Comments denoted by // are hidden in the generated CSS, whereas /* */ are passed along to the generated source.

Use hypens as word delimiters for class and id selectors unless the accompanying HTML markup requires otherwise.

The only main exception: inclusion of 3rd party libraries may require the use of camelCase, underscores, or no delimiters.

Use Foundation's rem-calc() mixin to translate pixel units to rem.

Sort directive names in alphabetical order.

Place @include and @extend directives as the first rules in a block of directives.

Any $variable or @mixin that is used in more than one file should be put in the bases/ folder.

Others should be put at the top of the file where they're used.

As a rule of thumb, don't nest further than 3 levels deep.

If you find yourself going further, think about reorganizing your rules (either the specificity needed or the layout of the nesting).

Layouts

According to the SMACSS method, layout components are the major guiding elements on the page (e.g., headers, footers, sidebars).

My guidelines are similar to SMACSS:

  • Prefix all layout class names with l-. For example, .l-two-columns, .l-content, and .l-sidebar.

Because they are major components on the page, many layout styles will involve media queries and column width mixins. Here is a typical example for a mobile-first Foundation-based 2 column layout:

Modules

Again, from SMACSS:

A Module is a more discrete component of the page. It is your navigation bars and your carousels and your dialogs and your widgets and so on. This is the meat of the page. Modules sit inside Layout components.

  • Modules should be broken down into as small of units as possible.
  • Prefix all module class names with the module name. For example, .header, .header-title, .header-icon, etc. for a header module.
  • Don't rely on specifying HTML elements as module selectors. For example, don't do this: .header li. Instead, prefer .header-item.
  • Avoid chaining together too many words in a module class name. Consider changing names like .article-quote-header-title to something shorter like .article-quote-title. In this case, even consider styling asides separately in a .quote module.

Related resources

  1. Sass preprocessor
  2. Ember CLI
  3. ember-cli-sass
  4. Rails Asset Pipeline
  5. Grunt
  6. grunt-sass
  7. SMACSS
  8. GitHub CSS Styleguide
  9. Google HTML/CSS Style Guide
  10. Modular CSS, Glass Case Blog

Last updated: