Skip to content

Instantly share code, notes, and snippets.

@sheck
Created October 26, 2015 16:07
Show Gist options
  • Save sheck/11d0f7b7ec4b4878a63b to your computer and use it in GitHub Desktop.
Save sheck/11d0f7b7ec4b4878a63b to your computer and use it in GitHub Desktop.
Rock CSS Guide

Rock CSS Guide

Outline

  1. About this Guide
  2. Naming Conventions
  3. Comments & Whitespace
  4. Creating Selectors
  5. Nesting
  6. Media Queries
  7. Helper classes
  8. When you can not edit the HTML markup
  9. Summary & General Rules
  10. Credits, Sources, Further Reading

1. About this Guide

When starting out in a new codebase, or writing a new section of CSS, there can be a lot of hesitation and uncertainty — "Is this the best way to do this?" "Am I doing this right?"

Our goals in writing this guide are:

  1. Eliminate guesswork when writing styles
  2. Provide consistancy where Bootstrap is inconsistant
  3. Help developers who are new to CSS get started in the right direction

High-level principles

At a high-level, your goals in writing CSS for Rock should be:

  • Create a library of reusable modules (or blocks) instead of styling specific pages and modules
  • Write styles with developer usability in mind

Note: at time of writing, our current codebase does not always follow these guidelines. We're aware of this and are making plans to refactor it.

2. Naming Conventions

Styles

A mix of BEM (a naming convention meaning block, element, modifier) and Bootstrap's conventions. More on this in section 5.

.blockname-elementname-modifiername
// Example
.footernav
.footernav-col
.footernav-col-big

Javascript Hooks

We seperate our javascript hooks from styling hooks to prevent accidental breakages, and allow more confidence in style refactoring.

.js-hookname
// Example
.js-loginbtn

Never style a .js- class — and don't use style classes for selectors in Javascript, either.

3. Comments & Whitespace

CSS Section Headings

//
// Heading 1 (2 blank lines above, 2 below)
// --------------------------------------------------

// Heading 2 (2 above, 1 below)
// -------------------------
// Heading 3 (2 above, 1 below)

Whitespace

  • 2 space soft indent
    • Why? Standard used by Bootstrap, renders consistently wherever used.
  • No trailing whitespace
  • Use the EditorConfig plugin to have your IDE take care of most of this. Visual Studio users can install this using the extension manager.

4. Creating Selectors

Block, Element, Modifier Naming Convention

  • Also called BEM
  • Blocks have sub elements, 1 level deep
  • Example:
    • .person
    • .person-head
    • No: .person-head-eye
    • Yes: .person-eye
  • Blocks and Elements can have modifiers
    • .person-tall
    • .person-eye-blue

Open for extension; Closed for modification

Don't modify the properties of a class based on it's location. Instead, add an optional class that adds the desired changes.

  • Example
    • No: .footer .menu { color: white }
    • Yes: .menu-light { color: white }

In this example, .menu has a different color simply becuase it is located in a different position within the HTML markup. Essentially, the styles for this specific module now live in two different areas — creating potential headaches later on. A more future oriented solution is to add another class to the HTML to achieve the same effect.

Don't style ID tags

There are many reason why it's a bad idea — mainly, it's practically impossible to override without using !important. The benefits just don't outweigh the disadvantages.

If you have to style third party code that does use ID tags, try using an attribute selector instead [id=“vendor-thing”] { … }

Low Specificity

Use the least amount of specificity necessary. The more specific your styles are, the increasingly harder it will become to extend and modify them later.

Avoid Qualifying selectors

Dont use ul.footernav if you can use .footernav instead.

5. Nesting

LESS (and other preprocessors) make it easy nest your styles. It can be very convenient, but it's overuse can lead to styles that are more specific than necessary. It's easy to lose track of how long (and specific) a selector has become when you're 5 levels deep.

  • Try to limit your nesting to 3 levels at most
  • Instead of nesting submodules, indent entire selectors to simulate their hierarchy in HTML
