Give some style with Tailwind

Give some style with Tailwind

·

4 min read

Updated version for Laravel 10 / Twill 3 on Apr 14, 2023

Installation and configuration

For these steps, we will mainly follow the official documentation.

Dependencies installation

# Tailwind and its dependencies: PostCSS, Autoprefixer
yarn add tailwindcss postcss autoprefixer --dev

Configuration files generation

Let's generate tailwind.config.js and postcss.config.js files in our project root folder with the default configuration. That can be done manually or with the following command:

npx tailwindcss init -p

PostCSS configuration

Here we keep the default configuration.

/postcss.config.js

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

Tailwind Configuration

From the default configuration, we add the paths (relative to the project root) to all of our files that can contain Tailwind class names (Blade templates, Vue components, ...)

/tailwind.config.js

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './resources/**/*.blade.php',
    './resources/**/*.vue',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Integration in our application

  • Create a CSS file with Tailwind directives

  • Import it into our application

  • Use it in our root view

We can use the default /resources/css/app.css that comes with Laravel (or feel free to do as you want) and we add the standard Tailwind directives.

/resources/css/app.css

@tailwind base;
@tailwind components;
@tailwind utilities;

Then we import it into our TypeScript application file.

/resources/js/app.ts

import { createApp, h, type DefineComponent } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'

import '../css/app.css'

createInertiaApp({
...

Time to play

Just to see if it works

To do so, we will use a simple component taken from Tailwind UI, and we replace the template part of our Index Page with this:

/resources/js/Pages/Index.vue

<template>
  <div class="bg-white">
    <div class="relative isolate px-6 pt-14 lg:px-8">
      <div class="mx-auto max-w-2xl py-32 sm:py-48 lg:py-56">
        <div class="text-center">
          <h1 class="text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl">Data to enrich your online business</h1>
          <p class="mt-6 text-lg leading-8 text-gray-600">Anim aute id magna aliqua ad ad non deserunt sunt. Qui irure qui lorem cupidatat commodo. Elit sunt amet fugiat veniam occaecat fugiat aliqua.</p>
          <div class="mt-10 flex items-center justify-center gap-x-6">
            <a href="#" class="rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Get started</a>
            <a href="#" class="text-sm font-semibold leading-6 text-gray-900">Learn more <span aria-hidden="true"></span></a>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

If Vite is started you just have to save and have a look at your browser to see

Why not add some logic to play around

At this time we have a static Vue application, maybe we could use some data from our Laravel Controller and play with CSS classes.

In our Laravel Controller, we will compute a darkMode random boolean that we will use on our Page.

The Inertia render function takes a second parameter which is an associative array that will be passed as Vue props in the Page.

/app/Http/Controllers/IndexController.php

<?php

namespace App\Http\Controllers;

use Inertia\Inertia;
use Inertia\Response as InertiaResponse;

class IndexController extends Controller
{
    public function __invoke(): InertiaResponse
    {
        return Inertia::render('Index', [
            'darkMode' => (bool)random_int(0, 1),
        ]);
    }
}

And now on our Page, we register our darkMode prop (as a Boolean) in our component props and use it in the first div of the template to alternatively set its class to bg-gray-600 or bg-white.

/resources/views/Pages/Index.vue

<script setup lang="ts">
interface Props {
  darkMode: boolean
}

const props = defineProps<Props>()
</script>

<template>
  <div :class="darkMode ? 'bg-gray-600' : 'bg-white'">
    <div class="relative isolate px-6 pt-14 lg:px-8">
      <div class="mx-auto max-w-2xl py-32 sm:py-48 lg:py-56">
        <div class="text-center">
          <h1 class="text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl">Data to enrich your online business</h1>
          <p class="mt-6 text-lg leading-8 text-gray-600">Anim aute id magna aliqua ad ad non deserunt sunt. Qui irure qui lorem cupidatat commodo. Elit sunt amet fugiat veniam occaecat fugiat aliqua.</p>
          <div class="mt-10 flex items-center justify-center gap-x-6">
            <a href="#" class="rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Get started</a>
            <a href="#" class="text-sm font-semibold leading-6 text-gray-900">Learn more <span aria-hidden="true"></span></a>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

If we go back to our browser, we can now either see this

or this


All is now set to build the front-end of our application, in the next article we will prepare the back-end


We'll do our best to provide source code of the serie on GitHub