The simplest way to add Tailwind CSS to Django πŸ’¨

Updated: Wed 28 February 2024

I'll show you a simple and robust way to integrate Tailwind CSS into your Django templates. We'll use the Tailwind CSS Standalone CLI to do this. πŸ‘¨β€πŸ”§

You could add Tailwind using a CDN. We won't do this: although the CDN is faster to add, it's less suitable for production.

The final product of our Django template, styled with Tailwind CSS, will look like this:

I've made an optional video guide (featuring me πŸ‡πŸΏ) here that follows the steps in this guide:

Q. What does it mean to add Tailwind CSS to a Django project?

Answer: Tailwind CSS is essentially a language on top of CSS. You can write CSS in Tailwind code. We then convert this Tailwind code into pure CSS for the browser to use.

To write Tailwind code in development, we need to convert it into pure CSS. We add a watcher that will a) watch your files and then b) convert the Tailwind CSS that you write into pure CSS whenever you make changes in development.

This means that you will write Tailwind code in development. But the server (whether in development or production) only ever serves pure CSS. We build this pure CSS from the Tailwind CSS during in development. So, in this way, Tailwind CSS is a tool for writing faster CSS in development.

Q. Why would I use Tailwind CSS in a Django project?

Many people prefer to write Tailwind CSS rather than pure CSS. It's a matter of preference. Tailwind CSS syntax is shorter, and you insert its classes directly into your HTML.

Setup your Django app

Install Django and create a project and app:

pip install django
django-admin startproject core .
python manage.py startapp sim
  • Add sim to INSTALLED_APPS in core/settings.py:
INSTALLED_APPS = [
    ... # Other apps
    'sim',
]

Render your Django page with some unstyled images

  • Add the home view to sim/views.py:
from django.shortcuts import render


def home(request):
    photo_data = {
        'photo_1': 'https://picsum.photos/seed/1/300/200',
        'photo_2': 'https://picsum.photos/seed/2/300/400',
        'photo_3': 'https://picsum.photos/seed/3/300/300',
        'photo_4': 'https://picsum.photos/seed/4/300/300',
        'photo_5': 'https://picsum.photos/seed/5/300/300',
        'photo_6': 'https://picsum.photos/seed/6/300/300',
        'photo_7': 'https://picsum.photos/seed/7/300/400',
        'photo_8': 'https://picsum.photos/seed/8/300/300',
        'photo_9': 'https://picsum.photos/seed/9/300/200',
        'photo_10': 'https://picsum.photos/seed/10/300/100',
        'photo_11': 'https://picsum.photos/seed/11/300/400',
        'photo_12': 'https://picsum.photos/seed/12/300/400',
    }
    return render(request, 'home.html', photo_data)
  • Create a urls.py file in the sim folder:
  • Add the home URL to sim/urls.py:

from django.urls import path

from . import views

urlpatterns = [
    path('', views.home, name='home'),
]
  • Include the sim URLs at core/urls.py :
from django.contrib import admin
from django.urls import include, path


urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('sim.urls')),
]
  • Create a templates directory in the sim app
  • Create a home.html file in the templates directory:
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Photo Grid with Tailwind CSS</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'css/output.css' %}" type="text/css"> <!-- We add the output Tailwind CSS here -->
</head>
<body class="h-screen flex justify-center items-center">

<div class="w-3/5 m-auto">
    <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
        <div class="grid gap-4">
            <div>
                <img class="h-auto max-w-full rounded-lg shadow shadow-lg" src="{{ photo_1 }}" alt="">
            </div>
            <div>
                <img class="h-auto max-w-full rounded-lg shadow" src="{{ photo_2 }}" alt="">
            </div>
            <div>
                <img class="h-auto max-w-full rounded-lg shadow" src="{{ photo_3 }}" alt="">
            </div>
        </div>
        <div class="grid gap-4">
            <div>
                <img class="h-auto max-w-full rounded-lg shadow" src="{{ photo_4 }}" alt="">
            </div>
            <div>
                <img class="h-auto max-w-full rounded-lg shadow" src="{{ photo_5 }}" alt="">
            </div>
            <div>
                <img class="h-auto max-w-full rounded-lg shadow" src="{{ photo_6 }}" alt="">
            </div>
        </div>
        <div class="grid gap-4">
            <div>
                <img class="h-auto max-w-full rounded-lg shadow" src="{{ photo_7 }}" alt="">
            </div>
            <div>
                <img class="h-auto max-w-full rounded-lg shadow" src="{{ photo_8 }}" alt="">
            </div>
            <div>
                <img class="h-auto max-w-full rounded-lg shadow" src="{{ photo_9 }}" alt="">
            </div>
        </div>
        <div class="grid gap-4">
            <div>
                <img class="h-auto max-w-full rounded-lg shadow" src="{{ photo_10 }}" alt="">
            </div>
            <div>
                <img class="h-auto max-w-full rounded-lg shadow" src="{{ photo_11 }}" alt="">
            </div>
            <div>
                <img class="h-auto max-w-full rounded-lg shadow" src="{{ photo_12 }}" alt="">
            </div>
        </div>
    </div>
