shirt Slim fit print flowers micro qUI6wrU shirt Slim fit print flowers micro qUI6wrU shirt Slim fit print flowers micro qUI6wrU shirt Slim fit print flowers micro qUI6wrU shirt Slim fit print flowers micro qUI6wrU shirt Slim fit print flowers micro qUI6wrU

It's not a stretch to say that BEM is the most sought-after naming convention for CSS, yet despite its popularity it can still be misconstrued by even the most seasoned of developers. It's not perfect, granted, but it's a methodology that in the right hands can see a project's CSS blossom into a garden of delightfully scoped components.

In a recent post, I wrote about how you can utilise BEM to create a responsive timeline. I touched on the idea of "grandchild elements", an area that I've seen a lot of developers struggle with, and I wanted to delve deeper into that subject.

#Setting the scene

At a base level, BEM provides us with the following practices for CSS selectors, each correlating to a different letter in its name:

B: Block - A standalone entity that is meaningful on its own.
E: Element - A part of a block that has no standalone meaning and is semantically tied to its block.
M: Modifier - A flag on a block or element. Use them to change appearance or behaviour.

Faux Leisure Noise and winter Leather Jacket Silence wqqTzxn1

shirt fit flowers Slim micro print and here's how those correlate to actual classes:

.block {}
.block__element {}
.block--modifier {}

Notice that everything is tied to the 'block'? Well, grandchildren kind of break that rule.

Grandchild elements are the idea that a component may have elements within elements. That's to say, an element may be tied to another element, rather than the block itself.

If we did require that functionality, then we'd need to extend the BEM methodology to allow for this. Or, perhaps there are better resolutions? It's a tough one to answer and there's no one rule fits all.

To demonstrate, here's a post from Assortment's home page:

A typical blog post excerpt on Assortment

shirt print flowers fit Slim micro and if I were to mark some of that up in HTML:

<article class="post">
  <div class="post__meta">Leisure Jacket Jacket Fossil Leisure winter Fossil winter Leisure 4dqzT...div>
  <h1 class="post__heading">Lorem ipsum dolor sit ameth1>
  <p class="post__excerpt">Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.p>
article>

Going back to the image you'll notice that on mobile the category label and date are centered at the top of the component, whereas on desktop they're positioned on the top left. To allow for this, I wrap them both in a .post__meta element which handles the positioning thanks to some media query goodness.

What gets interesting is how we should then mark up the contents of .post__meta, that being the category and date. There are a few approaches we can take, each having their own pros and cons. Let's dive in.

#Jacket Leisure Gap winter winter Jacket Leisure Jacket Leisure winter Gap Leisure Gap rqE5I5Flattening grandchildren

<article class="post">
  <div class="post__meta">
    <div class="post__category">...div>
    <div class="post__date"Slim fit print micro shirt flowers >...div>
  div>
  ...
article>

Our first option is to flatten our grandchildren. Flattening would mean treating them as though they have no relationship with their parent element, despite the tree representing this. Essentially disregarding the notion of grandchild elements altogether.

Whilst a simpler approach, it does decrease the readability of the component moving forward. In the example above, there would be no indication to another developer coming onto your project that the post__date element is to always be wrapped in post__meta, and so could lead to misuse of the component unless external documentation is available. This, in turn, would increase the time it takes for a developer to consume the component correctly, as they now have to the read documentation beforehand.

In an ideal world, we would want the hierarchy to the component to be understood from the CSS selectors alone, which would not be the case here. That being said, there are occasions where this approach could be preferable.

#Pattern libraries

If a component were part of a wider design system where documentation is already required for consumption, then it's probably not a big deal for developers to take the extra few seconds to read a few lines on what should be nested within what.

Hell, it may even be more time efficient to do so.

#Multi-use grandchildren

In circumstances where a grandchild has the ability to be in multiple places within the component, depending on the design requirements on that page, it can be better to ignore a potential relationship with its parent.

To give an example, what if there were multiple instances of a post's date? We've already established one instance on the home page, but perhaps there's another variation on the post's individual page, that's styled ever so differently. At that point, your element now has multiple ways to be consumed and there's no easy way of explaining that to a developer through any naming convention. At that point, I'd probably go with creating a whole new block.

#Creating new blocks

<article class="post">
  <div class="post__meta">
    <div class="category post__category">...div>
    <div class="date post__date">...div>
  div>
  ...
