Selecting the right CSS framework is key to scaling the team's capabilities and experience over time. When working with many technologies internally, it's crucial to streamline as many processes as possible to avoid inefficiency. Time is money!
Over the past few years at Clean Commit, we’ve built a vast spread of applications and websites. Since 2020 we have been investing in growing our JAM Stack capabilities, focusing on top-performing e-commerce projects using Shopify, BigCommerce and other headless-enabled systems.
At the same time, we're still actively developing new projects based on WordPress and WooCommerce when it makes sense. Not to mention that our team is actively developing custom applications with different stacks.
If you spot any of our products in the wild, you will see the use of different technologies and frameworks like React, Vue and templating languages like Laravel Blade on the front end. These technologies are significantly different, so we’ve had to find a way to standardise their implementations as much as possible.
Problem - lack of standardisation
We work with many different technologies. Using multiple front-end frameworks and backend technologies complicates work when our devs switch from project to project. Additionally, some of our projects used different styling approaches. Jumping between styling approaches made it almost impossible to reuse visual components between projects.
With Tailwind, we've been able to standardise CSS across all of our projects. Sticking to a consistent approach makes it easier to code at a constant pace, grow our front-end team's know-how and achieve visual bug-free outcomes quickly and reliably. It's also significantly easier to reuse components across different projects, even when using different front-end frameworks.
The way we worked before Tailwind
Back in 2015, our team was in love with Bootstrap. Bundled UI components made it easy to create handsome apps and sites, so we did just that. Efficient! Right..? Well, no, not really.
As we grew and our designs became more complicated, we started using custom styles added on top of Bootstrap. In the long run, this approach added unnecessary bloat to our projects and complicated the codebase.
The latter was solved by introducing BEM, and we tried to resolve the former by adding utility classes. After all, why should we repeat our code when we can simply reuse classes. Brilliant! Well, not really. This approach made us ask the question - do we even need Bootstrap? We modified it heavily already, cut out components we don't need, added a bunch of utility classes on top and then added a lot of custom code on top for each project.
Maybe if we can remove Bootstrap and create a custom base for our projects, that would speed up the work? So we went happily on our way to do just that. We scrapped Bootstrap, set up Sass mixins, generated a bunch utility classes, and it was a mess!
Our designers used slightly different layouts for their projects which forced us to adjust utilities every time or add a lot of custom classes to each project. We could easily fix this problem by adding an extremely large collection of utilities with unused classes being purged and one config file to adjust them. See where I'm going with this train of thought?
At that point, our team decided it was time to go back to the drawing board. The first step was to research available solutions. I've heard about Tailwind before, but only after some personal experimentation was I convinced it was a viable solution to issues we've been experiencing. As a company, we reached a point where the best path we could take was reinventing Tailwind. Utilities? Check. Purge? Check. Easy configuration? Check check check.
Rediscovering Tailwind after our internal trial and error process was a real blessing. We knew what we wanted, now the easy part, right? Right?
Getting the team on board
We found our solution and just needed to implement it. What could go wrong?
Making people change their way of doing things is challenging. Some of the team heavily preferred other frameworks like Bootstrap or Bulma. Others on the team were heavily invested in React and wanted to use styled components. Understandably, everyone defaults to the framework and stack they know the best.
Along with the preference issue, we didn't have any standards in place to support Tailwind development.
Switching to Tailwind is unintuitive at first. The biggest question is when to use Tailwind, and when should I use custom classes? After some experimentation, we decided to componentise as much as we could and use Tailwind classes except for couple of edge cases.
At first, using Tailwind “correctly” was tricky for most of our team. Some of our guys still used custom classes using Tailwind's
@apply. This approach was fortunately eliminated after couple of projects and code reviews sessions.
The best method to encourage devs to use Tailwind classes was debugging fully tailwind written code bases. Despite more complex markup, it's much easier and faster to debug styling issues when only Tailwind classes are used.
Armed with the knowledge that debugging existing projects will be easier, the team became much more receptive to the idea of fully committing to Tailwind.
Why we love Tailwind
One framework to rule them all
Our team focuses on delivering quality code. Our definition of “quality code” means little to no bugs, simply maintainable and easy scalability. We're curious and often want to try the "next big thing". That's why we experiment when it makes sense. It's a challenge to manage multiple stacks (duh), so it's nice to have one common denominator.
Our approach to styling is always built on top of Tailwind. This standardised procedure makes it a tad easier to experiment and move components across stacks (should something goes wrong). Thanks to our adoption of Tailwind CSS, we're more agile in our everyday work.
Standardisation with the design team
After successful adoption by our technical staff, it made sense to move Tailwind over to our design department. There’s no point in having half the team commit to a framework.
Since April of 2021, our design team have used Tailwind CSS as the guidelines for every new project. Implementing Tailwind during the design process means we don't have to deviate from default configuration too much. All we do now is change colours, fonts and adjust box shadows. The naming convention for different styles and colours is the same across the design which helps with collaboration and catching issues with styling early.
The bad & ugly of Tailwind
Tailwind is not all perfect. Sometimes it's simply, well, ugly. The markup at first can be overwhelming.
Just take a look at this Banner markup, and you'll know what I mean.
<div class="bg-indigo-600"> <div class="max-w-7xl mx-auto py-3 px-3 sm:px-6 lg:px-8"> <div class="flex items-center justify-between flex-wrap"> <div class="w-0 flex-1 flex items-center"> <span class="flex p-2 rounded-lg bg-indigo-800"> <svg ... /> </span> <p class="ml-3 font-medium text-white truncate"> <span class="md:hidden"> We announced a new product! </span> <span class="hidden md:inline"> Big news! We're excited to announce a brand new product. </span> </p> </div> <div class="order-3 mt-2 flex-shrink-0 w-full sm:order-2 sm:mt-0 sm:w-auto"> <a href="#" class="flex items-center justify-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-indigo-600 bg-white hover:bg-indigo-50"> Learn more </a> </div> </div> </div> </div>
The other issue with Tailwind implementation is the initial drop in productivity we've noticed. For the first 2-3 projects, our devs had problems with using Tailwind instinctively. It takes time to learn Tailwind to the point that you can easily create markups without looking at the docs.
The decrease in productivity reverses over time, and we saw a 6-10% productivity jump across our teams using Tailwind after a couple of months.
If you're looking for a new framework, try Tailwind!
Tailwind helped us to streamline our workflows and standardise our toolkit. It's not a panacea for all styling problems, but it turned out to be a perfect fit for Clean Commit.
When working on new projects, we have one less decision to make. Moving components between projects has never been easier. Our devs can easily switch between different codebases without learning (or relearning) styling practices unique to this project.
Tailwind has saved a lot of time and our sanity!