Blogs

How to Use Tailwind With BEM

How to Use Tailwind With BEM

Wojciech Krzysztofik

20 Jan 2021

Merge the King of Utility with the best of Modular CSS to create a brilliant combination for your projects.

Innerworks is coming soon...

This blog was originally published on our previous Cogworks blog page. The Cogworks Blog is in the process of evolving into Innerworks, our new community-driven tech blog. With Innerworks, we aim to provide a space for collaboration, knowledge-sharing, and connection within the wider tech community. Watch this space for Innerworks updates, but don't worry - you'll still be able to access content from the original Cogworks Blog if you want. 

If you’re looking for a simple approach to creating Modular CSS code, the Block, Element, Modifier methodology (or BEM) has for a long time, been a great place to start.


In 2020, things changed a little and utility-first CSS frameworks were confirmed as the way to go when the State of CSS reported Tailwind CSS as the hottest utility-first CSS framework on the scene.

Now, a lot of us are still a little reluctant to use the Tailwind approach. That left me (and a few other developers) wondering how can I hold onto the benefits of using BEM in my projects whilst adopting the new the Tailwind approach? 

I began to think about how these frameworks could work together. In this blog, I’ll show you how to merge the “King of Utility” with the “best of Modular CSS” to create a handy combination for you to use on your projects.

Let’s start with a quick reminder of how the BEM and utility-first approaches look in practice. 

 

 

The BEM methodology.

As I mentioned at the beginning, this methodology is based on three key things: Block, Element and Modifier. 

Image source: BEM

Block

Other examples of standalone entities are footers and navigation menus. 

Element

This can also be a header logo, footer link or button label. 

Modifier

Other descriptions of special behaviour of a block or element could be; active, disabled, underlined or large.

Example of a button

<footer class=”footer”>

    <button class=”footer_button”>Default Button</button>

    <button class=”footer_button--larger”>Large Button</button>

</footer>





 

 

The utility-first methodology: Tailwind. 

This approach assumes that the framework is packed with a lot of classes like text-center, mt-5, text-black, flex and rotate-90 that can be composed to style any element directly in the markup.

 

Example of a button: 

<button class=”text-center text-black my-5 border-black”>Button text</button>

As you can see, this approach allows you to create any designed element very fast. It is easy and intuitive to use, plus, it allows you to build any design without writing any line of code.

But here we come to the main disadvantage (that scares many of you away). Markup in the Tailwind approach doesn’t look as clean and readable with so many classes being assigned to elements.

Do. Not. Worry.  

There is a cool feature in Tailwind, @apply directive, that allows you to change this approach a little bit and helps to take back the control on the markup. It will allow you to extract common utility patterns to CSS component classes.

Example of a button: 

.button {
    @apply text-center text-black my-5 border-black;
}

And that’s it! You can go step further and use this directive and apply BEM again:

.button--red {
    @apply .button bg-red;
}

As Tailwind is based on its config file (tailwind.config.js) it contains all general settings like breakpoints, colours, font sizes which means you don’t need to keep those things in CSS variables any more. Using my above method, I now have a similar config file with the same structure in different projects which provides a welcomed boost in efficiency, productivity and organisation on projects as other developers can quickly dive into new tasks.

I’m really satisfied with how this combination works and I hope I’ve encouraged you to give Tailwind and BEM a chance to meet on your projects.

 

:)