BEM-Methodology-Talk



BEM-Methodology-Talk

0 0


BEM-Methodology-Talk

Given at CascadeBOS Meetup, 22 Oct 2013: http://www.meetup.com/cascadebos/events/142381712/

On Github andrewrota / BEM-Methodology-Talk

BEM Methodology

Who am I?

Andrew Rota

Interactive Developer at Sapient Global Markets

  • I build HTML5 / JavaScript web applications
  • I was a philosophy major
  • I'm an avid sea kayaker

What is BEM?

  • Block
  • Element
  • Modifier

History

tl;dr: Developed by Yandex, Russia's largest search engine company, in 2006/2007 to bring structure to web pages.

Source: BEM
BEM stands for Block, Element, Modifier. Architecture, Set of Principles BEM is a methodology for modularizing structuring sand developing user interfaces, especially on the web. WHY?: - Fast-to-develop, long-lived projects - Team scalability - Code reuse

Disorganized

Image by Source: davidd (CC BY 2.0

Over Specific

Location Dependent

Image by Source: Guma89 (CC BY-SA 3.0)

Ecosystem

OOCSS

.media {margin:10px;}
.media, .bd {overflow:hidden; _overflow:visible; zoom:1;}
.media .img {float:left; margin-right: 10px;}

SMACSS

.pod-callout { width: 200px; }
.pod-callout input[type=text] { width: 180px; }

Atomic CSS

.M-1 {margin: 1px;}
.M-2 {margin: 2px;}
.M-4 {margin: 4px;}
OOCSS

Block

block /blɒk/ n : A block is an independent entity, a "building block" of an application. A block can be either simple or compound (containing other blocks).

Source: BEM

- Each block have a block name and it is unqiue. - Instances of the same block can share the same name. - Blocks are independent, meaning they can be placed anywhere on the page, including within another block.

Blocks

Source: BEM

- Each block have a block name and it is unqiue. - Instances of the same block can share the same name. - Blocks are independent, meaning they can be placed anywhere on the page, including within another block.

Element

el•e•ment /ˈɛləmənt/ n : An element is a part of a block that performs a certain function. Elements are context-dependent: they only make sense in the context of the block they belong to.

Source: BEM

- Each element has an element name and it's unique within the scope of a block.

Modifier

mod•i•fi•er /ˈmɒdəˌfaɪər/ n : A modifier is a property of a block or an element that alters its look or behavior.

Source: BEM

- A modifier is used for minimal alterations to a block or element. - It has a name and a value. - Several modifiers can be used on a block or element at once.

Modifiers

Source: BEM

- A modifier is used for minimal alterations to a block or element. - It has a name and a value. - Several modifiers can be used on a block or element at once.

Back to Blocks

Source: BEM

Mapping the UI

-So we're looking for indepdendent entities in our application. At this point it's easiest to define these blocks based on visual and content clues. -What an stand on its own as complete, as self-contained, as location-independent. Keep in mind that this easier on some projects than it is on others. -Now there are different ways to split up the blocks on your site. You can nest blocks, of course, but I'd suggest the first time around not worrying about that. Just focus on the obvious stand alone, self-contained modules. You can break out nested blocks later, but nested blocks can make things more complicated, especially at first.

Demo App

Demo App

CSS Principles

  • Avoid descendent or other cascading selectors
  • Element selectors must not be used
  • CSS ID selectors must not be used
Before we start writing code, back to the rules.

Writing Blocks

<nav>
  <ul>
    <li><a href="#">Breaking</a></li>
    <li><a href="#">World</a></li>
    <li><a href="#">U.S.</a></li>
    <li><a href="#">Business</a></li>
    <li><a href="#">Politics</a></li>
    <li><a href="#">Entertainment</a></li>
    <li><a href="#">Technology</a></li>
    <li><a href="#">Sports</a></li>
  </ul>
</nav>

Writing Blocks

<nav class="nav-menu">
  <ul>
    <li><a href="#">Breaking</a></li>
    <li><a href="#">World</a></li>
    <li><a href="#">U.S.</a></li>
    <li><a href="#">Business</a></li>
    <li><a href="#">Politics</a></li>
    <li><a href="#">Entertainment</a></li>
    <li><a href="#">Technology</a></li>
    <li><a href="#">Sports</a></li>
  </ul>
</nav>

Writing Blocks

<nav class="nav-menu">
  <ul class="nav-menu--items">
    <li class="nav-menu--item"><a href="#">Breaking</a></li>
    <li class="nav-menu--item"><a href="#">World</a></li>
    <li class="nav-menu--item"><a href="#">U.S.</a></li>
    <li class="nav-menu--item"><a href="#">Business</a></li>
    <li class="nav-menu--item"><a href="#">Politics</a></li>
    <li class="nav-menu--item"><a href="#">Entertainment</a></li>
    <li class="nav-menu--item"><a href="#">Technology</a></li>
    <li class="nav-menu--item"><a href="#">Sports</a></li>
  </ul>
</nav>

Writing Blocks

.nav-menu {
  display: block;
  margin: 0;
  padding: 0;
  width: 100%;
  float: right;
}

.nav-menu--items {
  margin: 0;
  padding: 0;
}

.nav-menu--item {
  float: left;
  list-style-type: none;
  margin-left: 0.5%;
  text-align: center;
  width: 12%;
  & > a {
    background: $primaryColor;
    color: white;
    display: block;
    font-size: .9em;
    line-height: 3.2;
    text-decoration: none;
    &:hover {
      background: $primaryColorLighter;
      -webkit-transform: rotate(10deg);
      transform: rotate(10deg);
      -webkit-transition: all .25s linear;
      -moz-transition: all .25s linear;
      -o-transition: all .25s linear;
      transition: all .25s linear;
    }
  }
}

Define Modifiers

.nav-menu--item__simple {
  @extend .nav-menu;
  display: inline;
  float: none;
  & > a {
    line-height: 1;
    text-decoration: none;
  }
  &:after {
    content: " | ";
  }
  &:last-child:after {
    content: "";
  }
}

Building Your Application

├── blocks
│   ├── navMenu
│   │   ├── navMenu.css
│   │   ├── navMenuItem.css
│   ├── logo
│   │   └── logo.css
│   ├── header
│   │   └── header.css
│   └── search
│   │   ├── search.css
│   │   └── search_autocomplete.css

Disadvantages

  • Repititive code
  • Ugly
  • Fighting the platform?
  • Classitis
- BEM doesn't force you to pull out common patterns between blocks. - You could do it anyway, but this can couple components unnecessarily. - Ugly - Not using the cascade? Not unique to BEM, but cascade should be used carefully and isn't always right.

Advantage: Namespacing

.my-component-name__title

vs

.my-component .title
Namespacing helps you control the styles of your code. It's poor man's encapsulation. Especially when nesting components. Especially valuable on large sites.

Organization

Image by Stewart (CC BY 2.0)

- BEM brings an inherent organization to your CSS code. Your styles are organized by blocks and, if you do BEM right, everything is a block. - High cohesion and loose coupling = Refactoring within a block

Advantage: Programmatic control

block('navMenu').elem('item').click( ... );
block('navMenu').elem('item').setModifier('current');

Reference: BEM

What's so interesting about BEM is that it helps humans organize code, but it's focus on strict naming conventions means it opens the door for programmatic interpretation too.

Advantage: Shared UI language

There are only two hard things in Computer Science: cache invalidation and naming things.

- software engineer Phil Karlton's frequently quoted saying can apply to CSS - BEM uses intuitive language to describe the UI - Shared language from the beginning

Preprocessors: LESS

.block_name {
    &__element {
        color: #f00;
        &--modifier {
         font-weight: bold;
        }
    }
}

Produces

.block_name__element {
    color: #f00;
}
.block_name__element--modifier {
    font-weight: bold;
}

Preprocessors: SASS

$b: ".block_name";

#{$b}__element {
    color: #f00;
}

