CSS Styleguide

CSS Naming Convention

As a team we have decided on the BEM naming convention

We use:
a dash (-) to join words
a double underscore (__) to indicate a child element in a component
a double dash (--) to indicate a modified version of a component
l- to indentify a layout class
js- to identity a class that is being used to bind javascript behaviour to

/* Component */ .component-name {} /* Component modifier */ .component-name--modifierName {} /* Component descendant */ .component-name__descendant {} /* Component descendant modifier */ .component-name__descendant--modifierName {} /* Layout */ .l-layout-name {} /* Component state */ .is-state-type {} /* Non-styled JavaScript hooks */ .js-action-name {} /* Non-styled cucumber testing hooks */ .t-name {}

The reason to use such a naming convention is explained clearly in Philip Walton's CSS Architecture

CSS must not use id or js-* classes in selectors.

The js-* class names are reserved for JavaScript-only use.

The example below includes a dedicated JavaScript utility class to which behaviour is bound. It is independent of any specific UI component.

<a class="js-show-profile" data-username="necolas" href="{url}">...</a>

The HTML element has a .no-js class which is replaced with .js for browsers that js enabled and pass our criteria for a browser that we want to provide javascript support for. This enables to provide different styles for javascript and non-javascript experiences. .no-js can be utilsed to prevent the javascript version having to override the non-javascript version but does not have to be used.

/* style non-javascript version of componenet */ .no-js .component-name { } /* style javascript version of componenet */ .js .component-name { }

CSS Lint Configuration

We use CSS Lint to perform static analysis of our compiled CSS to enforce good practice. CSS Lint comes with predefined rules which can either be errors, warnings or ignored. Errors will fail the build and therefore require fixing. Warnings suggest that there may be an issue with the CSS so developers are expected to check warnings and confirm that they are ok to be used.

This is how we have our configuration file set:

css: errors: - important - known-properties - errors - duplicate-background-images - duplicate-properties - empty-rules - fallback-colors - font-faces - star-property-hack - import - ids - underscore-property-hack - shorthand - text-indent - vendor-prefix - zero-units warnings: - overqualified-elements - display-property-grouping - bar - regex-selectors - selector-max-approaching - font-sizes - floats - outline-none - qualified-headings - unique-headings - universal-selector - unqualified-attributes off: - adjoining-classes - box-sizing - box-model - bulletproof-font-face - compatible-vendor-prefixes - gradients

For information about each rule check the documentation

Folder Structure

This is the folder structure we use for organising our Sass files

├── base ├── components ├── layout ├── lib └── utilities

And a selection of the files found inside these:

├── base │   ├── _default.scss │   ├── _fonts.scss │   ├── _forms.scss │   ├── _links.scss │   ├── _media.scss │   └── _typography.scss ├── components │   ├── _button.scss │   ├── _header.scss │   ├── _icon.scss │   ├── _lists.scss ├── layout │   ├── _common.scss │   └── _pages.scss ├── lib │   ├── _functions.scss │   ├── _grid.scss │   ├── _mixins.scss │   ├── _placeholders.scss │   └── _variables.scss └── utilities └── _utils.scss

base - base rules are the defaults. They are almost exclusively single element selectors but it could include attribute selectors, pseudo-class selectors, child selectors or sibling selectors. Essentially, a base style says that wherever this element is on the page, it should look like this.

components - components are the blocks that make up your page. The modular parts of our design. They should be built in such a way that they can be dropped into any page or layout. Components should define how they look, but not their layout or position

layout - layouts hold one or more components together and are responsible for positioning components.

lib - library of variables, functions, mixing and placeholders. They output no css until used.

utilities - utilities are reusable helper classes

Output Files

├── basic.css.scss ├── enhanced_fixed.css.scss ├── enhanced_responsive.css.scss

basic.css.scss - This contains the basic styles present in the base folder and should work in all browsers including legacy browsers

enhanced_responsive.css.scss - This contains the enhanced and responsive styles and will only be used by browsers that understand media queries.

enhanced_fixed.css.scss - This contains a fixed width version of the enhanced styles of the website which is served to IE 7/8. It cIE 7/8 fixes are only included in this file.

Variable naming convention

To make variable names more understandable we use the convention category-some-name. This is also great for RubyMine as it can then auto-suggest available variables.

Example:

$color-green-primary $color-green-higlight

Colours

Colour Usage

$color-site-bg
$color-green-primary
$color-text-default
$color-black
$color-text-icon
$color-white
$color-link-nav
$color-green-primary
$color-link-nav-visited
$color-green-secondary
$color-link-external
$color-grey-light
$color-table-heading
$color-white
$color-table-background
$color-green-primary
$color-table-background-alt
color-green-paler
$color-table-border
$color-grey-light
$color-list-bullet
$color-green-secondary
$color-list-yes
$color-green-secondary
$color-list-no
$color-red-dark
$color-button-default
$color-green-light
$color-button-default-border
$color-green-medium
$color-button-default-text
$color-black
$color-button-primary
$color-yellow-light
$color-button-primary-border
$color-yellow-dark
$color-footer-bg
$color-grey-pale
$color-callout-background
$color-green-pale
$color-action-item-heading
$color-white
$color-action-item-heading-bg
$color-grey-medium
$color-action-item-border
$color-bluegrey-light
$color-icon-open
$color-yellow-light