A integração entre Django e Tailwind CSS combina um backend robusto em Python com uma abordagem moderna de estilização baseada em classes utilitárias. Esse encaixe é comum em aplicações web atuais por acelerar o desenvolvimento, manter consistência visual e facilitar a criação de layouts responsivos.
Este artigo apresenta os conceitos essenciais, a criação de um projeto Django, a configuração do Tailwind no fluxo de arquivos estáticos e a construção de uma tela simples de “chat bubble”. Também são incluídas boas práticas de formatação de classes com Prettier e um exemplo de uso de componentes prontos com FlyonUI, mantendo o projeto organizado e fácil de evoluir.
Visão geral do Django
Django é um framework web de código aberto para Python, conhecido pela filosofia “baterias incluídas”, pois traz muitos recursos prontos. Um framework é um conjunto de ferramentas e padrões que acelera o desenvolvimento, evitando repetição de código. Django inclui ORM (mapeamento objeto-relacional) para trabalhar com banco de dados usando objetos Python, além de autenticação e painel administrativo. A separação de responsabilidades também é um ponto forte, pois mantém o projeto mais previsível e sustentável.
O padrão arquitetural do Django costuma ser descrito como MVT (Model-View-Template). Em termos simples, Model representa os dados, View concentra a lógica que prepara a resposta, e Template define a apresentação em HTML. Essa divisão reduz acoplamento e facilita manutenção. Django também oferece proteções padrão contra ataques comuns, como injeção de SQL e falsificação de requisição entre sites.
O que é Tailwind CSS
Tailwind CSS é um framework CSS “utility-first”, ou seja, baseado em classes utilitárias pequenas e reutilizáveis. Em vez de criar muitas regras CSS personalizadas, a estilização é composta diretamente no HTML com classes como espaçamento, cor, tipografia e layout. Esse modelo incentiva consistência, pois o projeto usa uma mesma escala de valores definida pelo Tailwind. A responsividade também se torna mais simples, pois existem variações de classes para tamanhos de tela.
Um ponto central do Tailwind é o processo de compilação, que gera um arquivo CSS final contendo apenas as classes realmente usadas. Para isso, o Tailwind “varre” arquivos de template e código e inclui as classes encontradas. Isso evita CSS inflado e melhora desempenho. Essa geração depende de uma configuração correta do caminho dos templates no arquivo do Tailwind.
Por que Django e Tailwind funcionam bem juntos
Django organiza páginas usando templates HTML e um sistema de arquivos estáticos para CSS e JavaScript. Tailwind se encaixa nesse modelo ao gerar um CSS compilado que pode ser servido como arquivo estático. A combinação permite construir páginas rapidamente, pois o backend fica responsável por regras de negócio e o frontend ganha agilidade na composição visual. O resultado tende a ser um ciclo de desenvolvimento curto e com menos retrabalho de estilo.
Outro benefício é a clareza na separação: Django concentra rotas, lógica e dados, enquanto Tailwind fornece uma linguagem de design consistente. Mesmo sem componentes prontos, o Tailwind possibilita criar interfaces personalizadas com baixa necessidade de CSS manual. Em projetos maiores, a padronização de classes reduz divergência visual e facilita colaboração. O uso de ferramentas de formatação ajuda a manter templates legíveis.
Inicialização de um projeto Django
A criação do projeto começa com a instalação do Django e a geração da estrutura base. A instalação é feita pelo gerenciador de pacotes do Python, o pip. Em seguida, o comando administrativo do Django cria pastas e arquivos essenciais, incluindo o arquivo de configurações. Essa estrutura é a base para configurar templates e arquivos estáticos.
Os comandos a seguir mostram a instalação e a criação do projeto, mantendo o nome do projeto como exemplo. A lista apresenta exatamente o que é necessário para iniciar o diretório e entrar nele.
pip install django
django-admin startproject myproject
cd myproject
Para que templates e arquivos estáticos sejam encontrados de forma simples, é comum criar pastas dedicadas e configurá-las no arquivo settings.py. A configuração TEMPLATES controla onde o Django procura arquivos HTML. A configuração STATICFILES_DIRS define diretórios adicionais onde ficam CSS, JS e imagens. Os trechos abaixo ilustram ajustes típicos, considerando pastas templates e static na raiz do projeto.
# settings.py (trechos relevantes)
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"], # pasta global de templates
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"] # pasta global de arquivos estáticos
Integração do Tailwind CSS no projeto
Tailwind depende do ecossistema Node.js para compilar o CSS final. Node.js é um ambiente de execução de JavaScript fora do navegador, e o npm é seu gerenciador de pacotes. A instalação do Tailwind normalmente ocorre como dependência de desenvolvimento, pois ele é usado para gerar o CSS, não para rodar em produção. Após instalar, um arquivo de configuração é criado para indicar onde estão os templates e quais opções serão usadas.
Os comandos abaixo instalam o Tailwind e criam o arquivo tailwind.config.js. Em seguida, o CSS de entrada é criado com diretivas do Tailwind, que são marcadores que expandem para estilos base, componentes e utilitários. Um caminho comum é manter esse arquivo em static/css/main.css.
npm install -D tailwindcss
npx tailwindcss init
@tailwind base;
@tailwind components;
@tailwind utilities;
O arquivo tailwind.config.js precisa apontar para os templates Django, para que o Tailwind identifique as classes usadas. A chave content define os padrões de caminho que serão analisados. O exemplo abaixo cobre a pasta global templates e também templates dentro de apps Django. A configuração de darkMode define como o modo escuro é ativado.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./templates/**/*.html", "./**/templates/**/*.html"],
darkMode: "media",
theme: {
extend: {},
},
plugins: [],
};
Para gerar o CSS final, é comum criar um script no package.json que compila e observa alterações. O parâmetro -o define o arquivo de saída, e o parâmetro -w mantém o processo em modo “watch”, recompilando ao salvar templates ou CSS de entrada. Esse CSS compilado deve ser referenciado nos templates Django via o sistema de arquivos estáticos.
{
"scripts": {
"watch:css": "tailwindcss build static/css/main.css -o static/css/output.css -w"
}
}
npm run watch:css
Criação de um app Django para “chat bubble”
Em Django, um app é um módulo com responsabilidade bem definida, como “chat”, “blog” ou “contas”. A criação do app gera uma estrutura com arquivos para views, urls e possíveis modelos. A página do exemplo será servida por uma view simples que apenas renderiza um template. Essa abordagem é suficiente para demonstrar integração de Tailwind com templates.
Os comandos e arquivos a seguir mostram a criação do app e a view responsável por retornar o HTML. A função recebe um objeto request, que representa a requisição HTTP, e retorna uma resposta renderizada. O template usado será chat.html dentro da pasta de templates.
django-admin startapp chat
# chat/views.py
from django.shortcuts import render
def chat(request):
return render(request, "chat.html")
Para que a view seja acessível, é necessário declarar rotas. Em Django, rotas são declaradas em arquivos urls.py usando funções como path. Um arquivo de URLs do app define as rotas internas, e o arquivo principal do projeto inclui as rotas do app. Essa separação ajuda a manter o projeto organizado conforme cresce.
Os trechos abaixo mostram um chat/urls.py simples e a inclusão dessas rotas no arquivo principal do projeto. O nome da rota ajuda em reversão de URL, permitindo referenciar a rota por identificador em vez de texto fixo. Esse padrão melhora manutenção quando caminhos mudam.
# chat/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.chat, name="chat"),
]
# myproject/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("chat.urls")),
]
Template base com carregamento de CSS estático
Um template base concentra o “esqueleto” HTML, evitando repetição entre páginas. No Django, o template base costuma definir o block que será preenchido por páginas específicas. O carregamento de arquivos estáticos é feito com a tag {% load static %} e com o helper {% static %}, que monta o caminho correto do arquivo. Esse mecanismo funciona bem com o CSS compilado do Tailwind.
O exemplo abaixo inclui o arquivo static/css/output.css como stylesheet. As classes Tailwind são aplicadas no body e em elementos internos para criar uma base visual simples. O bloco content permite que outros templates herdem e preencham o conteúdo central.
{% load static %}
<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Django com Tailwind</title>
<link rel="stylesheet" href="{% static 'css/output.css' %}" />
</head>
<body class="min-h-screen bg-slate-200 dark:bg-slate-800">
<section class="container mx-auto flex flex-col items-center px-4">
<div class="mt-10 mb-6 text-center">
<h1 class="text-4xl font-bold text-sky-600 dark:text-sky-300">Chat Bubble</h1>
<p class="mt-2 text-sm text-slate-600 dark:text-slate-300">
Exemplo de interface usando Tailwind CSS em templates Django.
</p>
</div>
{% block content %}{% endblock %}
</section>
</body>
</html>
Template do chat com classes Tailwind
A tela de chat pode ser construída com layout flexível e estilos de tipografia e espaçamento do Tailwind. A estrutura inclui avatar, cabeçalho com nome e hora, corpo da mensagem e um rodapé com status. Esse modelo é comum em interfaces de mensageria e demonstra bem alinhamento e responsividade. As classes usadas controlam tamanho, cores, bordas arredondadas e espaçamentos.
O exemplo abaixo usa herança do template base e insere o conteúdo no bloco definido. O HTML foi mantido simples para destacar as utilidades do Tailwind. Os textos e horários são apenas demonstrativos e podem ser substituídos por dados vindos do backend posteriormente.
{% extends "base.html" %}
{% block content %}
<div class="w-full max-w-xl space-y-6">
<div class="flex items-start gap-3">
<div class="h-10 w-10 overflow-hidden rounded-full bg-slate-300">
<img
src="https://cdn.flyonui.com/fy-assets/avatar/avatar-1.png"
alt="Avatar"
class="h-full w-full object-cover"
/>
</div>
<div class="flex-1">
<div class="flex items-baseline gap-2">
<span class="text-sm font-semibold text-slate-900 dark:text-slate-100">Jhon Doe</span>
<span class="text-xs text-slate-500 dark:text-slate-400">11:46</span>
</div>
<div class="mt-2 rounded-2xl rounded-tl-sm bg-slate-100 p-4 text-sm text-slate-900 dark:bg-slate-700 dark:text-slate-100">
That's awesome. I think our users will really appreciate the improvements.
</div>
<div class="mt-1 text-xs text-slate-500 dark:text-slate-400">Delivered</div>
</div>
</div>
</div>
{% endblock %}
Execução do servidor de desenvolvimento
O Django inclui um servidor de desenvolvimento para testar a aplicação localmente. Esse servidor recarrega automaticamente em várias alterações de código Python, ajudando no ciclo rápido de desenvolvimento. O comando deve ser executado no diretório onde está o arquivo manage.py. Ao iniciar, o Django expõe uma URL local para acesso no navegador.
O comando abaixo inicia o servidor. Em paralelo, o processo do Tailwind em modo “watch” mantém o CSS compilado atualizado conforme as classes mudam nos templates. Essa combinação garante que mudanças visuais apareçam rapidamente durante o desenvolvimento.
python manage.py runserver
Formatação de classes Tailwind com Prettier
Com Tailwind, é comum que um elemento acumule muitas classes, o que pode reduzir legibilidade. Prettier é um formatador de código que padroniza a formatação automaticamente, e existe um plugin específico para organizar classes do Tailwind em uma ordem consistente. Essa ordenação reduz diffs desnecessários em controle de versão e melhora manutenção. O resultado é um HTML mais limpo e previsível.
Os comandos abaixo instalam o Prettier e o plugin de Tailwind como dependências de desenvolvimento. O arquivo .prettierrc registra o plugin para que a ordenação seja aplicada ao formatar. A integração com editor varia, mas a configuração base do projeto já habilita o comportamento quando o Prettier é executado.
npm install --save-dev prettier prettier-plugin-tailwindcss
{
"plugins": ["prettier-plugin-tailwindcss"]
}
Uso de componentes FlyonUI com Tailwind e Django
FlyonUI é uma biblioteca de componentes construída sobre Tailwind, fornecendo padrões prontos de interface. Uma biblioteca de componentes reúne estruturas HTML e classes que implementam peças comuns, como chat, botões e menus. Esse tipo de solução reduz tempo de montagem de layouts repetidos. Quando a biblioteca inclui JavaScript opcional, os arquivos precisam ser servidos como estáticos no Django.
A instalação é feita via npm e a configuração do Tailwind deve incluir os caminhos de conteúdo e plugins necessários. O exemplo abaixo mostra a instalação e um modelo de configuração incluindo FlyonUI. A ativação de JavaScript é opcional e deve ser incluída apenas se componentes interativos forem usados.
npm install -D flyonui@latest
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./templates/**/*.html",
"./**/templates/**/*.html",
"./node_modules/flyonui/dist/js/*.js"
],
theme: {
extend: {},
},
plugins: [
require("flyonui"),
require("flyonui/plugin")
]
};
Quando o JavaScript da biblioteca precisa ser servido pelo Django, um arquivo pode ser copiado para a pasta static. Isso permite referenciar o script no template base usando a tag {% static %}. O caminho final deve refletir a organização do projeto, como static/js/flyonui.js. Essa inclusão é feita no final do body, prática comum para não bloquear renderização.
O trecho abaixo mostra como incluir o script no template base, assumindo que o arquivo foi colocado em static/js/flyonui.js. Em cenários sem componentes interativos, essa etapa pode ser omitida sem prejuízo. O foco principal permanece na geração e uso do CSS com Tailwind.
<script src="{% static 'js/flyonui.js' %}"></script>
Chat bubble com classes e estrutura do FlyonUI
O exemplo de chat com FlyonUI usa classes semânticas fornecidas pela biblioteca, como “chat”, “chat-bubble” e variações de remetente e destinatário. Essas classes encapsulam um padrão visual consistente, reduzindo a necessidade de compor utilitários manualmente. A estrutura inclui avatar, cabeçalho com horário e um rodapé com status. O resultado é um layout de chat pronto com poucas decisões adicionais.
O template abaixo mantém a herança do base.html e substitui o conteúdo do bloco principal. As imagens são apenas ilustrativas e o conteúdo textual é demonstrativo. Esse modelo mostra como Django pode renderizar componentes prontos sem alterar o funcionamento do backend.
{% extends "base.html" %}
{% block content %}
<div class="w-full max-w-xl space-y-6">
<div class="chat chat-receiver">
<div class="avatar chat-avatar">
<div class="size-10 rounded-full overflow-hidden">
<img
src="https://cdn.flyonui.com/fy-assets/avatar/avatar-1.png"
alt="avatar"
/>
</div>
</div>
<div class="chat-header text-base-content/90">
Obi-Wan Kenobi
<time class="text-base-content/50">12:45</time>
</div>
<div class="chat-bubble">I started learning guitar today!</div>
<div class="chat-footer text-base-content/50">
<div>Delivered</div>
</div>
</div>
<div class="chat chat-sender">
<div class="avatar chat-avatar">
<div class="size-10 rounded-full overflow-hidden">
<img
src="https://cdn.flyonui.com/fy-assets/avatar/avatar-2.png"
alt="avatar"
/>
</div>
</div>
<div class="chat-header text-base-content/90">
Anakin
<time class="text-base-content/50">12:46</time>
</div>
<div class="chat-bubble">That's awesome! You're going to be great at it!</div>
<div class="chat-footer text-base-content/50">
Seen
<span class="icon-[tabler--checks] align-bottom text-success"></span>
</div>
</div>
</div>
{% endblock %}
Conclusão
A integração de Django com Tailwind CSS cria um fluxo eficiente: Django organiza rotas, templates e arquivos estáticos, enquanto Tailwind fornece uma camada visual flexível e consistente. A configuração depende de três pontos essenciais: caminhos corretos em tailwind.config.js, geração do CSS compilado e referência ao arquivo resultante via static. Com isso, templates ganham estilos responsivos sem depender de grandes arquivos CSS manuais.
A organização do HTML melhora com Prettier e o plugin do Tailwind, que padronizam a ordem das classes e reduzem ruído em manutenção. Quando há necessidade de velocidade na criação de interface, bibliotecas como FlyonUI adicionam componentes prontos que se encaixam naturalmente no sistema de templates do Django. O conjunto forma uma base sólida para aplicações web modernas, combinando produtividade no backend e agilidade na camada visual.