logo-mark Shape arrow-right arrow-right arrow-right Group Group chevron-vertical Created with Sketch. chevron-vertical Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Created by FontForge 20170731 at Tue Dec 2 15:06:59 2014 By Aleksey,,, Copyright (c) 2014 by Cruzine. All rights reserved.

CSS Styleguide

For all our web development projects we write modular CSS using SCSS with the BEM methodology (Block, Element, Modifier) and custom naming conventions.

SCSS
SCSS is a CSS preprocessor that allows us to do things like nesting and use mixins and placeholders to keep our code DRY.
The following rules should be considered when writing SCSS:
  1. Keep it DRY (Don’t Repeat Yourself)
  2. Use the BEM method to name classes
  3. Class names should always have a prefix (o-, c-, l-, u-)
  4. Class names should be lowercase and use hyphens to separate words eg. main-navigation
  5. Class names should be suitably descriptive (long is better than very short)
  6. Leave a space between the class name and the opening ‘{’
  7. Never nest classes more than 3 levels deep
  8. Get familiar with the SCSS file structure and place new code in the appropriate locations
  9. Code should be modular and easily duplicated across projects
  10. Every scss file should have a header and sections
BEM (Block, Element, Modifier)
BEM is a naming convention for CSS. We use BEM to structure the naming of SCSS classes and to create modularisation in our code. Here’s how it looks simplified:
//SCSS classes using BEM

.block { /* styles */ }
.block__element { /* styles */ }
.block--modifier { /* styles */ }
Block
A 'Block' has an abstract definition but could be considered a top level container/component with possible child elements. One example would be a button class.
// This is a block

.button {
  width: 100%;
  height: 72px;
  background: #ffffff;
}
Element
Any child of a block would then be considered an 'Element' and is specified using a double underscore class name in this style button__label. This sense of ownership between blocks and elements makes it easier to write and understand SCSS.
Using BEM our SCSS for a button with a label now looks like this:
// This is a block

.button {
  width: 100%;
  height: 72px;
  background: #ffffff;
}

// This is an element

.button__label {
  display: inline-block;
}

Modifier
A modifier is used to retain the base styles of a block. While adding new styles without affecting the original implementation. We use a modifier class button--dark to change the background color of our buttons. We then save on rewriting code (keeping things DRY) by chaining our modifier class in the HTML, to create the same button with a different colored background.
// This is a block

.button {
  width: 100%;
  height: 72px;
  background: #ffffff;
}

// This is a modifier

.button--dark {
  background: #333333;
}

Naming Conventions Extended
To complement our BEM style of writing classes. We use extended class naming conventions to give further structure to our SCSS. All CSS classes are given a prefix which helps to define the use of a class. These prefixes are:
o- //Object
c- //Component
l- //Layout
u- //Utility
Object (o-)
Objects are considered the small building blocks of our website (buttons, input fields, tags, labels, messages).
Attributes of an object:
  • A small reusable UI element (often used many times).
  • Shouldn't be context aware (it should look and work the same everywhere).
  • Objects shouldn’t contain other objects. They should stand-alone.
Our button object class o-button is used in hundreds of places and looks and behaves the same everywhere.
.o-button {
  /* styles */
}
Component (c-)
Components are the larger building blocks (cards, faq, forms, search, video player).
Attributes of a component:
  • Large reusable collection of UI elements
  • Can include objects and other components
  • Context aware (Component adapts to its location)
Our .c-tutorial-item class is used in multiple places and changes its layout, text and imagery depending on the location with the help of modifier classes.
.c-tutorial-item {
  /* styles */

  .o-button--bookmark {
    display: none;
  }

}
Layout (l-)
Layout classes are used to change the position (width, padding, margins, display, align) or make small changes (color) to components and objects.
Attributes of a layout:
  • Can be global (used on all pages) or local (used on specific pages)
  • Mostly used to change layout attributes
  • Should be chained to the end of a class list <span class=”o-label l-margin-15”>
Instead of adding a margin to our form component class c-form. We create a global layout class l-margin-15 and add that to the form class list. Now whenever we reuse the form, we add the margins independently. We can chain as many layout classes as our form requires and this protects our c-form class so that we can safely use it everywhere.
// Global layout classes from layouts.scss

.l-margin-15 {
  margin-top: 15px;
}

.l-margin-30 {
  margin-top: 30px;
}

// Local layout classes from homepage.scss

l.home-hero {
  position: relative;
  z-index: 0;
}

Utility (u-)
Utility classes do a single thing, very well.
Attributes of a utility:
  • Simple classes (often one line) that do one task that overrides everything else.
We define display:none as a utility class so that it can be used globally. We use an !important declaration to supercede all other classes.
// Any HTML that has this class will be hidden by default

.u-hide {
  display: none !important;
}

File Structure
Our SCSS file structure mirrors the extended naming conventions. This groups layouts, components and objects in folders and provides a location to store SCSS abstracts, base files and external libraries.
/abstracts: SCSS exclusives (never compiled to main.css)
  • variables.scss (colors, fonts)
  • mixins.scss (breakpoints)
/base: Reset styles for CSS and typography
  • base.scss (reset)
  • typography.scss (type scale)
/components: Collection of large scale UI building blocks
  • navigation.scss (site navigation, sidebar)
  • form.scss (login, contact)
  • ...
/layouts: Global and local layouts
  • layouts.scss (margin, padding, display, flex, grid...)
  • ...
/lib: External CSS libraries
  • normalize.scss
  • bourbon.scss
  • animate.scss
  • ...
/objects: Collection of small UI building blocks
  • buttons.scss
  • inputs.scss
  • ...
shame.scss
A file for temporary quick hacks and fixes.
utilities.scss
Collection of utility classes.
Table of Contents
Each file should have a title, description and table of contents at the top in the following format.
/*
 * Title
 *
 * Description
 *
 * 1. Section
 *
 * 2. Section
 *
 */

Section Headings
Each section of the file should have a section header in the following format.
/* ===================
1. Section
====================== */