This is a 2 part series where I talk about the two main tech I used to build my new website, samanthaming.com. The first one I talked about my experience using VuePress. In this one, I'll talk about Tailwind CSS:
- What I was using before
- Why did I switch from Bulma to Tailwind
- Benefits of Tailwind
- Challenges of Tailwind
- Was it worth the switch
What I was using before?
Previously, I was using a CSS framework called Bulma. I wanted to pick a framework that was as close to the final design as possible. Why? Because it means less customization from me and less work π Remember, I'm a lazy programmer π
Why didn't I pick bootstrap or foundation, you may ask. Those two are super popular frameworks, so if I were to use it, I would probably end up doing a lot of customization to make my site look different. Which meant work and that's a hard pass from me. So Bulma it is!
My old site essentially was a rip off of Bulma π. I believe I kept everything as is, the only thing I tweaked was the color palette. I love using a CSS framework. I'm not a designer, so I rather not waste time spinning out my own design system. Being able to apply a few classes and have it look beautiful, oh ya, CSS framework is the way for me!
Why did I switch from Bulma to Tailwind
For my new project, I decided to use Tailwind, which is a utility-first CSS framework. The philosophy is quite different from your standard CSS framework like Bulma or Bootstrap. So let me spend a bit of time explaining the difference.
Let's say you would like to buy a "table" for your home. You could purchase ready-made and ready-built table from your local shop. Of course, you can still customize it by painting over it. But the table is pretty much set, the amount of changes you could do to it is going to be limited. And that's pretty much what you get with a CSS framework π¦
But you could also make your own table by getting your own supplies from Home Depot. They offer you all the tools and materials to make a custom version from your pure imagination π΅. And this is the experience of using Tailwind. It provides you all the utility to build your own component.
For my new site this time, I actually came up with a mock up. I wanted to create something from scratch. And honestly, my proficiency with CSS has improved since building my old site, so I didn't want to be boxed in by any CSS framework. Your next question might be, okay we get it, you don't want to use a CSS framework, why not just use pure CSS π€ Great question, read on! π
Utility-First vs CSS
One can argue that Tailwind is just a class wrapper of CSS properties. And honestly, they won't be wrong. Let's take a look:
<a class="text-blue hover:text-red">Link</a>
It reads exactly how it will be styled. Make the text blue
and when it's hovered, turn the text red
.
Conversely, if I was writing this with pure CSS. I'd probably do this:
<a class="primary-link">Link</a>
And then I'll apply the CSS.
.primary-link {
color: blue;
}
.primary-link:hover {
color: red;
}
Right off the bat, less code! All I have to do is add the appropriate class and voila, it's styled right there π It's like doing inline styling but way cleaner. And that's kind of the philosophy of utility-first. Here's how Tailwind explains it:
Tailwind provides low-level utility classes that let you build completely custom designs without ever leaving your HTML
Yes to not leaving your HTML π€©
Benefits of Tailwind
Let's look at some of my favorite thing about Tailwind. It's not strictly just Tailwind, but the benefits of why the utility-first concept is so awesome!
No More Naming Problems
One thing I hate about styling is coming up with names. Should I name it primary-link
or primary
or do I follow BEM and do something like primary__link
. Needless to say, naming things are complicated π
If you use Tailwind that goes out the door. I can add the styling right inside the HTML tag. It's like styling inline. It doesn't pollute other similar tags and it's scoped to the specific tag.
<a class="text-red">red color link</a>
<a>default color link</a>
No Over-bloating of CSS files
Here's a sample of my old site's SCSS file structure based on segmenting your styles into components:
- bulma.scss
- general.scss
- blog.scss
- tidbit.scss
- pagination.scss
- banner.scss
- footer.scss
- header.scss
This is considered tiny. Imagine working at a company where the code base is huge, there's even a bigger break down of individual SCSS components. A "simple" color change involves finding the HTML file, then looking for the respective CSS file, then making the adjustment there, and praying it's properly scoped so you don't accidently make a change that pollutes other components. The stress, am I right π©
Here's my new SCSS file structure:
- tailwind.scss
- general.scss
That's it! I no longer have to break my styles into different components. Cause all my style is applied inline. I rarely touch the CSS anymore. I just have to adjust my HTML file πͺ
Typically as your app grows, with more feature being added, your CSS file will inevitably grow in size. However, if you use Tailwind, it will remains relatively the same. Because all subsequent style changes is just a simple addition of applying a utility class. No more introducing new CSS means small CSS file size which translates to a speedy page load time, oh yay π
Speed
Please call me the flash! The ability to add styling has never been faster. Let's do a scenario comparison:
Your company sells blue boxes. So your manager asks you to create a blue box.
Tailwind way
<div class="border border-blue">
blue box
</div>
/* No CSS Change */
CSS way
<div class="product">
blue box
</div>
.product {
border: 1px solid blue;
}
A few months down the road, your R&D department said they can now create red boxes. So please add the new product to our inventory.
Tailwind way
<div class="border border-blue">
blue box
</div>
<div class="border border-red">
red box
</div>
/* No CSS Change */
CSS way
<div class="new-product">
red box
</div>
.product {
border: 1px solid blue;
}
.new-product {
border: 1px solid red;
}
And this can keep going ...Hopefully I painted a picture why a utility-first method first is such a game-changer. The speed is no match. It easily adapts with growing changes in your app without introducing new CSS. Fast to make to changes, fast to implement, no more digging into your CSS files π¨
Pseudo Classes & Responsivness
So I mentioned how Tailwind is similar to inline styling. Where you apply style without leaving your HTML and it's scoped to the specific tag. One thing that inline styling can't do is handling of pseudo classes. But Tailwind can!
<a class="hover:underline">link</a>
βοΈ See how easy it is to read. When the link is hovered, underline the text.
And the responsivness is fire too. See if you can decipher this:
<h1 class="text-xs sm:text-sm md:text-base lg:text-lg">Title</h1>
The text is increasing in size as you move to bigger screen sizes. How easy is that! You don't have to deal with media points. And what a breeze to implement. I love this feature!
Challenges of Tailwind
As revolutionary Tailwind is, there is definitely some challenges. I don't think it's any problem with Tailwind but more the underlying concept of a utility-first framework. So that's what I'm going to speak about instead.
Repeating CSS
One of the biggest annoyance of utility-first is the repeated classes.
<h1 class="bold text-2x text-blue">Tibit Title</h1>
<h1 class="bold text-2x text-red">Blog Title</h1>
<h1 class="bold text-2x text-green">Vidbit Title</h1>
However, in regular CSS. I'd just create a class to capture the similarities.
<h1 class="heading text-blue">Tibit Title</h1>
<h1 class="heading text-red">Blog Title</h1>
<h1 class="heading text-green">Vidbit Title</h1>
.heading {
font-weight: bold;
font-size: 2em;
}
And of course I can still do that in Tailwind. But that kind of defeats the purpose of using a utility-first concept. I want to minimize any introduction of CSS to my project at all.
But honestly, this is not a big deal for me. Because I'm using VuePress. Anything I feel like it's being repeated, I just create a vue component.
<CustomVueTitleComponent color="blue">
<CustomVueTitleComponent color="red">
<CustomVueTitleComponent color="green">
<!-- CustomVueTitleComponent.vue -->
<template>
<h1 class="bold text-2x" :class="`text-${color}`"></h1>
</template>
Readability
This is probably the biggest downfall of a utility-first concept. Adding a few classes is fine. But when you're adding tons of CSS classes, the readability can definitely be challenging π
<div
class="text-blue mr-3 ml-4 mt-4 mb-2 border border-blue px-2 sm:px-3 md:px-10 lg:px-0 xl:pl-10 w-full border lg:w-10-12 xl:w-8/12"
></div>
βοΈDid you catch my duplicate? Accidently adding duplicate class happened to me a lot. Of course, nothing will be broken, I will still have the style I desire. But things like that can happen when readability is poor. You might end up adding duplicate classes and debugging can be challenging. I don't have a great solution for this besides having some linter to catch the duplicates. Definitely something to consider.
Was it worth the switch from Bulma to Tailwind
Yes! I love using Tailwind. I love the utility-first philosophy. But just like minimalism, it's not suitable for everyone. If you have your own design system, then go for it. But if you don't, and you want something that looks great right out of the box, then stick with a tradition CSS framework like Bootstrap.
It worked for my own personal project because I had a design in mind. But even for larger companies, I think it's a huge benefit for adopting this. That's actually how I got introduced to this. My current role at GitLab, we're all about that utility-first. We have a significant code base, so not having to dig into the CSS and make all the changes in the HTML is such a plus. Here's how GitLab puts it:
Utility Class removes code duplication and encapsulates a clear responsibility
Hope you enjoy this summary of my experience and feedback on using Tailwind βοΈ
Top comments (13)
Great Read ! You mention "Repeating CSS" and " ... One of the biggest annoyance of utility-first is the repeated classes ... ". That got me thinking, have you tried using the @apply feature from tailwind ?
tailwindcss.com/docs/extracting-co...
Haven't tried tailwind myself yet, but once I read the docs, I really liked the @apply feature and I can't wait to try it :)
I think you could do
like "grouping" talwind classes
Thanks for reading my article and the positive feedback Pascal π
Unfortunately
@apply
didn't work for me. I'm using stylus with VuePress. Something about the syntax that's not working π But I have used theirtheme()
function and it works perfectly πI'm terrible at naming things, it's one of the reasons I love about Tailwind -- No more class or id names. Instead, I just apply the style directly...and with that comes the benefits of speed and moving very quickly without thinking of class names π
Can't wait until you give Tailwind a try! I'm a huge fan π
@samanthaming , does the
@apply
statement work if you try specifying the language with the "lang" attribute? I've never tried multiple style blocks in a vue component, so I'm interested to know if this works:I am wondering if the theme () option is helpful when trying to create a darkmode/lightmode feature for a webapp π€π€
Thank you for this interesting article, i love Tailwind ! Do you use PurgeCSS? If yes, I think you should modify this part of your code :
To :
tailwindcss.com/docs/controlling-f...
WOOOO, thanks for introducing me to PurgeCSS π€© I'm using VuePress, which uses PostCSS ... but I wonder if it's redundant to have both? -- but they do different things, so maybe I should include it π€
Awesome intro to Tailwind.
It's not for everyone, but like you said, if somebody's willing to put in a bit of work to figure out what all the classes mean, and they want to style their site/app from scratch using little more than their own imagination, there's really no easier/better way.
I'll definitely recommend this article to anybody that has to put up with my use of Tailwind, since I couldn't make a better argument for it myself.
Tailwind makes a daunting task a lot more approachable, and it's probably helped me write more maintainable /less redundant styles (since it's literally right there in the class names what they do, and there's less digging through a bunch of external Sass to find the custom class I needed to use), though I don't think I'd be able to do everything with Tailwind alone. But it's a super helpful tool, regardless.
I use the Tailwind Intellisense and Headwind Class Sorter VS Code extensions (along with a comprehensive Stylelint config) so the styles basically write themselves these days.
Interesting read. I've used Bulma earlier on small hobby-projects and enjoyed it a lot. Never used Tailwind, but I read through much of the documentation and I liked the concept. Quite a different approach compared to bootstrap and bulma. I really want to try it out once and see if I'm able to at least make something half decent with it (bulma/bootstrap makes it quite easy to make good looking sites imo, but all my sites/projects tend to resemble each other... Probably more a failing on my part than the frameworks though)
Yup, a totally different approach from the standard CSS frameworks. If you have a design in mind, then Tailwind would be a good choice. But sometimes the cookie-cutter approach you get from CSS frameworks is might be what you need. So it really depends on the project. I say give Tailwind a try, and that way you will know which approach is best in which scenario π
Love the difference explanation :) Now I will definitely try it :)
This should be a good idea to start learning any new framework as we always think how should we start.
Awesome post and I loved your site! Thanks for sharing!
Thanks David for the positive feedback! It's now a lot easier to add more features to it too! Can't wait to continue building on it π