Skip to content

Instantly share code, notes, and snippets.

@phillbaker
Forked from kmamykin/CSS Styleguides.md
Created April 1, 2014 19:55
Show Gist options
  • Save phillbaker/9921797 to your computer and use it in GitHub Desktop.
Save phillbaker/9921797 to your computer and use it in GitHub Desktop.

#Introduction

Several layers of css rules:

  • Base: resets, normalize, base colors, typography, etc.
  • Layout: header, footer, wrapper, grid, sidebar, main-column
  • Modules: avatar, buttons, upvote, forms
    • States: (defined with the modules) somemodule-active, somemodule-disabled, -selected
    • Themes: (defined with the modules) somemodule-primary, somemodule-large

Module

Modules contain the bulk of project css rules.

"As we all know, the smaller the unit, the more reusable it is." - Someone Smart

Modules represent visual concepts, not domain concepts

The most atomic and reusable structure of classes is when they represent small visual concepts, that are relatively domain independent. The contrast can be seen in these examples:

Option1:

in questions.css
question {
  question-aside {
    question-author-avatar {}
  }
  question-body {
  }
}

Option2:

in layout.css
.wrapper {}
.sidebar {}
.main{}
in aside.css
aside { avatar-large {} }
aside-primary {}
in content.css
content-body {}
content-body-primary { font-size: larger; }
in questions/show.html
.wrapper
  .sidebar
    .aside.aside-primary
  .main
    .content-title
    .content-body.content-body-primary

Using Opton1, every page would have to repeat the definitions for domain concepts (e.g. tutorial heading, question heading etc), and those definitions will be a) mostly be empty (assuming inheriting from some common styles), or b) bloated with duplication.

Cognitively, with Option1 there are 2 levels of indirection, mapping domain entities to domain css classes inside html, and then mapping domain css to visual concepts in css/scss code.

Option2 allows for direct mapping of domain concepts (what to display, tutorial.title) to visual concept (how to display, class='content-heading')

Additional benefit of Option2 is that overtime the visual concepts develop and become reusable, forming a custom "CSS framework".

Module structure

Modules assume a predefined structure of html using standard elements or custom classes e.g

upvote {
  span.counter {}
  a.span.icon-arrow-up {}
}

sidebar {
  sidebar-posted-as {}
  sidebar-action {}
}

We can define specialization of modules for different state or theme:

upvote-large { // override styles for upvote }
upvote-active { // override styles for upvote }

Finally in html we can map domain concepts (e.g. tutorial upvotes) to visual concepts: upvote button:

<div class="upvote upvote-large upvote-active">

The trick is to identify these modules in the design, extract them and apply consistantly.

Other guidelines

  • No # for styling, except may be footer/header/body (http://nefariousdesigns.co.uk/on-html-element-identifiers.html)
  • Duplication is an enemy, strive to eliminate with @mixins and @extends
  • Ideally very little should go to individual pages css, most should be in modules, layout or base.
  • Media queries - to be defines together with modules or layout
  • Prefer to use child selector (>) for direct descendents of a module (not to cascade to all descendent)
  • External css/js should go to vendor directory, not app/assets

JavaScript

Prefer to use data properties to select elements for js functionality as well as to pass parameters. Example: to have js displaying hidden div on click of a link

<a href="#somediv" data-reveal="slow">  
<a href="/something" data-poll="5">  

When in doubt

https://github.com/styleguide/css

Documenting Styles

References:

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