Learn the CSS "BEM" Naming Convention with Oreos - AKOS
Loader
Skip to content

Learn the CSS “BEM” Naming Convention with Oreos

Reusable CSS components and code sharing in front-end development using Block, Element and Modifier (BEM) naming convention.

It’s rare, that Frontend engineers change their ways, It’s rarer, for Frontend engineers to adapt new conventions. It’s rarer than rare, for Frontend engineers to stay happy with any decision they make. And, I run among this rare breed of conventional rags; while others may have adopted the darkness of being conventional, I was born in it, molded by it.

I believe that being adaptable has become a cliché, it’s everywhere, from internet memes to agency mottos (ironic…if you know who I work for). Change is hard, but accepting that you need to change is even goddamn harder.

But, change, if and when you do realize it’s necessity, can be uplifting and almost rejuvenating, like a deep exfoliation face treatment with crystals.

Now, Daniel Ramirez (@drmz.io), one of my colleagues is always pushing me to learn new things, and I hate him for it. “Damn Daniel, back at it again with your new world ways.” Although it feels very recent, because I’m old, it was maybe about a couple years ago that I got introduced to the BEM naming convention. At first, I didn’t like it as it felt like an overkill for writing CSS classes, but slowly – too slowly, I ended up embracing it. And now that I have, I want to write about it because that’s what people do.

Learning by association is exactly how I teach; I also have an affection for analogies, and Oreos.

What exactly is “BEM” and why use it?

BEM: Block Element Modifier, is a methodology that helps you create reusable components in CSS and code sharing in front-end development.

You can read more about it on the website but it’s basically, it says that “BEM is a highly useful, powerful, and simple naming convention that makes your front-end code easier to read and understand, easier to work with, easier to scale, more robust and explicit, and a lot more strict.” 

The BEM approach ensures that everyone who participates in the development works with a single codebase and speaks the same language. Using BEM’s proper naming convention will better prepare you for design changes made to your website.

“BEM”, as the name suggests, is made of three components – Blocks, Elements and Modifiers. And, so are Oreos – Cookies, Creme and Flavor.

Side Note: Look up why Oreos calls their filling Creme instead of Cream. Spoiler Alert: FDA.

A Block is a standalone entity that is meaningful on its own, it is a parent to it’s children – Elements. Elements have no meaning of their own and are semantically tied to their parent block. Modifiers are flags applied to the block or it’s children Elements to change their appearance or behavior.

Another unexpected benefit from using BEM has been the ease of naming class selectors. I am not spending hours and hours thinking of yet another creative way to name my classes like my first born, which is also yet to be decided.

Consider this web-page listing of Oreo offerings introducing us to the different magical flavors available. 

Let’s define and identify our Oreo Blocks, Elements and Modifiers.

1. Identify Blocks and Modifiers

Based on the design above, we want to build it in an efficient way for us to re-use our Block class name selectors within our Elements. For that, we start off by defining our Blocks and Elements. Not going to name them just yet, just identify what a block is and what are the elements inside each.

Block: Each Oreo package row
Elements: Single Oreo Packaging Graphic, Oreo Logo, Product Title, Product Description, Forward Path Action button, Forward Path Sub-action Button

2. Identify Modifiers

Once we have blocks and elements defined, we need to identify and plan for modifications needed for each distinctive element compared to our baseline, ‘The OG Oreo’.

For our Oreos listings page, we have 2 Modifiers:

  • Flavor of Oreo: Impacts row background color and font color within Block.
  • Availability of Oreo: Impacts button style, color and state inside each Block.
Flavor Modifiers: Oreo Block Background Gradient, Font color
Availability Modifier: Button Style, color and state

Naming

Blocks:

Since blocks are meaningful stand alone entities, we want to name them as such. There are times that blocks can be nested within or interact with each other, but semantically they are equal.

For our Oreo products, each Oreo row block will be named oreo.

Elements

Inside each Block there are Elements that have no independent usage. Looking back at our Oreo listings: product image, Oreo logo, the product name, description, and CTA button are all dependent on the Block it lies in. There are no other instances where we will use these elements across our design that requires inheriting exactly the same layout and style specifications.

CSS class for Elements is formed as parent Block name followed by two underscores and element name. The element name can and should be a small description of its purpose in our layout. For our Oreo Listings example, here’s how we’ll name the elements.

Primary Elements

Package Image (Left Column): oreo__package

Oreo Details Area (Middle Column): oreo__details

Oreo CTAs (Right Column): oreo__action

Secondary Elements

(Inside Details Column)

Oreo Logo: oreo__details-logo

Oreo Product Name: oreo__details-name

Oreo Product Description: oreo__details-description

(Inside Actions Column)

Oreo CTA Button: oreo__action-eat

Oreo CTA Subtext: oreo__action-sub

Modifiers

Declaration and organization of Modifiers is probably my favorite part of using BEM. If you’ve used any frontend frameworks like Bootstrap, Foundation, Material UI etc., you are probably already familiar with usage of Element Modifiers.

  • Bootstrap Buttons: btn-lg btn-block btn-success (btn-primary, btn-lg, and btn-link are modifiers for the btn element)
  • Foundation Buttons: large expanded success (large, expanded, and success are modifiers for the button element)

