Archive

Archive for July, 2014

Scaling Down The BEM Methodology For Small Projects

July 17th, 2014 No comments
To make the right choices for your project, start with a general approach, or methodology.

Front-end development is no longer about individual frameworks. Tools are available — we merely have to choose. To make the right choices for your project, you need to start with a general approach, or methodology. But most methodologies have been created by big companies? Are they still useful for small companies, or do we need to reinvent them at a small scale?

You probably already know of BEM121, one of those methodologies developed by a big company — namely, Yandex2. BEM posits that three basic entities (blocks, elements and modifiers) are enough to define how to author HTML and CSS, structure code and components, describe interfaces and scale a project up to an industry-leading service.

I’ve spent some time with Yandex and BEM, and I know that this methodology works for large projects. Yandex uses BEM to develop CSS and JavaScript components; Yandex also optimizes templates and tracks dependencies in BEM, develops BEM utilities, supports code experiments and researches the field. On a large scale, this investment pays off and allows Yandex to develop hundreds of its services faster.

Would smaller teams benefit from BEM? I wasn’t sure. BEM is a layer of abstraction, offered with other tools and technologies. A small agile team switching to a full BEM stack would be questionable. Could the idea — the approach itself — be useful?

To make the right choices for your project, start with a general approach or methodology.

I had to revisit this question when my career recently took me from Yandex to Deltamethod, a mid-sized startup in Berlin. Facing ambitious development plans, we decided to try BEM on a smaller scale. We wanted the same benefits that Yandex gets from BEM: code sharing, a live style guide, scalability, faster development. We also wanted to keep our toolchain and upgrade the existing code base gradually, rather than start from scratch.

For some time, we’ve been focusing on architecture and the basics, trying aspects of BEM one by one, assessing the results, then moving forward. We keep writing down ideas, guidelines, useful tips and short tutorials. I am now convinced that BEM applies to small projects as well. I’ve written down my findings, in case you find them useful. Let’s start by reviewing the basics.

BEM 101

While semantics is considered the foundation of web development, various front-end technologies do not share the same semantic model. The HTML of a modern app is mostly a div soup. CSS by itself does not offer any structured model at all. High-level JavaScript components use abstractions that are not consistently tied to styles or markup. At the UX level, interfaces are described in terms that have nothing in common with technical implementations. Enter BEM, a unified semantic model for markup, styles, code and UX. Let’s take a closer look.

Blocks

A block is an independent entity with its own meaning that represents a piece of interface on a page.

Examples of blocks include:

  • a heading,
  • a button,
  • a navigation menu.

To define a block, you’d give it a unique name and specify its semantics. Several instances of the same block definition (such as various buttons or multiple menus) might exist in the interface.

Any web interface can be represented as a hierarchical collection of blocks. The simplest representation is the HTML structure itself (tags as blocks), but that is semantically useless because HTML was designed for structured text, not web apps.

Elements

An element is a part of a block, tied to it semantically and functionally. It has no meaning outside of the block it belongs to. Not all blocks have elements.

Examples of elements include:

  • a navigation menu (block) that contains menu items;
  • a table (block) that contains rows, cells and headings.

Elements have names, too, and similar elements within a block (such as cells in a grid or items in a list) go by the same name. Elements are semantic entities and not exactly the same as HTML layout; a complex HTML structure could constitute just a single element.

Modifiers

Modifiers are flags set on blocks or elements; they define properties or states. They may be boolean (for example, visible: true or false) or key-value pairs (size: large, medium, small) — somewhat similar to HTML attributes, but not exactly the same. Multiple modifiers are allowed on a single item if they represent different properties.

Blocks and the DOM

How do you work with BEM while still using HTML? You do it by mapping DOM nodes to BEM entities using a naming convention.

BEM uses CSS class names to denote blocks, elements and modifiers. Blocks, elements or modifiers cannot claim any “exclusive ownership” of DOM nodes. One DOM node may host several blocks. A node may be an element within one block and (at the same time) a container for another block.

A DOM node being reused to host more than one BEM entity is called a “BEM mixin.” Please note that this is just a feature of convenience: Only combine things that can be combined — don’t turn a mix into a mess.

The BEM Tree

By consistently marking up a document with BEM entities, from the root block (i.e. or even ) down to the innermost blocks, you form a semantic overlay to the DOM’s existing structure. This overlay is called a BEM tree.

The BEM tree gives you the power to manipulate the whole document in BEM terms consistently, focusing on semantics and not on a DOM-specific implementation.

Making Your First Move

You might be thinking, “I’ll give BEM a try. How do I start migrating my project to BEM? Can I do it incrementally?” Sure. Let’s start by defining some blocks. We will only cover semantics; we’ll proceed with specific technologies (like CSS and JavaScript) later on.

As you’ll recall, any standalone thing may be a block. As an example, document headings are blocks. They go without inner elements, but their levels (from top-most down to the innermost) may be defined as key-value modifiers.

If you need more levels later, define more modifiers. I would say that HTML4 got it wrong with

to

. It made different blocks (tags) of what should have been just a modifier property. HTML5 tries to remedy this with sectioning elements, but browser support is lagging.

For example, we get this:

BLOCK heading
MOD level: alpha, beta, gamma

As a second example, web form input controls can be seen as blocks (including buttons). HTML didn’t get it exactly right here either. This time, different things (text inputs, radio buttons, check boxes) were combined under the same tag, while others (seemingly of the same origin) were defined with separate tags ( and