CSS, imagens e layout profissional no seu site
Sirva CSS, JavaScript e imagens no Flask e monte um layout moderno com Tailwind CSS.
A pasta static/
O Flask serve automaticamente qualquer arquivo que esteja dentro da pasta static/ do seu projeto. É lá que ficam CSS, JavaScript, imagens, fontes e qualquer outro recurso que o navegador precisa carregar.
Estrutura recomendada:
meu_projeto/
├── app.py
├── static/
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── main.js
│ └── img/
│ ├── logo.png
│ └── favicon.ico
└── templates/
├── base.html
└── index.html
Referenciando arquivos com url_for
Nunca use caminhos fixos como /static/css/style.css. Use url_for('static', filename=...) para gerar a URL corretamente, mesmo que a aplicação esteja em um subdiretório:
<!-- No template Jinja2 -->
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
<img src="{{ url_for('static', filename='img/logo.png') }}" alt="Logo">
O url_for garante que o caminho funcione em qualquer ambiente, seja local ou em produção.
Favicon e meta tags
Para que o navegador exiba o ícone da aba corretamente, adicione o favicon no <head> do seu template base:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="{{ url_for('static', filename='img/favicon.ico') }}">
<title>{% block title %}Meu Site{% endblock %}</title>
</head>
As meta tags de viewport são essenciais para que o layout funcione bem em dispositivos móveis.
Adicionando Tailwind CSS via CDN
A forma mais rápida de começar com Tailwind CSS é usando o CDN do browser. Adicione no <head> do seu base.html:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<title>{% block title %}Meu Site{% endblock %}</title>
</head>
Com isso, você pode usar qualquer classe do Tailwind diretamente no HTML.
Criando um layout responsivo
Vamos montar um layout completo com navbar, hero e footer usando Tailwind:
<!-- templates/base.html -->
<!doctype html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<title>{% block title %}Meu Site{% endblock %}</title>
</head>
<body class="bg-gray-950 text-white min-h-screen flex flex-col">
<!-- Navbar -->
<header class="border-b border-white/10 py-4">
<div class="max-w-5xl mx-auto px-6 flex items-center justify-between">
<a href="/" class="font-bold text-lg">Meu Site</a>
<nav class="flex gap-6 text-sm text-white/60">
<a href="/" class="hover:text-white">Inicio</a>
<a href="/sobre" class="hover:text-white">Sobre</a>
<a href="/contato" class="hover:text-white">Contato</a>
</nav>
</div>
</header>
<!-- Conteudo -->
<main class="flex-1">
{% block content %}{% endblock %}
</main>
<!-- Footer -->
<footer class="border-t border-white/10 py-6 text-center text-xs text-white/30">
2026 Meu Site. Feito com Flask e Tailwind CSS.
</footer>
</body>
</html>
Grid de cards
Um padrão muito comum é exibir conteúdo em um grid responsivo. Com Tailwind, basta algumas classes:
<!-- templates/index.html -->
{% extends "base.html" %}
{% block content %}
<section class="max-w-5xl mx-auto px-6 py-16">
<h1 class="text-3xl font-bold mb-8">Artigos</h1>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
{% for artigo in artigos %}
<a href="/artigo/{{ artigo.slug }}" class="bg-white/5 border border-white/10 rounded-xl p-6 block hover:border-yellow-400/30 transition-colors">
<span class="text-xs text-yellow-400 uppercase tracking-wider">{{ artigo.tag }}</span>
<h2 class="font-bold mt-2 mb-2">{{ artigo.titulo }}</h2>
<p class="text-sm text-white/50">{{ artigo.resumo }}</p>
</a>
{% endfor %}
</div>
</section>
{% endblock %}
O grid usa md:grid-cols-2 para duas colunas em telas médias e lg:grid-cols-3 para três colunas em telas grandes. Em telas pequenas, os cards ficam empilhados automaticamente.
Dicas de performance
Quando seu site for para produção, algumas práticas ajudam a melhorar o carregamento:
- Cache de arquivos estáticos: configure o tempo de cache no servidor (Nginx ou o próprio Flask)
- Minificação: use versões
.min.csse.min.jsdas bibliotecas - Lazy loading de imagens: adicione
loading="lazy"nas tags<img> - CDN para bibliotecas: use CDNs para jQuery, Tailwind, highlight.js em vez de servir localmente
No Flask, você pode configurar o cache de arquivos estáticos:
app = Flask(__name__)
app.config["SEND_FILE_MAX_AGE_DEFAULT"] = 3600 # 1 hora de cache
Conclusão
Arquivos estáticos são a ponte entre o backend Python e a experiência visual do usuário. Com a pasta static/, o url_for e o Tailwind CSS via CDN, você consegue criar layouts profissionais e responsivos sem precisar de um pipeline complexo de build. No próximo passo, vamos aprender a colocar tudo isso no ar com Docker e Gunicorn.