#{$b}__element--modifier {
    font-weight: bold;
}

Produces

.block_name__element {
    color: #f00;
}
.block_name__element--modifier {
    font-weight: bold;
}

Preprocessors: Stylus

.block_name
  &__element
    color: #f00
    &--modifier
      font-weight: bold

Produces

.block_name__element {
  color: #f00;
}
.block_name__element--modifier {
  font-weight: bold;
}

Tools and frameworks: BEMHTML

{
  block: 'navigation',
  content: [
    {
      elem: 'item',
      content: 'News'
    }
  ]
}
BEMHTML assembles your web pages for you in terms of blocks, elements, and modifiers. It's essentially an all in one templating solution for building your client side code. Page structure is in a JSON format: the "BEM Tree". This gets converted to HTML.

Tools and frameworks: CSSO

.primary-navigation {
  font-size: 12px;
  color: red;
  font-weight: bold;
}

.secondary-navigation {
  color: red;
  font-weight: bold;
}

To...

.primary-navigation{
  font-size:12px
}
.primary-navigation, .secondary-navigation{
  color:red;
  font-weight:bold
}
Yandex's CSS Optimizer is helpful for cleaning up repeated properties. It will handle tasks like merging blocks with identical properties.

Tools and frameworks: Emmet

Rather than writing

ul.primary-navigation>li.primary-navigation__item*5

Instead write:

ul.primary-navigation>li.-item*5|bem

Results in:

<ul class="primary-navigation">
    <li class="primary-navigation__item"></li>
    <li class="primary-navigation__item"></li>
    <li class="primary-navigation__item"></li>
    <li class="primary-navigation__item"></li>
    <li class="primary-navigation__item"></li>
</ul>

Tools and frameworks: inuit.css

Example:

.pagination {
    text-align:center;
    letter-spacing:-0.31em;
    word-spacing:-0.43em;
}
[...]
.pagination__first a:before {
    content:"\00AB" "\00A0";
}
.pagination__last a:after {
    content:"\00A0" "\00BB";
}
Harry Robert's (CSS Wizardry) Inuit is built on the BEM naming convention, but it's not a pure BEM framework.

The Future (?)

Image by Sam Howzit (CC BY 2.0)

- Web Components / Shadow DOM