Frontend Styleguide


Classes, IDs, etc.

In your CSS

  • Use classes as much as possible
  • Do NOT use IDs (because they are very hard to override, due to specificity issues)
  • Avoid element selectors (a, p) as much as possible (if you use them, child element selectors are preferred > p)

In your Javascript

  • Use IDs like “#js-something” to bind behavior to single, uniqe elements, because IDs are still fastest
  • Use data attributes instead of classes, to bind behavior to sets of elements (e.g. in the markup <div data-behavior="datepicker"> in the JS $('[data-behavior=datepicker]')). Finding element by data attributes is almost as fast as by classes (blogpost) and it creates a nice separation of concerns between behavior and styling.

Exceptions to the rule

  • The only time where both CSS and Javascript are dealing with classes, is for classes that indicate state. These can be either pseudo classes (:focus, :hover) or classes prefixed with is- (e.g. is-disabled, is-selected).

Template Code

  • Use haml
  • Prefer standard Rails view helpers over libraries like simple_form or formtastic


  • Use Sass with Sass syntax

  • By default, use dashes for CSS classes instead of underscores: my-class instead of my_class

Sass File Structure

  • Naming convention for Sass files:
    • always prefix partials (= files meant for @importing) with an underscore _
    • always use file extension .css.sass
    • => _partial.css.sass




Basic variables, mixins & styles that are the base for all stylesheets.


  • CSS resets (if used)
  • default styles for elements
  • only element selectors
  • use sparingly


  font-weight: bold


  • literal colors
  • mapped colors ($light-background-color, $border-color)


  • font-family
  • font-size variables
  • possibly typography related mixins


  • $content-width
  • breakpoints
  • $padding: 10px, $margin: 20px


  • Compass




  • file name: singular (‘button’, ‘box’, ‘list’)
  • load order independent (@import 'modules/*')
  • context independent (avoid fixed widths)
  • content independent
  • complete (+ responsive)
  • module should describe a design element NOT a content element


Controller specific styles, scoped using class & ID from <body> tag

<body class="controllername" id="controllername_actionname">
/blocks (for composition, complex modules, content specific)

CSS Frameworks

  • Use Compass whereever possible


good for:

  • admin backends
  • no design requirements

not good for:

  • anything else
Zurb Foundation


Roll your own

Responsive CSS

  • breakpoint


  • Do NOT use JavaScript UNLESS you know what you’re doing!

  • Write your Javascript using Coffeescript

  • dont’t polute the global namespace
  • define functions/classes in app specific namespace window.ShortAppName = {}

Testable JavaScript

  • Aim to write testable JS
    • Coffescript Classes can help with that
  • Integration tests with Cucumber & co are not enough. JS should also be unit testable


  • avoid curly braces whereever possible
  • prefer and/or over &&/|| for boolean expressions for readability
  • always use Ruby style string interpolation: "foo #{myVariable} bar"


  • always prefer @ over this
  • leave out the dot: @name instaead of


  • use fat arrow myFunction = (argument) => over that = this constructs
  • except if you need BOTH this & that inside the function

Anonymous funtions

  • omit braces when there are not arguments:

    myFunction = ->
      # ...
  • space before function arrow (dashrocket)

    myFunction = (argument) ->
      # ...

File structure & loading sequence

Here is an example for a basic file structure for javascript in a Rails project.

Manifest file

// app/assets/javascripts/

# = require vendor/library
# = require init
# = require_tree modules

Init file

In the init file we set up the app’s namespace in order to not polute the global namspace. Here we also have our central call to $(document).ready() ($ ->). Ideally there shouldn’t be any other $(document).ready() in the codebase.

// app/assets/javascripts/

window.Namespace = {}

$ ->
  myInstance = new Namespace.MyClass()

A nice, modern, modular class:

// app/assets/javascript/modules/

class Namespace.MyClass

Classic jQuery-style Javascript:

// app/assets/javascript/modules/

Namespace.initDatepicker = ->

Variables & Classes

  • Use camel case for variable names: myLittleVariable
  • Prefix variables that contain jQuery objects with $
  • try to avoid too short variable names: use (event) -> instead of (e) ->

  • classes start upper case Class and instances lower case ìnstance = new Class()
  • namespace also starts upper case window.Namespace = {}


Event Listeners

  • Minimize number of event listeners for performance reasons
  • Try listening on a appropiate parent element


<ul id="list">
  <li class="item">...</li>
  <li class="item">...</li>
  <li class="item">...</li>

Instead of this:

$('.item').click ->
  # behavior

Do this:

$('#list').on 'click', '.item', ->
  # behavior

The advantages are that it’s faster, because you have less event listeners to bind etc. and it is more flexible, since you can add new items to list without needing to add new listeners.

Caching jQuery objects

  • cache jQuery objects in variables, if you need to use them multiple times

Do this:

$form = $('selector')

instead of:


Rails & JS

Controversial: * gon - you can use it to share global config between Rails & JS, but then it might be overkill - not so much for controller specific data

Proposed: * routes (Rails’ named routes in JS) * i18n (Rails i18n in JS)