These are examples of Element level modifiers, and that’s an easy implementation to add to your workflow. However, if you’re able to conceptualize and use modifiers on a Block-level, it can help out tremendously.

In our Oreos listings – we can certainly take the route of Element-level modifiers by adding modifiers to each element selector. But, wouldn’t it be easier to just add modifiers to the whole block since almost all of our modifications are block (Oreo package) specific. The background color gradient of the block, the font and button color, and font style of action sub-text is all dependent on the block.

Our Oreo Modifiers apply to three styles: Block background gradient, Block text color, and action buttons. From the three, Block background gradient and text colors are inherited from the Oreo flavor, while action button style (Ghost/Hollow vs Filled) is dependent on availability. This leads to two types of modifiers that can be applied to our block.

  • Flavor Modifier (controls the background and text color): oreo--flavorX.
  • Availability Modifier (controls the button style): oreo--is-unavailable

What happens if we don’t use a modifier? In our CSS block declarations, we can have a default styles for our primary block (The OG Oreo) and followed by Modifier declarations that overwrite the OG. Our default declarations will be the background and text color of the OG Oreo, and the filled button reflecting a currently available button style.

Here’s a list of modifiers for our entire Oreo listings page:

Flavor Modifiers

Default (No Modifier): The OG Flavor Style

oreo--the-og: Radial Background and Text Color: #272320

oreo--peanut: Radial Background and Text Color: #BF9859

oreo--redvelvet: Radial Background and Text Color: #BF9859

oreo--mint: Radial Background and Text Color: #61AD8F

oreo--chocolate: Radial Background and Text Color: #5B372C

oreo--birthday-cake: Radial Background and Text Color: #F963B9

oreo--lemon: Radial Background and Text Color: #F5B529

Let’s Make Oreos

Now, since we have all our BEMs defined and Class names finalized, let’s get to the best part.

Defining the Block(s)

/* Block component */
.oreo{
 /* Elements go here */
}
<div class="oreo">
    <!-- Elements Go Here -->
</div>

<!-- Block with flavor Modifier -->
<div class="oreo oreo--red-velvet">
    <!-- Elements Go Here -->
    ...
</div>

<!-- Block with flavor Modifier and availability Modifier -->
<div class="oreo oreo--red-velvet oreo--is-unavailable">
    <!-- Elements Go Here -->
</div>

Defining Elements

/* Block component */
.oreo{
 /* Elements within the block */
 &__package{
     ...
 }
 &__details{
     ...
 }
 &__action{
     ...
 }
}
<div class="oreo"> <!-- << Block >> -->
    <div class="oreo__package"> <!-- << Primary Element: Package Image >> -->
        <!-- <img> goes here --> ...
    </div>
    <div class="oreo__details"> <!-- << Primary Element: Package Details >> -->
            <!-- Secondary Elements for Details go here -->
            ...
    </div>
    <div class="oreo__action"> <!-- << Primary Element: Package Purchase Action >> -->
        <!-- Secondary Elements for Purchase Actions go here -->
        ...
    </div>
</div> <!-- << End Block >> -->

Adding Modifiers to Blocks

<div class="oreo oreo--red-velvet oreo--is-unavailable"> 
    <!-- << Block Level Modifiers Added for Flavor and Availability >> -->
    ...
</div>
/* Colors Sass Map */
$flavor-colors: (
   the-og: #272320,
   red-velvet: #A92229,
   mint: #61AD8F,
   choco-creme: #4C241F,
   birthday-cake: #F963B9,
   peanut-butter: #BF9859,
   lemon: #F5B529
);

/* Flavor Modifier Classes */
@each $name, $color in $flavor-colors {
    .oreo--#{$name}{
        color: $color;
        background: linear-gradient(to right, rgba(255,255,255,0.3) 0%,rgba($color,0.3) 50%,rgba(255,255,255,0.3) 100%);
        button{
            background: $color;
            &:hover, &:active, &:focus{
                background: smart-scale($color, 25%);
            }
        }
        .oreo__action-sub{
            color: $color;
        }
        /* Button Modifier - if unavailable */
        &.oreo--is-unavailable{
            button{
                border: 1px solid $color;
                color: smart-scale($color, 25%);
            }
        }
    } 
}

Sprinkle in some the rest of the CSS for your layout, and voilà! we have our Oreo Listings Page.

See the Pen Oreo x BEM by Sahil (@sahilakos) on CodePen.

See the Pen Oreo x BEM by Sahil (@sahilakos).

Now since you have the Oreo grid laid-out on your screen, it’s time to jump back into the real world; so head on over to your nearest grocery store and buy all the different flavors of Oreo you can find.


AKOS works with businesses and non-profits to build their digital presence, and marketing systems for maximum impact. Learn more and get in touch with us at akosweb.com/contact

netsuite celigo iglobal braintree ups angular-js aweber aws constant-contact css3 drupal-8 heroku html5 hubspot javascript laravel magento mailchimp mysql node-js october-cms php postgresql react-js redis salesforce shopify silverstripe sketch squarespace wordpress AKOS LinkedIn Medium Facebook Instagram Medium Imagination Foundation Caring For Canines Code Technology Co+Hoots Flexible Dieting Heckler Design Medicx Media Solutions OdySea Aquarium Skin Actives Scientific Tech Talent Awards Wired PR Yeager Play Button