// No
.footernav {
  [...]
  .footernav-col  {
    [...]
    .footernav-header  { [...] }
  }
}
// Yes
.footernav {
  [...]
}
  .footernav-col  {
    [...]
  }
    .footernav-header  { [...] }

6. Media Queries

General Principles

  • Keep media queries close to the styles that they effect, not in a seperate stylesheet.
  • Use our media query helpers
@xs = (min-width: @screen-xs-min) = 480px
@sm = (min-width: @screen-sm-min) = 768px
@md = (min-width: @screen-md-min) = 992px
@lg = (min-width: @screen-lg-min) = 1200px
// Example
@media @xs {
  .footernav {
    padding: 2em;
  }
}

Mobile First

Aim to build your styles and their respective media queries mobile first: styles for mobile are the base styles, and media queries are used to provide styles for the larger screen sizes. This isn't always feasible, but it will help you and other developers in the future.

// Yes
.block { padding: 1em; }
@media @sm {
  .block { padding: 2em; }
}
@media @lg {
  .block { padding: 4em; }
}
// No
.block { padding: 4em; }
@media (max-width: 1199px) {
  .block { padding: 2em; }
}
@media (max-width: 992px) {
  .block { padding: 1em; }
}

7. Helper Classes

Helper classes are single responsibility classes or variables that can be combined with reusable modules, or added into a glue layer, to acheive the styles you're looking for.

Media Query Helpers

See #6

Margin & Padding

Our margin and padding helpers follow a basic pattern:

[margin/padding]-[side: t,b,r,l,v,h,all]-[size: sm,md,lg,xl]

Side values

  • Top
  • Bottom
  • Right
  • Left
  • Vertical (top & bottom)
  • Horizontal (left & right)
// Examples of actual classes
.padding-b-md
.margin-l-xl
<!-- Usage Example -->
<div class="margin-v-lg">[...]</div>

LESS Spacing Variables

We use some spacing variables that are based of off bootstraps own variable: @grid-gutter-width. We multiply or divide this variable to create complementary pixel values.

// Our Helpers
@spacing-sm-px // Default: 7.5px
@spacing-md-px // Default: 15px
@spacing-lg-px // Default: 30px
@spacing-xl-px // Default: 60px

Using spacing variables can help you create designs that have consistent spacing and vertical rhythm.

8. When You Can Not Edit The HTML Markup

One of the goals when writing CSS for Rock is to create reusable modules. If you can control the markup of the HTML, this is easy to implement. If you have to use markup that is already set, and possibly unchangeable, it becomes more of a problem.

There are two ways to work around this:

  1. Duplicate the Rock Block and modify the markup (make sure you know what you're doing)
  2. Create a 'glue layer' between your reusable modules and the uneditable markup

Creating a glue layer

With a glue layer, you add mixins (can be regular CSS classes), to specific class. When compiled by LESS, all of the styles from these classes will be added, or mixed-in.

// Example
.some-rock-block-header {
  .footernav-heading;
}
.some-rock-block-wrapper {
  .container;
}
.some-rock-block-button {
  .btn;
  .btn-default;
  .pull-right;
}

Note: this method creates a bit of duplication in your stylesheets. This is something we would normally avoid, but there are not too many alternatives here.

9. Summary & General Rules

  • Select what you want explicitly, rather than relying on circumstance or coincidence. Good Selector Intent will rein in the reach and leak of your styles. (.sub-header instead of .content h2)
  • Write selectors for reusability, so that you can work more efficiently and reduce waste and repetition. (.highlight-color instead of .blue)
  • Do not nest selectors unnecessarily, because this will increase specificity and affect where else you can use your styles. (.footernav-col instead of .footer .sidebar .nav .col)
  • Do not qualify selectors unnecessarily, as this will impact the number of different elements you can apply styles to. (.nav instead of ul.nav)
  • Keep selectors as short as possible, in order to keep specificity down and performance up.
  • When in doubt, bootstrap wins. If it’s not clear in this style guide, do what Bootstrap does.

10. Credits, Sources, Further Reading

Most of the work is inspired, similar, or copy and pasted directly from articles by really talented individuals.

@jonedmiston
Copy link

@sheck thanks so much for this. Still very helpful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment