Since Django 4 form rendering with Tailwind can be used to render beautiful forms without using Node or any other packages like django-crispy-forms.
All you need is the Tailwind CLI binary and django-widget-tweaks.
The pytailwindcss package bundles the Tailwind CLI as a self-contained binary: not need to install Node!
The downside is, that it’s not possible to use any Tailwind plugins except for the built-in ones like @tailwindcss/forms.
pip install pytailwindcss
or put
pytailwindcss==0.1.4
into your requirements.txt (you should do that anyway).
Create an entry point for Tailwind in static/css/project.css:
@tailwind base;
@tailwind components;
@tailwind utilities;
Create a Tailwind configuration file in your project root to tell Tailwind where your templates are:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./<project>/**/*.{html,js}"],
theme: {
extend: {},
},
plugins: [require("@tailwindcss/forms")],
};
Whenever you run the local development server, also run the Tailwind compiler:
tailwindcss --watch -i <project>/static/css/project.css -o <project>/static/css/dist/styles.css
Include the compiled CSS as static file in your base template templates/base.html:
<link href="{% static 'css/dist/styles.css' %}" rel="stylesheet">
In order to customize the form rendering, define and configure a custom form renderer in your settings.py:
from django.forms.renderers import TemplatesSetting
class FormRenderer(TemplatesSetting):
form_template_name = "form_snippet.html"
FORM_RENDERER = "config.settings.base.FormRenderer"
Use django-widget-tweaks to add custom Tailwind classes to the input elements. Implement your own form rendering template form_snipper.html.
The following snippet covers the most basic input elements, feel free to implement your own.
{% load widget_tweaks %}
<div class="grid grid-cols-1 gap-6">
{% for field in form %}
<label class="block">
<span class="text-gray-700"
>{{ field.label }}</span
>
<!-- Checkbox -->
{% if field|field_type == 'booleanfield' %} {{
field|add_class:"rounded border-gray-300
text-indigo-600 shadow-sm
focus:border-indigo-300 focus:ring
focus:ring-offset-0 focus:ring-indigo-200
focus:ring-opacity-50" }}
<!-- Date -->
{% elif field|field_type == 'datefield' %} {{
field|add_class:"mt-1 block w-full rounded-md
border-gray-300 shadow-sm
focus:border-indigo-300 focus:ring
focus:ring-indigo-200 focus:ring-opacity-50"
}}
<!-- Email -->
{% elif field|field_type == 'emailfield' %} {{
field|add_class:"mt-1 block w-full rounded-md
border-gray-300 shadow-sm
focus:border-indigo-300 focus:ring
focus:ring-indigo-200
focus:ring-opacity-50"|attr:"placeholder:" }}
<!-- Password -->
{% elif field|field_type == 'passwordfield' %}
{{ field|add_class:"mt-1 block w-full
rounded-md border-gray-300 shadow-sm
focus:border-indigo-300 focus:ring
focus:ring-indigo-200
focus:ring-opacity-50"|attr:"placeholder:" }}
{% else %}
<!-- Fallback -->
{{ field }} {% endif %}
</label>
{% endfor %}
</div>
Tailwind is great with components. Django templates are not great with components.
It’s a good idea to define custom classes for highly re-usable elements like buttons and links. Define them in static/css/project.css.
Note that if you are using Tailwind with a framework like React, you should not define your custom CSS classes but instead heavily break down your UI into components.
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.btn-link {
@apply font-medium text-indigo-600 hover:text-indigo-500;
}
.btn-primary {
@apply items-center justify-center
rounded-md border border-transparent bg-indigo-600
px-4 py-2 text-base font-medium text-white
shadow-sm hover:bg-indigo-700;
}
}
Now all your forms will automatically look nice!
<form
class="login"
method="POST"
action="{% url 'account_login' %}"
>
{% csrf_token %} {{ form }} {% if
redirect_field_value %}
<input
type="hidden"
name="{{ redirect_field_name }}"
value="{{ redirect_field_value }}"
/>
{% endif %}
<a
class="btn-link"
href="{% url 'account_reset_password' %}"
>{% trans "Forgot Password?" %}</a
>
<button class="btn-primary" type="submit">
{% trans "Sign In" %}
</button>
</form>
Don’t forget to run the Tailwind CLI with the --minify argument in your deployment step in order to optimize the CSS:
tailwindcss \
--minify \
-i mentionedd/static/css/project.css \
-o mentionedd/static/css/dist/styles.css
Erben Systems GmbH
Watterstrasse 81, c/o Sarbach Treuhand AG, 8105 Regensdorf, Switzerland
CHE-174.268.027 MwSt