Skip to content Paweł Grzybek

BEM with Emmet

You’ll notice a Russian theme to today’s post. Emmet, created by Sergey Chikuyonok from Moscow, is a fantastic extension available for the majority of today’s popular code editors. BEM (Block, Element, Modifier) is a very widely used methodology that helps me to keep my projects sane and well organised. It is created by some very clever guys from Russia’s largest search engine — Yandex.

BEM requires a lot of typing, but Emmet helps you to create a markup with less typing. You probably can guess where I’m going with this. If not, have a look at Wes’s tweet that inspired me to dive into the subject.

Emmet filters

Emmet is of the best things ever made for developers. It allows you to expand small abbreviations to serious chunks of code. Have a look at this easy example:

Emmet

Cool, yeah? I hope that you’re already using it, but if not go here and download the extension to your editor of choice. But that’s not everything that it comes with. One of the features are filters:

Filters are special post-processors that modify expanded abbreviation right before output to the editor.

Using filters is as easy as passing pipe (|) followed by shortcut of a filter after abbreviation. Let’s make our output single-lined by passing the |s filter.

Emmet filters

BEM (Block, Element, Modifier)

This article is not about how amazing or ugly this methodology is. It works for me on the majority of my projects and it helps me a lot to keep my project well organised. If you would like to learn more about it, I highly recommend you read official documentation or Harry’s article. Developer’s preference are different and some prefer to separate blocks and elements by a single underscore, some prefer double underscores. It’s the same with the modifier classes, some prefer a single hyphen, some prefer double hyphens. I prefer to follow the official notation with double separators. Let’s stick to the article example and have a look at how to BEMify this markup:

<article class="post">
  <div class="post__title"></div>
  <div class="post__date"></div>
  <div class="post__content"></div>
</article>

Using BEM filter with Emmet

You know about filters, you know about BEM. Let’s have a look at how to apply the |bem filter in practice:

Emmet bem filter

Love it! Massive time saver! If you use Sublime Text you may need to apply your own settings to customise the output for your needs. Just go to Preferences -> Package settings -> Emmet -> Settings - User. My configuration file looks like this:

{
  "syntaxProfiles": {
    "html" : {
      "filters" : "html, bem"
    }
  },
  "preferences": {
    "bem.elementSeparator":"__",
    "bem.modifierSeparator":"--",
    "bem.shortElementPrefix":"-"
  }
}

As you can see I applied the html and bem filter as the default one for all .html files. It allows even more simplification of the process by omitting the filter in the abbreviation. Hopefully this article helped you to speed up your BEM workflow. Please share your thoughts, favourite Emmet features or methodologies that you use.

Comments

  • A
    Ahmad Awais ⚡

    It is working fine for me.

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Hmmm, I need to find a reason why it doesn't work on mine. Thanks for feedback.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
      • A
        Ahmad Awais ⚡

        You can check this gist I created https://gist.github.com/ahm...

        👆 you can use Markdown here

        Your comment is awaiting moderation. Thanks!
        • Pawel Grzybek
          Pawel Grzybek

          Thank you so much, I amended my snippet and now everything works fine.

          👆 you can use Markdown here

          Your comment is awaiting moderation. Thanks!
  • A
    Aleks Petrov

    Awesome, but I use Jade, and this Emmet feature don't work for me.

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Sorry @Lelique:disqus . My experience with Jade is very minimal. Can't help you this time :(

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
    • D
      Dmitriy

      For Jade you can use Bemto: https://github.com/kizu/bemto

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • L
    Ljubisa Djordjevic

    Does it work with HAML?

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Sorry but I don't use HAML. Check documentation please. This cheat sheet may be helpful too http://docs.emmet.io/cheat-...

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • P
    Piotr z blog.piotrnalepa.pl

    Unfortunately, it works only in simple cases. When I try to expand the following piece of code:

    .post>.__title+.__body>.__intro+.__main+.__comments|bem

    It doesn't work as expected. I mean I would expect to have a class .post__body__comments but I get .post__comments

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Hello Piotr.

      I'm almost sure that your abbreviation if generated accordingly to official BEM documentation. I used to nest classes same as you expect from this abbreviation, but some time ago I started to follow this shallow nesting.

      Like this:


      <div class="post">
      <div class="post__title"></div>
      <div class="post__body">
      <div class="post__intro"></div>
      <div class="post__main"></div>
      <div class="post__comments"></div>
      </div>
      </div>

      Not like this:


      <div class="post">
      <div class="post__title"></div>
      <div class="post__body">
      <div class="post__body__intro"></div>
      <div class="post__body__main"></div>
      <div class="post__body__comments"></div>
      </div>
      </div>

      Following these rules, your abbreviation generates correct output.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • C
    Christophe HERMANN

    Thanks for the trick, really usefull!
    For PHPStorm user (and WebStorm to, I guess) : Files → Settings → Editor → Emmet → HTML → check BEM in "Filters enabled by default".

    By doing this you don't need to add "|bem" at the end ;-)

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Amazing. Thanks for contribution. I may update the article with your instruction later on as majority of backend developers who I work with use PHP Storm. Thanks Christophe! Have a great day!

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
      • M
        Md Ashikur Rahman Ashik

        But in phpstorm comment always adding to bottom but i want it inline and there is no option for customization.
        Regards.

        👆 you can use Markdown here

        Your comment is awaiting moderation. Thanks!
        • Pawel Grzybek
          Pawel Grzybek

          Sorry/ it is hard to speak about php storm for me. I don't use this IDE. Hopefully you found the solution already.

          👆 you can use Markdown here

          Your comment is awaiting moderation. Thanks!
          • M
            Md Ashikur Rahman Ashik

            No dear i am using bottom line command with |c still there is not extra customization option for emmet :)

            👆 you can use Markdown here

            Your comment is awaiting moderation. Thanks!
  • J
    Jitendra Vyas

    How to set this config in Atom?

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      I don't use Atom anymore. I came back to Sublime Text. I believe that it is exactly the same tho. Inside your `config.cson` file:


      "*":
      emmet:
      preferences:
      "bem.elementSeparator": "__",
      "bem.modifierSeparator": "--",
      "bem.shortElementPrefix": "-"

      I didn't test this snippet tho, confirm if its working and correct me if I'm wrong please.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
      • J
        Jitendra Vyas

        I don't know where to put this setting in Atom

        👆 you can use Markdown here

        Your comment is awaiting moderation. Thanks!
        • Pawel Grzybek
          Pawel Grzybek

          This is a great section for you then.

          http://flight-manual.atom.i...

          👆 you can use Markdown here

          Your comment is awaiting moderation. Thanks!
  • B
    Bruce Lee

    unfortunately it doesn't work as expected in vscode

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Good point. To be fair, it is a very old article and I don't use these tools anymore. I am afraid I am unable to help out with this one, but I will appreciate if you drop a comment with a solution if you figure it out.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Looks like it is fully supported by VSCode. It is even mentioned in the official VSCode documentation. Just but running a few little examples through it, produces a little bit different results what I used to get in Sublime Text (as presented in this article), but I am sure with a little bit of a research it can be configured.

      https://code.visualstudio.com/docs/editor/emmet#_bem-filter-bem

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!

Leave a comment

👆 you can use Markdown here

Your comment is awaiting moderation. Thanks!