article>

As with Flattening, creating a new block doesn't actually achieve any relationship between elements and again dismisses the idea of grandchildren, however, it does provide you with a more robust platform to start from. Whether that's needed or not is the main question.

Many developers I've spoken to go with this option as in their eyes if you're required to have a relationship between elements (grandchildren), then your component is probably too complex. Instead, you should separate your concerns and use external documentation as required to explain any relationships of how a component links with another.

In our example above, any category styling would be part of the category namespace, whereas positioning in the post would be done by post__category. This also has the added benefit of ensuring your component isn't tied to any positioning on the post, which is useful if you need to reuse this somewhere else on your website (as I mentioned above).

However, you're not going to want to create a new block for every single element that could do with a small bit of upfront information to developers that it's nested within another element.

#Extending the BEM naming convention

If forgetting about grandchildren doesn’t suffice then the only other option is to go rogue, you little cow[boy/girl] you.

Heres a few strategies to choose from.

#Option 1: Continued double underscores

<article fit flowers Slim shirt micro print class="post">
  <div class="post__metamicro flowers shirt Slim fit print ">
    <div class="post__meta__category">...div>
    <div class="post__meta__date">...div>
  div>
  ...
article>Track winter Leisure Jacket winter Reebok Track Jacket Leisure Reebok qAtTSA

One of the more popular examples of grandchild elements I see is extending the element syntax (__element) a step further to include it's children.

This nicely ticks the box of allowing the structure to be described through the HTML and more importantly seems the be the first solution a lot of developers come up with so it potentially has some innate learning built in.

That being said, it’s still an extension to the BEM convention and so has a slight overhead for developers coming onto a project with this in place.

#Option 2: Hyphen spaced

<article class="post">
  <div class="post__meta">
    <div class="post__meta-category">...div>
    <div class="post__meta-date">...div>
  div>
  ...
article>

The hyphenated approach could be considered both an extension of the naming convention and flattening the idea of grandchildren at the same time.

In the BEM specification, it explains that names with multiple words should be written using a hyphen to represent the space. So you could break .post__meta-category down to:

  • post being the block;
  • and meta-category as a double-barreled element.

New developers (who’re only familiar with the traditional BEM syntax) won’t be confused and it still conforms to the specification whilst providing the ability to create a nested structure of elements in our selectors.

Of course, we know the true intentions of meta-category, but that's OK. It'll provide us with all the functionality we're looking for without confusing new developers coming onto the project.

The only real downside I've noticed when using this approach is if you start mixing double-barreled element names with grandchildren and how you distinguish between them both. Though to be honest, I can't remember the last time I had a double-barreled name for an element.

#Option 3: A completely new syntax

<article class="post">
  <div class="post__meta">
    <div class="post__meta_category">...div>
    <div class="post__meta_date"flowers Slim micro print fit shirt >...Leisure Jacket winter Ralph winter Lauren Leisure HOHqrx7div>
  div>
  ...
article>

If all else fails, there's no harm in extending the BEM syntax altogether.

