Support the ongoing development of Laravel.io →

Setting Up Tailwind CSS in Laravel

31 Aug, 2021 11 min read

Photo by Pankaj Patel on Unsplash

Introduction

Tailwind CSS is a really cool CSS framework that you can use when building your applications and websites. In fact, I think it's that cool that since it's release, I've switched away from using Bootstrap as my go-to framework for new projects and use Tailwind instead.

In this article, we're going to take a quick look at what Tailwind CSS is and why I think it's useful. We're then going to step through two different ways of how to set up Tailwind in your Laravel projects.

What is Tailwind CSS?

Tailwind is a utility-first CSS framework that you can use to style your website directly in your HTML. As an example, it provides you with CSS classes such as flex, pt-4, text-center so that you can have granular control.

To give an example, let's look at how you might make a button using Tailwind:

<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Button
</button>

If we wanted to make this same style button using Bootstrap, we'd probably do something like this:

<button class="btn btn-primary">
  Button
</button>

As you can see, we're adding individual CSS classes to the markup, rather than having one or two classes like you would in Bootstrap.

Now, don't worry, I know what you're thinking... "That HTML looks really messy and overcomplicated. The Bootstrap version looks so much better and easier to understand!". I thought the same thing when I first started using Tailwind. I just thought that it was a bit of a fad that would probably die down after a few months. But, I gave it a try anyway so that I could make a more informed decision. I loved it!

Of course, it felt a little bit weird at first, but after an hour or two it felt really natural to use. When I was using Bootstrap, I always felt like I was fighting the built-in CSS styles to get anything done. It was great for throwing together sites really quickly, but to tailor them to my own liking, I had to override a lot of styles. But with Tailwind, if I wanted to quickly add a style to a button, it was as easy as adding it straight to the HTML.

If you're interested in reading more about why Tailwind is useful, Adam Wathan (the creator of Tailwind) has a really interesting article about it that I'd recommend reading.

Using the CDN

The easiest (but not necessarily the best) way to get started with Tailwind is to add the stylesheet to your HTML using the CDN. This is particularly useful if you want to quickly prototype an idea or just have a play around with the framework.

To get started, you just need to add the following line to into the <head> section of your HTML:

<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">

Although this is the quickest way to add Tailwind to your project, I'd probably advise against it for any live projects, because:

The size of the CSS file is larger than it would be if bundled after installing via NPM.

  • You can't customize Tailwind's default theme.
  • You can't use any directives like @apply, @variants, etc.
  • You can't enable additional variants like group-focus.
  • You can't install third-party plugins.
  • You can't tree-shake unused styles.

Using NPM

If you're intending on using Tailwind in a project that's going to be live, it's much better to install it using NPM. By doing this, you aren't affected by the downsides that I stated above like when using the CDN. So, let's take a look at how to get started:

Installing Tailwind

To install Tailwind, you'll just need to run the following command:

npm install -D tailwindcss@latest postcss@latest autoprefixer@latest

Setting up Your Tailwind Config

Now that we have Tailwind installed, we can run the following command to create a blank tailwind.config.js file:

npx tailwindcss init

You should now have a tailwind.config.js that looks like this:

module.exports = {
  purge: [],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

This is the file that you might use when you need to make changes to your theme or install plugins. As an example, if we wanted to define 'Poppins' as our default 'sans' font, we could update the file like so:

module.exports = {
  purge: [],
  darkMode: false, // or 'media' or 'class'
  theme: {
    fontFamily: {
      'sans': ['Poppins', 'ui-sans-serif', 'system-ui'],
    },
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

Configuring Laravel Mix

Now that we have Tailwind installed and configured ready to go, we can set up Laravel Mix so that our CSS is bundled whenever we build our assets.

I'm going to make the assumption here that you're using the default app.css file here that comes with a fresh Laravel installation. But if not, you can update the first parameter in the postCss() method to match your main CSS file path.

I'm also going to make the assumption that your webpack.mix.js file still looks the same as the one that comes in the fresh default Laravel installation.

Let's add the necessary require() method to our postCss() method in the webpack.mix.js file like so:

const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
    .postCss("resources/css/app.css", "public/css", [
        require("tailwindcss"),
    ]);

Adding Tailwind to Your Application's CSS

We're almost there! Now that we've installed and configured Tailwind, we need to add the styles to our main CSS file.

I'm going to make the assumption here that we're using the resources/css/app.css CSS file mentioned above. All we need to do is open up the file and add the following to the top:

@tailwind base
@tailwind components
@tailwind utilities

Tailwind should now be added to your project's CSS file and you should be able to start using it right away. You'll also need to remember to add it to the top of your HTML:

<!doctype html>
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>

Congratulations, you've now got Tailwind installed ready to use in your project!

Purging Unused CSS Classes

I'd recommend configuring Tailwind to purge unused CSS classes from your application's CSS file.

As a really basic example, let's imagine that you're only using the text-blue-500 class in your application. It wouldn't make sense for us to include all of the other classes that Tailwind provides in our application's CSS. If we included all of the unused classes, we would be increasing the size of our CSS file which can have a negative effect on search rankings in Google.

So, to purge any unused CSS classes, we can update our tailwind.config.js file to look similar to the following:

 module.exports = {
   purge: [
     './resources/**/*.blade.php',
     './resources/**/*.js',
     './resources/**/*.vue',
   ],
    darkMode: false, // or 'media' or 'class'
    theme: {
      extend: {},
    },
    variants: {
      extend: {},
    },
    plugins: [],
  }

As you can see, we've added three new lines to the purge section of the file. These lines allow us to preserve any CSS classes that are found in any files inside our resources folder that end with .blade.php, .js or .vue.

But, it's really important to make sure that you write your styles in your markup in a way that can be preserved. Let's take a look at the example that the Tailwind documentation gives of how NOT to write your classes.

Because of the way that the regex rule works that is used to detect the CSS classes, it will detect strings that aren't separated by spaces, quotes or angle brackets. This means that if you have any of these in your classes (for example, if you were adding conditional classes), they might get ignored and purged.

For example, let's say that in a Vue.js file, you were adding conditional CSS classes. If there's an error, you want to add the text-red-600 class, but if there's no error, you want to add text-green-600. You could potentially write it like so:

<div class="text-{{  error  ?  'red'  :  'green'  }}-600"></div>

However, this would detect text-{{, error, ?, red, :, green, }}-600. As you can probably guess, this means that because it didn't detect text-red-600 or text-green-600, the classes you need would be purged from your CSS (assuming that they aren't included elsewhere in your markup somewhere).

Instead, to write the classes in a way that can be detected and not purged, you would write the conditional like so:

<div class="{{  error  ?  'text-red-600'  :  'text-green-600'  }}"></div>

To learn more about this, I'd recommend giving the official Tailwind documentation's section about writing purgeable HTML a read.

Splitting HTML into Components

As your application grows, you'll likely find that you'll be reusing common parts of your markup in a lot of different places. So, in a similar way that you'd tend to try and keep your code DRY (don't repeat yourself), you can do the same in Laravel with your views.

In this particular section, we'll be using Blade components as examples, but the concept can still be applied if you're building your frontend using something like Vue.

So, to get a bit of context, let's imagine that we have a button that we use in many places across our frontend that has the following markup:

<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Button
</button>

Now, let's say that a few months after releasing the original website, we want to update all of the buttons to be green rather than blue. Of course, we could do a 'find and replace' across all of our Blade files. But, as you can probably guess, that would be cumbersome and would leave room for error. What would happen if you forgot to change one of them? Or if you accidentally changed another element that was using the bg-blue-500 class but that wasn't meant to be updated?

To get around this, we can make use of Laravel components. Components allow us to create reusable elements that we can use in our Blade files.

To get a better idea of what they are and how to use them, let's imagine the following HTML:

<div>
  <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
    Button One
  </button>

  <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
    Button Two
  </button>
</div>

We're going to take these two buttons and split them into components that we can use instead. Let's start by creating our component by making a new resources/views/components/button.blade.php file.

We can then move the button's HTML into our new button.blade.php file like so:

<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Button One
</button>

But, we'll need to make sure that we make the button text dynamic so that we can reuse this component across our system. We can do that by outputting a $text attribute that we'll be passing to the component. Our new button markup would then look like this:

<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  {{ $text }}
</button>

Now we can update our original HTML with the two buttons to use our new components rather than the button's duplicated markup:

<div>
  <x-button text="Button One"/>
  
  <x-button text="Button Two"/>
</div>

This now means that if we want to update the colours of our buttons from blue to green, all we'll need to do is change it once in our resources/views/components/button.blade.php file.

You might find that in one part of your frontend that you'd like to keep the general look of the button but change something (the font size as an example). Instead of needing to create a new component or manually create the button without a component, we can make our component's CSS classes dynamic.

To do this, we can update our component like so:

<button {{ $attributes->merge(['class' => 'bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded']) }}">
  {{ $text }}
</button>

We could then call our component:

  <x-button text="Button One" class="text-xl"/>

This would result in the following HTML being output:

<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded text-xl">
  Button One
</button>

To find out more about components in Laravel, I'd definitely recommend giving the official documentation a read. It shows the different types of things that you can do with components and gives some really useful examples.

Conclusion

Hopefully, this article should have given you an overview of how you can set up Tailwind CSS for your Laravel applications and websites. It should have also shown you how to set up Laravel Mix to purge any unused CSS and then briefly showed you how to split your reusable HTML into components.

Keep on building awesome stuff! 🚀

Last updated 3 weeks ago.

ravindrana, hamza094 liked this article

2
Like this article? Let the author know and give them a clap!
ash-jc-allen (Ash Allen) I'm a freelance Laravel web developer from Preston, UK. I maintain the Ash Allen Design blog and get to work on loads of cool and exciting projects 🚀

Other articles you might like

November 18th 2024

Laravel Custom Query Builders Over Scopes

Hello 👋 Alright, let's talk about Query Scopes. They're awesome, they make queries much easier to r...

Read article
November 19th 2024

Access Laravel before and after running Pest tests

How to access the Laravel ecosystem by simulating the beforeAll and afterAll methods in a Pest test....

Read article
November 11th 2024

🍣 Sushi — Your Eloquent model driver for other data sources

In Laravel projects, we usually store data in databases, create tables, and run migrations. But not...

Read article

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.