</div>

</body>
</html>

  • Run the server:
python manage.py runserver

You should see some unstyled images. We'll now use Tailwind CSS to style them.

img_1.png

Install Tailwind CSS

We'll use the Tailwind CSS Standalone CLI to integrate Tailwind CSS into a Django project.

  1. Download the Tailwind CSS Standalone CLI

Visit Tailwind CSS Github releases > 'Assets' > Find the name of the file for your operating system.

I'm using an M1 Mac, so I'll use the tailwindcss-macos-arm64 file. img.png

Download the file using curl into your project directory, adding the file name to the end of the URL:

curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/<the_file_name_for_your_os>

For me on MacOS, that's:

curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-macos-arm64

Rename it (for convenience):

mv tailwindcss-macos-arm64 tailwindcss

Make it executable:

chmod +x tailwindcss

You've now installed the Tailwind CSS Standalone CLI.

Add Tailwind CSS

Create a Tailwind CSS configuration file

  • Create a tailwind.config.js file
./tailwindcss init

You should see:Created Tailwind CSS config file: tailwind.config.js

  • Add the paths to your Django templates in the tailwind.config.js file:
/** @type {import('tailwindcss').Config} */
module.exports = {
    purge: [
        './**/templates/*.html',
    ],
    theme: {
        extend: {},
    },
    plugins: [],
}

Add Tailwind CSS file to your Django project

  • Create a static directory in the sim app:
  • Create a css directory in the static directory:
  • Create an input.css file in the css directory:
@tailwind base;
@tailwind components;
@tailwind utilities;

Start your Tailwind watcher

Q. Why do we need a watcher when running Tailwind CSS in a Django project? A. Tailwind CSS is essentially a wrapper around CSS. You can write CSS in Tailwind code. We then need to convert this Tailwind code into pure CSS. The watcher will watch your Tailwind CSS file and convert it into pure CSS whenever you make changes.

./tailwindcss -i ./sim/static/css/input.css -o ./sim/static/css/output.css --watch

You should see:

Rebuilding...
Done in 13ms.
  • Now make any Tailwind CSS change to your home.html file, and your watcher will automatically rebuild the CSS file to include the changes.

Visit your Django page

python manage.py runserver

The page should now be styled with Tailwind CSS.

img_1.png

Extra: A small mistake that you'll make in the future (which I've made in the past) πŸ•΅οΈ

So, you've loaded your Django project that uses Tailwind CSS.

You'll make a change to one of your Django templates using your Tailwind CSS file and refresh.

Then you'll wonder: why aren't the changes showing up in the browser?

-> This is because you forgot to start the watcher in a separate terminal window.

So, to avoid this mistake, you could:

  • add the watch command to run whenever you run your Django app, or
  • if you're using Pycharm, create a Compound configuration that runs the server and the watcher at the same time (They'll be something similar in other IDEs).

How to run the Tailwind watcher whenever I run my Django app

How would I run the watcher whenever I run my Django app? Answer: Add a simple subprocess to your settings file To avoid forgetting to run the watcher, you could add a subprocess to your settings file that runs the watcher whenever you run your Django app. The subprocess code:
# tailwind_watcher.py
import subprocess

def run_tailwind_watch():
    """
    Runs TailwindCSS in watch mode for automatic recompilation.
    """
    command = [
        './tailwindcss',  # Make sure that this points to your tailwindcss file in your project.
        '-i', './sim/static/css/input.css',  # input
        '-o', './sim/static/css/output.css',  # output
        '--watch'
    ]
    subprocess.run(command)
    print('TailwindCSS watcher started.')

run_tailwind_watch()
And then add this to the end of your `settings.py` file:
# settings.py
from .tailwind_watcher import run_tailwind_watch # You'll need to change this to point to your tailwind_watcher file.

if DEBUG:  # We only need to run the watcher in development (given reasons mentioned in the guide).
    run_tailwind_watch()
Now, whenever you run your Django app, the watcher will also run.

Complete βœ…

Congrats on adding Tailwind CSS to your Django project πŸŽ‰ You've learned how to:

  1. Install Tailwind CSS Standalone CLI
  2. Add Tailwind CSS to your Django templates
  3. Start a watcher to convert your Tailwind CSS into pure CSS

P.S Want to build Django frontend faster?

Probably like you, I want to get my Django frontend out fast as possible (preferably instantly).

So, I'm building Photon Designer. Photon Designer lets me produce Django frontend visually and extremely quickly - like a painter sweeping his brush across the page πŸ–ŒοΈ

If you found this guide helpful, you can see Photon Designer here .

Let's get visual.

Do you want to create beautiful django frontends effortlessly?
Click below to book your spot on our early access mailing list (as well as early adopter prices).