Styling Conventions. BEM, SMACSS, OOCSS

Known styling conventions are paraphrased below, followed by a list of commonalities.

  1. OOCSS
  2. BEM
  3. SMACSS
  4. List

OOCSS (Object Oriented CSS)

OOCSS is used by Facebook. OOCSS has shared focuses on manageability and smaller file size. It's techniques are conceptually similar to those of Object Oriented Programming. Repeatable structures are separated from specific details to be optimised and reused. This would include things like headers, comment lists, link styles, media blocks.

OOCSS was created by Nicole Sullivan to support her own claim that she could style a gmail-like layout in a few hours source.

There is a video of Nicole modifying a template to make a gmail-like layout. She recommends using this same template, which uses a grid-defining stylesheet that is ~500 bytes.

Nicole created smush.it, an image optimiser maintained by yahoo and integrated with yslow more and more. She also created cssLint with famous yahoo script author Nicholas Zakas. Her clients include Yahoo and the W3C organization.

She has said that 'class-itis' and 'div-itis' are lame un-questioned myths. Reflow is a geeky concern -an irrelevant performance bottleneck. Filesize should be the most important concern for a web developer.

Facebook render and response times were reduced to half using OOCSS.

What it looks like:

The example and the result here:

.media:before,
.media:after {
    content: " ";
    display: table;
}
.media:after {
    clear: both;
}
.mediaImg {
    float: left;
    margin-right: 10px;
}
.mediaBody {
    display: table-cell;
    width: 10000px;
    vertical-align: top;
}
.mediaBody :first-child {
    margin-top: 0;
}
<div class="media">
    <img src="http://placekitten.com/100/100" class="mediaImg">
    <div class="mediaBody">
        <p>Cupcake ipsum dolor sit amet halvah.</p>
        <p>Cupcake ipsum dolor sit amet halvah.</p>
    </div>
</div>

The example and the result it produces can be seen here.

The "media" block is encapsulated. Its definitions affect the structure of media block only and do not style the inner contents. In one of her lectures Nicole shows a Facebook page with "media" structures tinted red -most of the page appears red. They are the most common structure.

OOCSS "extends" an object with new classnames that may override the default definitions. Importantly, it relies on the Cascade to achieve this and avoids specificity.

/*
 * good
 */
.mediaBody { }
.mediaBodyVideo { }
/*
 * bad
 */ 
.media .mediaBody { }
.mediaBody.Video { }
/*
 * good
 */
.message { }
.error { }
/*
 * bad
 */
.message { }
.message.error { }

OOCSS also avoids '!important' and the use of ids and element specifiers:

/*
 * good
 */
.mediaBody { }
/*
 * bad
 */
div.mediaBody { color:red !important; }
#Header.mediaBody { }

Something like referential transparency is encouraged. An object should not appear differently due to its location. For example, one heading giant and pink in one place should not be small and blue in another.

/*
 * bad
 */
.column3 .media { font-size:bigger; }

Styles are self-contained for each structure and toggle classes are low in the dom tree closer to the component.

OOCSS headers are defined in one place. 10 or more header definitions are usually too many:

h1, .h1 { /*...*/ }
h2, .h2 { /*...*/ }
h3, .h3 { /*...*/ }
h4, .h4 { /*...*/ }
h5, .h5 { /*...*/ }
h6, .h6 { /*...*/ }
<h3 class="h6">heading</h3>

A reset stylesheet and a grid system should be used. 10 or more 'float' definitions indicate the absence of a grid system.

All rules should have the same strength: 1, 2 or 3

/*
 * good
 */
.gl .title { ... } .gl .body { ... } .gl .foot { ... }
/*
 * good
 */ 
.title { ... } .gl .body { ... } .gl .left .foot { ... }

BEM (Block Element Modifier)

BEM is used by Russian search-engine Yandex. It was developed over a period of several years to make complex web applications manageable. BEM 'Blocks' are used by all Yandex web applications with many shared Blocks reused across applications.

The BEM conventions are considered stable by Yandex and have remained unchanged for the last few years. Yandex have released 'starter' repositories and have open-sourced some BEM Blocks.

Because BEM avoids a cascade for applying styles, browser rendering of BEM documents is observably faster.

Yandex have developed their own browser. They are an authoritative source of information.

What it looks like:

.b-head-logo { }
.b-head-logo__name { }
.b-head-logo__name_state_current { }
<div class="b-head-logo">
    <span class="b-head-logo__name">
        Web Service Name Here
    </span>
</div>

The above Block is b-head. Each Element in the Block is prefixed with the Block name. The b- prefix on the Block name describes the type of block (there are 4 types only).

Block, Element, Modifier

Block

A Block is semantically or visually distinct in the document (a menu or a sidebar). It does not use IDs for styles. A successful Block is reusable on any page in any context any number of times.

Any Block should allow for arbitrary content to be embedded whenever possible. Blocks must be independent, classname conflicts must not alter the appearance of another Block.

Block elements are prefixed with the parent block name. Block styles are affected through classnames and never through tag names.

Element

An Element is part of a Block (menu item, sidebar title). It does not exist outside of a Block-provided context.

Modifier

A flag to define a Block state. Requires a name and value. ex, size-big.

Two reasons to change a presentation state:

  1. Context-dependent modification
  2. Context-independent modification

SMACSS (Salable Modular Architecture for CSS)

SMACSS is used by yahoo and was popularly introduced through yahoo mail. Created by Jonathan Snook, who maintains a web book describing it. 'Snook avoids making conclusive statements. His text is filled with recommendations and caveats.

Its definition is not strict, like BEM or OOCSS. It is more of a guideline. Mindshare around SMACSS is substantial and SMACSS related content is easy to find on the internet.

What it looks like:

.pod {
    width: 100%;
}
.pod input[type=text] {
    width: 50%;
}
.pod-constrained input[type=text] {
    width: 100%;
}
.pod-callout {
    width: 200px;
}
.pod-callout input[type=text] {
    width: 180px;
}
<div class="pod pod-constrained">...</div>
<div class="pod pod-callout">...</div>

The above Module is 'pod'. Each element in the module is styled through the namespace of the Module, '.pod'. Each Module associates with its own stylesheet.

Base, Layout, Module, State, Theme

  1. Base
  2. Layout
  3. Module
  4. State
  5. Theme

State changes

State changes come from a className (via javascript), psuedo-class or media query.

Co-dependent parent and sibling states are considered "troublesome". "applying a state to each button is preferred", because this offers better separation between modules. 'Easier to test, develop and scale.

.btn { color: #333; }
.btn-pressed { color: #000; }
.btn-disabled { opacity: .5; pointer-events: none; }

List

Shared characteristics of BEM, SMACSS and OOCSS:

bumblehead.com