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 tosim/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 thesim
folder: - Add the
home
URL tosim/urls.py
:
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
]
- Include the
sim
URLs atcore/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 thesim
app - Create a
home.html
file in thetemplates
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.
Install Tailwind CSS
We'll use the Tailwind CSS Standalone CLI to integrate Tailwind CSS into a Django project.
- 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.
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 thesim
app: - Create a
css
directory in thestatic
directory: - Create an
input.css
file in thecss
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.
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:
- Install Tailwind CSS Standalone CLI
- Add Tailwind CSS to your Django templates
- 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 .