Why we use Tailwind CSS as our primary framework
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.
Before we explain our thoughts on Tailwind, please hear out our short pitch. Are you trying to figure out the best technology stack for your upcoming website or application project? Drop our team a line to see if we can help. The worst that can happen is you get experience-backed advice!
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.
Benefits of Tailwind CSS
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.
Designing with Tailwind CSS
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.
Utility first CSS framework
One of Tailwind's main selling points is its utility classes. Utility classes are classes that are general-purpose and can be used for a variety of different types of styling. This makes them perfect for use in a variety of contexts, as they can be easily reused and don't require any specific knowledge about Tailwind to use them.
Faster styling
Fully adopting Tailwind has had a positive impact on our team's efficiency. We don't spend as much time writing custom CSS classes, and we're able to move faster thanks to the utility classes (once we started using them properly). In addition, debugging styling issues is now easier than ever before thanks to the standardised approach that Tailwind encourages.
Responsiveness
Building complex responsive layouts is easy. You can use utility classes freely across any number of breakpoints to make your design come alive conditionally - no need for Global Styles.
Highly customizable
Tailwind CSS offers flexible customization. It comes with its own built-in default configuration, but you can easily override it by making changes in the config file. The key here being easy access to everything through one location (including colors schemes and stylesheets) while still keeping things organized so they don't get out of hand during fast-paced development.
Better composition
Tailwind CSS makes it easy to break down your styles into small reusable components. By doing this, you can avoid repetition and keep things organized by creating CSS classes for every feature or section on the website instead of hogging all page space with one big style sheet that applies globally.
Consistency
Tailwind has a lot of pre-built classes for sizing and colors that will reduce or completely remove the need to implement your own design system. Or, even better, adopt Tailwind's specifications into your own design system.
Letting Tailwind take the lead has significantly streamlined the handoff between our design and development team, because our frontend developers already know what's in Figma will match Tailwind's output.
UI Kits
There's a handful of nice UI kits on the market that can speed things up. Tailwind UI and Tailwind UI Kit are the two that we've investigated.
We have an in-house designer (hi Patryk!), but even still, these libraries save a ton of time.
We'll often bump into a feature that needs to be built which is really challenging. Calendars seem to have come up a lot in the applications we've been developing. Being able to quickly pull down a tricky component and make some tweaks is a blessing.
The bad & ugly of Tailwind
Tailwind CSS isn't perfect. And while our small team of frontend developers have adopted it with great success, we're aware that it does some things... not super well.
Ugly markup
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>
Learning curve
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.
Animation difficulties
Tailwind is great for making simple animations, but if you want to create more complex ones with movements and actions it can be tough.
Even though there are some built-in options that allow for this kind of thing, they're not always enough--especially since these libraries don't provide all the necessary tools needed in order achieve what we need (think about how many class names would have been required).
When we've been met with this situation recently we've opted to use vanilla CSS in combination with an animation library like GSAP.
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! If you liked this article, check out Clean Commit blog for more
Frequently Asked Questions
Whenever we explain to new clients that we use Tailwind, they usually throw a handful of questions back at us. Here are the questions we get asked most frequently.
Is Tailwind CSS better than Bootstrap?
We may be biased because we've pushed Tailwind as standard practice, but we would strongly argue that Tailwind CSS is better than Bootstrap.
Bootstrap is now an "old" technology. It was made by Twitter in mid-2010. Just because something is old doesn't mean it's not great, but Bootstrap, in our opinion, is a heavily overused framework and feels a bit clunky. Tailwind, on the other hand, offers a way to build customised designs with a standardised approach, meaning your new shiny application doesn't look the same as everything that's on the market.
Despite the markup looking a bit busy, Tailwind is a nicer and more efficient CSS framework than Bootstrap. Unlike Bootstrap, Tailwind offers a set of utility classes that let you work with what you need.
Is Tailwind CSS a framework?
It sure is. The official Tailwind CSS website even describes it as a "utility-first CSS framework".
What is Tailwind CSS used for?
Tailwind is used to style user interfaces quickly and more efficiently than traditional CSS. It provides utility classes for controlling the variables that define the look and feel of a user interface, like padding, margin, colour, shadows and font.