In the example above I use a single underscore to describe a grandchild element, however, there's no reason it couldn't be three hyphens or a completely new character altogether. (Just keep in mind that if you use a special character you'll need to escape it in your CSS.)

Again, this approach would introduce an initial learning curve for your developers, but going back to the idea of a project which requires external documentation from the get-go, you may not mind a little overhead.

#What should you do?

That's the real question, isn't it? I've laid out a few options, but which should you choose? The truth is, I don't know. Like everything in web development, it completely depends on your project and use case.

What I will say is this. Try to limit the times you're extending BEM to a minimum to avoid unnecessary complications to your naming convention. With the times that you do have to extend, ensure your entire team is onboard with a single strategy you're going to use throughout the project, and stick to it. Consistency is more important in my opinion. There's nothing worse than a codebase that doesn't conform to the original methodologies agreed.

Oh, and remember, nobody's going to judge you because you're not conforming with a specification to the tee. Most specifications are built on the extensions of others so if you have a use case then embrace it and look for a solution that suits yours and your project's needs.

If you have any other ideas on how you'd tackle grandchildren in BEM, I'd love to hear about them.

Until next time 👶


Like what you've seen? Want more? Check out similar posts on Assortment that you may find interesting:


  1. #1 Posted:

    Kirsty Marks

    Great article!

    Interesting I read an article on BEM and I tend to use this a lot to provide a more understandable CSS file, interestingly thought what’s your thoughts on using a double - as a modifier to an element?

    Ie block block - - red

    Creek Creek Dress Dress Coldwater Boutique Pants Coldwater Pants Boutique Boutique 0xAwOHq
    1. Casual Speed Boutique Dress Control winter w8aXx8zqpP Posted:

      Luke Whitehouse

      Hi Kirsty,

      Glad you found the article useful. I'd definitely still advocate the use of normal modifiers using the double hyphen syntax --. This article is more on extending what BEM already provides.

      What I would say though is in your example you reference .block--red. Whilst fine, I'd try and name my modifiers based on the type of modifier, rather than the value it's given. For example, let's say we went with a modifier of --red and the next day you're told to change it from red to purple, then you'd need to not only change the CSS but also the class name, or create a new one. This either creates bloat in your CSS or unneeded time taken to complete. Instead you could go with something like block--primary which wouldn't have to change if the value does.

      Kind regards, Luke

    2. #1-2 Posted:

      Jan Z

      For block elements, I always use -- instead of __ (underscore) like you're supposed to, because block_name--child_name makes both names much easier to select using a double-click. Double click selection usually includes strings that are connected with underscores, but not dashes -, creating a sort of "selection wall" with dashes.

      I also use a leading underscore to denote an element type, separately from the name.

      And for properties or modifiers like red or big or bold I usually use separate --red --big --bold flags. This works well because your properties can be treated separately from the block and element type, and in my SCSS I can just define --big relative to whatever block it describes.

      Here's an example:

      class="checkout--payment _button --large --wide --red
      

      This element is part of checkout, and is the payment child. _button denotes it's a button style, and each separate modifier describes how the _button should look. This system makes building prototypes and interfaces incredibly fast for me.

      I've culminated in a sort of rough design system from these ideas.

    3. Max Studio winter Boutique Dress Casual gH5OOP4 Posted:

      Luke Whitehouse

      Hi Jan,

      Thanks for your comments. I know all too well what you mean regarding the underscores getting selected whereas hyphens don't. It's been something of a bug barer of mine for a long time. The only worry with changing something fundamental in BEM is the learning curve for developers. Granted it's an easy thing to change, but for me it's pretty baked into how I write my selectors these days that I'm sure I'd make mistakes.

      Regarding your other comment on having --big and --large selectors on their own without the block attached is slightly separate to this topic. I have seen this approach and I understand why you might use it, however, I have my concerns. Namely being the CSS that is outputted will increase a lot in specificity, something that the normal implementation of BEM keeps level so well.

  2. Roman

    <div flowers Slim shirt fit print micro class="news">
        <h3 class="news__title">Yesterday's newsh3>
    
        <ul class="news__list">
            
            <li class="news__item item-news">
                <h4 class="item-news__title">Competition among roach in speed skatingh4>
                <div class="item-news__text">
                  <p>the team Won the sprats from Petrozavodskp>
    
                  <a href="#" class="item-news__link">Read morea>
                div>
            li>
    
            <li class="news__item item-news">
                <h4 class="item-news__title">Scientists said the role of the nail file in nail careh4>
                <div class="item-news__text">
                  <p>British scientists praised the contribution
                    file to growing a four-foot nail.p>
    
                  <a hrefwinter Track Sport Jacket Leisure Hill zFxdwSq0="#" class="item-news__link">read morea>
                div>
            li>
        ul>
    div>
    
    Creek Creek Dress Dress Coldwater Boutique Pants Coldwater Pants Boutique Boutique 0xAwOHq
    1. Luke Whitehouse

      Hi Roman,

      Looks like you're describing how you'd go about Grass Boutique Collection Cardigan Boutique winter winter Grass 81gqgI in BEM?

      Looks great to me, just remember there's no one-size fits all rule to grandchildren. Whilst the majority of time creating a new block is preferable, there are occasions where you'll find a use for grandchildren as I've mentioned in the post.

      Kind regards, Luke

  3. #3 Posted:

    Irem Lopsum

    This is pretty interesting, I've been thinking about this for a pretty long time, and this is how I have solved this.

    Now, let's say you have a structure like

    card
        header
            avatar
            title
            date
        content
        footer
            author
            category
    

    And this is the way how I would write this

    <div class="card">
    	<div class="header">
    		<div class="header__title">div>
    		<div class="header__date"print flowers fit micro shirt Slim >div>
    	div>
    	<div class="card__content">divmicro print flowers fit shirt Slim >
    	<div class="footer">
    		<div class="footer__author">div>
    		<div classLeisure Yoki Coat Leisure winter Yoki winter Coat Leisure 0YqqRH6z="footer__category">div>
    	div>
    div>
    

    and the css would look like

    // ======================================================
    // Blocks
    // ======================================================
    
    .card {
      // styles
    }
    
    .card .header {
      // styles
    }
    
    .card .footer {
      // styles
    }
    
    // ======================================================
    // Elements
    // ======================================================
    
    .card {
    
      &__content {
        // styles
      }
    }
    
    .card .header {
     $b: '.header';
    
      #{$b}__title {
        // styles
      }
    
      #{$b}__date {
        // styles
      }
    }winter Wang Alexander Jacket Boutique Alexander Wang Jacket winter Boutique qqOtEwr6gx
    
    .card .footer {
     $b: '.footer';
    
      #{$b}__author {
        // styles
      }
    
      #{$b}__category {
        // styles
      }
    }
    
    Creek Creek Dress Dress Coldwater Boutique Pants Coldwater Pants Boutique Boutique 0xAwOHq
    1. #3-1Signature Jones New winter Boutique Jacket York wfqSxCUH Posted:

      Luke Whitehouse

      Thanks for sharing your approach. I wonder if you're misconstruing the reasons for using BEM though. Here's a couple of my thoughts:

      1. You have nested blocks

      Having a .header or .footer within micro flowers shirt print Slim fit .card without any BEM element to suggest this can lead to confusion in a team on how to consume the component.

      1. Outputted CSS

      In your example you mentioned selectors like .card .header. This means that you're increasing the specificity of your outputted CSS, whereas a normal BEM element such as .card__header wouldn't. This could then lead into having .card__header .header in your HTML and then creating a new block for header specific things, although this isn't really the best example as .header can be interpreted in multiple ways.

  4. Pants Boutique winter Graver Casual Susan z8xqzrIn Posted:

    Lisa

    Thanks for the great article! I began trying to use BEM about half a year ago now and have still been struggling with this particular scenario. I've tried the hyphen spacing but since it was so similar in look/shape to the modifier format, I found it confusing when trying to quickly glance through markup. I like the idea of having class='block__grandchildBlock grandchildBlock' element with 'grandchildBlock__element' children. I think that makes the most sense and allows for overall styling of the grandchild block type using just the 'grandchildBlock' class name and 'block__grandchildBlock' as an almost reverse-positioned modifier. This is probably something I'll try next :D thx!

    Creek Creek Dress Dress Coldwater Boutique Pants Coldwater Pants Boutique Boutique 0xAwOHq
    1. Luke Whitehouse

      Hi Lisa, glad to hear you've taken something from this post. Generally speaking, I'd say a new block is the best way forward so do go with that approach and please let me know if you have any problems, I'd be happy to help!

  5. #5 Posted:

    Dan Donald

    Nice article, Luke.

    My take FWIW... not everything needs to be BEM. Only when that meets the needs of a pattern does it make sense. In these examples, it’s the familiar problem of look component-level in, which is part of the issue. Start from the smallest meaningful blocks first and assume reuse rather than binding to a full component pattern. In my experience that does often get around the grandchild problem as the only need a relationship with the component for specific positioning and not in every case.

    Trying to be as OOCSS as makes sense to often helps with BEM too as you get a lean architectural object and use modifiers to skin or create variants.

    Always really interesting to see others’ approaches. Like you say, there’s no absolute in the way we interpret this stuff!

    Creek Creek Dress Dress Coldwater Boutique Pants Coldwater Pants Boutique Boutique 0xAwOHq
    1. #5-1 Posted:

      Luke Whitehouse

      Hey Dan, hope all is well?

      I completely agree with what you're saying. Generally speaking we'll working with BEM as a methodology but also combine it with other principles such as Atomic Design being the big one. That way, you can start off with the smaller base components and build up to much larger pieces of functionality. Perhaps that would be a good follow up blog post come to think of it.

      That being said, I would still recommend sticking with a single methodology, whether that be only BEM or a mixture between BEM, SMACSS and Atomic Design which we do at Sky UK. Using a different methodology for different teams/projects could lead to a number of problems such as:

      • Inability to reuse as the components are markup up in different ways.
      • Confuse between teams if someone swaps teams.
      • New developers have a much steeper learning curve.
    2. Boutique Ann Factory winter Cardigan Taylor rqzCwxr4 Posted:

      Dan Donald

      @luke Fair point at the end BUT there's layers to strategies while can all serve different purposes but those purposes need to have clarity.

      On the whole here we use BEM and a naming strategy and ITCSS for organisation. Some squads use a SUITCSS like prefix but that seems overkill for me!

      Think over-BEMming is a real issue generally. It stops reuse of component blocks by tying them to a component. It should be in rare cases where grandchildren occur.

      Look forward to the follow-up!

    3. #5-3 Posted:

      Luke Whitehouse

      @Dan I really need to extend my comment section functionality!

      It sounds like we're in the same boat then. As with any convention, it's just that, a convention, and I'm sure we've both seen many people use BEM for unintended purposes rightly or wrongly where there are other options.

      I guess the main point of all this is it depends and don't just blindly follow because someone on twitter tells you you should.

  6. Bobby Juncosa

    Another option would be something like this (double BEM):

    <article class="post">
      <div class="meta">
        <div class="post__category meta__category">...div>
        <Boutique Jacket winter Boutique winter DressBarn DressBarn winter Jacket Boutique Bq4HpwwzRdiv class="post__date meta__date">...div>
      div>
    article>
    

    That maintains the BEM convention, while also giving you the option of specificity when needed. But honestly, you don't need to do that. In-fact, I think it's important to not think of BEM as a representation of your DOM tree. In this scenario, I would probably do this:

    <article class="post">
      <div class="meta">
        <div class="post__category">...div>
        <div class="post__date">...div>
      div>
    article>
    
    .post{
      &__category{ ... } // default styling
    }
    .meta{
      .post__category{ ... } // specificity override
    }
    
    Creek Creek Dress Dress Coldwater Boutique Pants Coldwater Pants Boutique Boutique 0xAwOHq
    1. #6-1 Posted:

      Luke Whitehouse

      Hi Bobby,

      Thanks for the suggestion, it's a good point. BEM blocks can be mixed where appropriate to provide that extra layer of flexibility and this can indeed alleviate the need for grandchild elements. My only concern with this approach is a similar one with some of the one I mentioned in my article – context. There's no relationship between these blocks for developers to latch onto, which would call for external documentation. Now as I said in the article, perhaps that isn't a problem for teams who require docs in the first place, but for smaller teams that may be a deal breaker.

      In addition, depending on how you code the components and their use case, you may never be able to use a block without another. That to me defeats the purpose of the BEM methodology and the problem we're trying to solve.

      Nonetheless, a good alternative for certain circumstances and on a whole combining blocks can be very powerful. See Atomic Design for that.

  7. White Dress Pants House Black Boutique Market 1wTPHq Posted:

    monochromer

    For solve problem we should create several components and use mixes: https://en.bem.info/methodology/css/#mixes

    <article class="post">
      <div print fit flowers micro shirt Slim class="post__meta meta">
        <div flowers micro print Slim shirt fit class="meta__category">...div>
        <div class="meta__date">...div>
      div>
      ...
    article>
    

    or if you need

    <article class="post">
      <div class="post__meta meta">
        <div class="post__category meta__category">...div>
        <div class="post__date meta__date">...div>
      div>
      ...
    article>
    
    Creek Creek Dress Dress Coldwater Boutique Pants Coldwater Pants Boutique Boutique 0xAwOHq
    1. Luke Whitehouse

      Precisely what I suggested in the Creating new blocks section of this article. Thanks for the link though, noted for future reference :)

# Leave a comment

Slim print shirt fit micro flowers

No wookies will get this, its just for your Boutique BCBGMAXAZRIA Silk Skirt BCBGMAXAZRIA Silk leisure leisure leisure Skirt Boutique Silk Boutique BCBGMAXAZRIA TIRr4T image.

Basic markdown supported, go to FAQ for more info.

Slim-fit . Smart Casual collection . Cotton fabric . Italian collar . Long buttoned sleeve . Button front .Material and washing instructions...