Skip to content

Whiteboard Style Guide: CSS

Jonathan Cutrell edited this page May 14, 2015 · 16 revisions

Code Style Guide for CSS


The purpose of this style guide

In branding, style guides serve to retain the integrity of a brand's presentation to the world. The point of this is to not only ensure the high quality of that brand, but also to ensure that those consuming the material FROM that brand can understand it. If, for example, a designer at Coke put out a version of their logo that was set against a blue and green background, despite how good it may look, it would confuse consumers.

This style guide serves as a foundation for understanding how Whiteboard writes CSS, so that when we pass the CSS between developers or to external teams, we have a cohesive understanding and a unified style.

The following is a conglomeration of "best practices", as well as practices we retain. It is necessarily intertwined with some of our HTML style guide and usage.

File Structure

Hacks.css

Specificity and Selectors

Rules regarding specificity and selectors:

  • Selector chains should not be nested more than 4 selectors deep. The only exception to this rule is :before and :after elements, which are technically nested 5 elements deep, including their attached parent.
  • When possible, choose direct child selectors (>)
  • Never use !important
  • Prefer classes over any other type of selector
  • Avoid base level element styling; exceptions might include styling anchor (<a>) elements or list elements (ul, ol), but avoid if possible.

Declaration block styling

When declaring a basic style, always use the format below:

.my-selector {
    margin: 12px auto;
    padding: 6px;
    padding-left: 10px;
    transition: all 0.4s;
}

Notice the following rules related to this style declaration:

  • Always break declarations into the block between the brackets, even if there is only one style declaration in the block.
  • place a space between the selector and the bracket
  • use 4 spaces for indentation instead of tabs
  • Use shorthand when possible
  • When overriding previous rules (like with padding in the example), group the relevant rules together
  • Leave no space between the property and the colon, but do leave a space after the colon
  • Always use semicolons after each property declaration, including the last property in the block

Class Naming Structures

In general, classes should be named semantically in relation to the content they describe. This rule can be broken without much negative consequence, but should be followed as a good practice.

Whiteboarders always name classes with lower-case only, opting for dashes as separators between words.

We follow this structure:

<div class="slider">
    <div class="slider-wrap js-initialized">
        <div class="slider-slide slider-slide--active">
            <div class="slider-slide--image full-bg"></div>
            <div class="slider-slide--title u-upcase"></div>
        </div>
        <div class="slider-slide">
            <div class="slider-slide--image full-bg"></div>
            <div class="slider-slide--title u-upcase"></div>
        </div>
    </div>
</div>

Notice a few important pieces of the above scenario:

  • We utilize the BEM inspired module-subpiece--modifier pattern to "extend objects", conceptually
  • It's okay to have a class name without a dash
  • It's okay to add multiple classes to a given element

Furthermore, the above example also includes a few special class-naming structures. Classes starting with js- should never be referenced in the stylesheets (these are intended to be used only as hooks for JavaScript functionality). Classes starting with a u- (for "utility") should always be top-level classes, and should modify a specific, narrow set of style declarations.

If a particular module seems to be getting to detailed in its class naming structure, it should be separated into smaller modules. Smaller, in general, is better when it comes to object modeling, and this is no different in conceptual object modeling in CSS. This naturally presents some hierarchical challenges, most of which may be overcome by relying on classes for styling to avoid specificity issues.

Avoid styling based on page-level classes. This pattern closes off the reusability of code, and because of the distance between the page-level class and the class being used, often is difficult to decode.

Fonts

Rules:

  • Use no more than 6 non-native fonts (including individual weights) in a given project; for example, 3 weights from two families is the maximum before font resources cause significant slow-down and overhead.
  • Set a body font size
  • Rely on rem as often as possible; 1rem = body font size * 1
  • Do NOT set font size in your primary stylesheet; instead, create a dedicated type scaffold that allows for a more natural font scaling strategy. Determine all sizes of the fonts at the beginning of the project, and re-use those sizes.

Note on font size scaffolds: Using h-classes (.h1, .h2, etc) can provide a natural rhythm that is reusable across the project. Determine these font sizes up front, and reuse them throughout the process as much as possible, relying on base level styles for font-sizes.

Resets, Boilerplates, etc.

We use normalize.css. Boilerplate code in Launchframe is loosely based on some of Bootstrap's grid and Skeleton's base aesthetic styles.

Grid information

Grid classes are ugly, but their usefulness generally justifies their use in most cases for Whiteboard. We use the following pattern for grid classes:

modifier-breakpoint[-direction]-count

Where modifier is one of:

  • vp (vertical padding)
  • vm (vertical margin)
  • col (width)

Breakpoint is one of xs, sm, md, lg, or xl, each breakpoints defined in the grid itself.

Direction is applicable to the vertical margin classes only, and is one of top or bottom.

Count is the number to apply to the modification, typically from 1 to 16 (in a 16 column grid).

All grids should be built with @media queries that rely on min-width, not max-width or a combination of the two.

Secondary: Style Guide for SCSS

Clone this wiki locally