I have been writing web templates using HTML and CSS for over 10 years. I am no expert or at least I stopped being one with the rapid development of CSS 3 and all the nice things modern browsers support nowadays. I have also never been a strictly frontend developer, so I don’t follow the CSS development that closely.
In the past I typically wrote CSS by creating custom classes, either trying to create a set of classes for components using semantic names or defining a utility class here and there.
BEM and other approaches
At my previous job we tried adopting BEM as the naming convention and consequently I used it for my own stuff as well. In larger codebases, CSS has always became unmaintainable, partially due to its nature and partially because people I have worked with were never true frontend developers who would invest the time to make strict rules and follow them. In that context, BEM didn’t really help that much with maintainability. I was also frequently struggling to structure the HTML and name the relevant CSS classes properly. I am not saying that BEM is a bad way to structure CSS, just that creating maintainable CSS with it is still hard and requires experience.
One of the more lightweight alternatives to BEM is SMACSS. It definitely looks promising because of its simplicity, however I have never came around to actually put it anywhere.
And of course we can use frameworks like Bootstrap or Bulma to help us with the basic layout and elements, but eventually we will need to write our own CSS anyway and so it hardly solves the problem for highly-customized websites.
Recently I have seen a lot of discussions about atomic or utility-first CSS. If you want to read about the general advantages of it there is a nice collection of articles named The Case for Atomic / Utility-first CSS. Of course, this approach has its own problems, starting with possibly ugly and bloated HTML, bloated CSS without optimization, new ways to think about creating reusable components and so on. I know I was skeptical at first. Anyways, given all the bad experiences with organizing CSS, I wanted to give it a try.
To do that, I chose Tailwind CSS, one of the utility-first frameworks that is all the rage now. I used it first on a micro page efficientdeveloper.com and then experimented with it a bit more in other projects.
Once the setup is finished, building/prototyping new layouts and elements is really easy, fast and productive. There are plenty of examples on the official website and even a screencast from the authors. It definitely takes a moment to learn some basic naming conventions of the utility classes but there are typically very easy to remember if you know CSS since they are derived from the CSS properties. In the beginning I recommend to search for “Tailwind cheat sheet” online and pick something you like – there are plenty of them and they are a big help.
This is how Tailwind looks like on efficientdeveloper.com:
<body class="flex content-center max-w-full justify-center my-20">
<div class="main flex flex-col w-3xl rounded-lg pt-56 md:border border-gray-800">
<h1 class="font-semibold text-6xl text-center text-yellow-100 mx-10 mb-10">efficient developer</h1>
<h2 class="font-hairline text-2xl text-center text-gray-500 mx-8 my-10">upcoming book for software engineers</h2>
<div class="text-red-400 border-red-400 border-dashed border inline-block w-32 rounded-lg p-2 text-center my-10">
<a class="text-blue-400 text-center p-10 text-2xl hover:underline" href="https://bit.ly/2RMbsl9" target="_blank">Sign up for news</a>
<a class="mb-24 mt-10 mx-10 sm:mx-24 block" href="https://twitter.com/stribny">
<svg class="tw-icon" xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-twitter">
<path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"></path>
I am definitely at the beginning of my Tailwind/atomic CSS journey, but I can already see one big benefit for me: I don’t have to think about naming classes most of the time which really reduces the cognitive load when creating a new layout or a component, especially so compared to BEM. I am also not really writing any CSS, just writing my HTML markup. It is quite pleasant not to go back and forth between markup and styles. On top of that there is a great VSCode extension Tailwind CSS IntelliSense which makes writing markup really fast.
I haven’t played with extracting components yet, so for now all I do is just using utility classes and making a copy of the code for the same “components”. For large projects this is probably not the best way, but for smaller projects this feels great and allows us to customize each instance easily. This is also not an issue if we are using a frontend framework like Vue.js or React, because then we can just use Vue or React components.
Now, I am definitely sold on the prototyping side of things, but what about maintenance? I think editing becomes easier with Tailwind, because we don’t have to go look for all the places where a specific class is defined and overwritten (even though browsers make this pretty easy) and we will typically not break anything in another place, because we are just adding or removing atomic classes for specific HTML elements. Also, no more mess in the CSS, as the number of custom classes is reduced to a minimum. How this changes once we want to extract Tailwind components I am not sure.
Overall it seems like Tailwind CSS is a solid choice for building web interfaces, especially interfaces which will use a lot of custom elements, because creating new elements is so easy. I definitely recommend to check it out, even if you are skeptical of utility-first CSS concept.Loading Likes...