DEV Community

Cover image for Building my site with Tailwind CSS
Samantha Ming
Samantha Ming

Posted on • Originally published at samanthaming.com

Building my site with Tailwind CSS

Alt Text

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

And then I'll apply the CSS.

.primary-link {
  color: blue;
}

.primary-link:hover {
  color: red;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode
/* No CSS Change */
Enter fullscreen mode Exit fullscreen mode

CSS way

<div class="product">
  blue box
</div>
Enter fullscreen mode Exit fullscreen mode
.product {
  border: 1px solid blue;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode
/* No CSS Change */
Enter fullscreen mode Exit fullscreen mode

CSS way

<div class="new-product">
  red box
</div>
Enter fullscreen mode Exit fullscreen mode
.product {
  border: 1px solid blue;
}
.new-product {
  border: 1px solid red;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

☝️ 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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode
.heading {
  font-weight: bold;
  font-size: 2em;
}
Enter fullscreen mode Exit fullscreen mode

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">
Enter fullscreen mode Exit fullscreen mode
<!-- CustomVueTitleComponent.vue -->

<template>
  <h1 class="bold text-2x" :class="`text-${color}`"></h1>
</template>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

☝️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 ✌️

Resources

Top comments (13)

Collapse
 
turbopasi profile image
Pascal Lamers • Edited

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

<h1 class="blue-heading">Tibit Title</h1>

.blue-heading {
   @apply bold text-2x text-blue
}

like "grouping" talwind classes

Collapse
 
samanthaming profile image
Samantha Ming

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 their theme() function and it works perfectly πŸ‘

h1 {
  font-weight: theme('fontWeight.semibold')
}

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 πŸ‘

Collapse
 
richardeschloss profile image
Richard Schloss • Edited

@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:

<style lang="css" scoped>
/* Your tailwind css here */
/* Does @apply work here? */
</style>

<style lang="stylus" scoped>
/* Your stylus here (that you already have) */
</style>
Collapse
 
turbopasi profile image
Pascal Lamers • Edited

I am wondering if the theme () option is helpful when trying to create a darkmode/lightmode feature for a webapp πŸ€”πŸ€”

Collapse
 
jeremyrobert profile image
JΓ©rΓ©my ROBERT

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 :

<CustomVueTitleComponent color="blue">
<CustomVueTitleComponent color="red">
<CustomVueTitleComponent color="green">

<!-- CustomVueTitleComponent.vue -->

<template>
  <h1 class="bold text-2x" :class="`text-${color}`"></h1>
</template>

To :

<CustomVueTitleComponent color="text-blue">
<CustomVueTitleComponent color="text-red">
<CustomVueTitleComponent color="text-green">

<!-- CustomVueTitleComponent.vue -->

<template>
  <h1 class="bold text-2x" :class="color"></h1>
</template>

tailwindcss.com/docs/controlling-f...

Collapse
 
samanthaming profile image
Samantha Ming

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 πŸ€”

Collapse
 
mtpiercey profile image
Matthew Piercey

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.

Collapse
 
jherseth profile image
JHerseth

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)

Collapse
 
samanthaming profile image
Samantha Ming

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 😊

Collapse
 
ivanesko69 profile image
Ivo

Love the difference explanation :) Now I will definitely try it :)

Collapse
 
miteshkamat27 profile image
Mitesh Kamat

This should be a good idea to start learning any new framework as we always think how should we start.

Collapse
 
sanchezdav profile image
David Sanchez

Awesome post and I loved your site! Thanks for sharing!

Collapse
 
samanthaming profile image
Samantha Ming

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 πŸ˜†