HTMX, Tailwind CSS, and Django: From Basics to Advanced. Part 2

Patryk Młynarek - Backend Engineer

Patryk Młynarek

31 January 2024, 9 min read

thumbnail post

What's inside

  1. Example usages
  2. Real-world Example
  3. HTMX Commonly Used Features
  4. Optimizing Performance
  5. Alternative integration for HTMX and Tailwind CSS
  6. Resources
  7. Conclusion

Welcome to the second part of our deep dive into the dynamic combination of HTMX, Tailwind CSS, and Django. In the first part, we extensively explored setting up these tools, laying a foundation for modern web development. As we venture further, we aim to transition from foundational knowledge to an intricate understanding.

In this edition, we'll unveil the commonly used features of HTMX, illustrating its transformative impact on interactive web development. Alongside, we'll delve into practical applications, showcasing the synergy of Tailwind CSS and HTMX in real-world scenarios. Beyond mere applications, our focus will also span towards optimizing performance, ensuring that our applications look good, function well, and deliver unparalleled speed and responsiveness.

Additionally, for those who love to explore alternative paths and seek flexibility in their tech stack, we'll touch upon alternative methods of integrating HTMX and Tailwind CSS. As we conclude, a curated list of resources will guide you toward further mastery of these technologies.

So, buckle up for another enlightening journey as we continue to unravel the combined prowess of HTMX, Tailwind CSS, and Django, guiding you from basics to advanced nuances.

Example usages

Tailwind CSS

These examples demonstrate the power and simplicity of Tailwind CSS, a utility-first CSS framework. With just a few class attributes, you can effortlessly style your web elements and create a visually appealing Call to Action (CTA). The classes applied here control everything from background gradients and text color to font size and padding.

For instance, the background gradient, achieved with the classes bg-gradient-to-r from-purple-600 via-pink-600 to-red-600, smoothly transitions from purple to pink and then to red, creating an eye-catching visual effect. The text is styled in white for contrast, enhancing readability.

The use of classes like text-3xl and font-semibold defines the header's size and weight, while mt-4 adds spacing to the paragraph below. Even the button is effortlessly styled using classes like bg-pink-500, which sets the background color, and hover:bg-pink-700, which creates a color transition on hover.

The beauty of Tailwind CSS lies in its simplicity and flexibility. If you ever need to adjust the design, you can modify or add Tailwind classes without touching your CSS files.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tailwind CSS Call to Action</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gradient-to-r from-purple-600 via-pink-600 to-red-600 text-white font-sans p-8">
    <div class="container mx-auto text-center">
        <h2 class="text-3xl font-semibold mb-4">Ready to Get Started?</h2>
        <p class="mt-4">Join us today and experience the future of web development.</p>
        <button class="bg-pink-500 hover:bg-pink-700 text-white font-bold py-2 px-4 rounded-full mt-8">Sign Up Now</button>
    </div>
</body>
</html>

html1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tailwind CSS Feature List</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 font-sans p-8">
    <div class="container mx-auto">
        <h2 class="text-2xl font-semibold mb-4">Our Features</h2>
        <ul class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
            <li class="bg-white p-4 rounded-lg shadow-md">
                <h3 class="text-lg font-semibold">Feature 1</h3>
                <p class="mt-2">A description of feature 1.</p>
            </li>
            <li class="bg-white p-4 rounded-lg shadow-md">
                <h3 class="text-lg font-semibold">Feature 2</h3>
                <p class="mt-2">A description of feature 2.</p>
            </li>
            <li class="bg-white p-4 rounded-lg shadow-md">
                <h3 class="text-lg font-semibold">Feature 3</h3>
                <p class="mt-2">A description of feature 3.</p>
            </li>
        </ul>
    </div>
</body>
</html>

htmx2

HTMX

Pay special attention to the three additional attributes added to the form markup: hx-post, hx-swap, and hx-target. These attributes are where the magic happens, enabling us to send form data requests to a specified URL, such as register, and seamlessly replace the content of an element with a specific ID in response to the request. This dynamic interaction empowers us to create web applications that can update and modify content without needing full page reloads.

hx-post="/add-task": This attribute specifies the URL to which the form data will be sent when the form is submitted. In this case, it's set to /add-task, indicating that a POST request will be made to the /add-task endpoint.

hx-swap="outerHTML": This attribute defines how the server's response should replace the current element's content. outerHTML means that the entire element, including its HTML structure, will be replaced with the response. In this context, it ensures that the form and its content are replaced with the updated list of tasks.

hx-target="#task-list": This attribute specifies the HTML element with the ID task-list that will be updated with the response from the server.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Task Management App</title>
        <script
            src="https://unpkg.com/htmx.org@1.9.6"
            integrity="sha384-FhXw7b6AlE/jyjlZH5iHa/tTe9EpJ1Y55RjcgPbjeWMskSxZt1v9qkxLJWNJaGni"
            crossorigin="anonymous"
        ></script>
        <script src="https://cdn.tailwindcss.com"></script>
    </head>
    <body class="bg-gray-100 font-sans p-8">
        <div class="container mx-auto">
            <h2 class="text-2xl font-semibold mb-4">Task Management App</h2>
            <form
                hx-post="/add-task"
                hx-swap="outerHTML"
                hx-target="#task-list"
                id="task-form"
                class="bg-white p-4 rounded-lg shadow-md"
            >
                <div class="mb-4">
                    <label for="task" class="block text-gray-600">New Task:</label>
                    <input type="text" id="task" name="task" class="form-input" required />
                </div>
                <div>
                    <button
                        type="submit"
                        class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full"
                    >
                        Add Task
                    </button>
                </div>
            </form>
            <ul id="task-list" class="mt-4"></ul>
        </div>
    </body>
</html>

htmx3

Real-world Example

Explore a practical demonstration of how HTMX, Tailwind CSS, and Django seamlessly collaborate to create a modern web application. This example showcases best practices and demonstrates the synergy of these technologies in a straightforward yet impactful manner.

Key Features:

  • Todo List Application: The example project is a minimalist Todo list application. It allows users to add and delete tasks seamlessly, demonstrating the smooth integration of HTMX, Tailwind CSS, and Django.
  • HTMX for Interactivity: Discover how HTMX supercharges the front end, enabling dynamic and interactive features. Learn how to implement tasks like task creation and deletion without needing full page reloads.
  • Tailwind CSS Styling: Witness the power of Tailwind CSS in action as it enhances the application's appearance and responsiveness. Tailwind CSS allows you to create a visually appealing, user-friendly interface with minimal effort.
  • Docker for Containerization: Learn how Docker simplifies the development and distribution of the application. Understand the Dockerfile setup for the entire project, ensuring a consistent and reproducible environment.
  • Pre-commit Hooks: Discover how pre-commit hooks streamline code quality with autoflake, flake8, isort, bandit, and Black. See how these hooks ensure code consistency and security.
  • Testing with pytest: Explore using pytest for writing unit tests that verify the application's functionality. Learn how to create tests that validate each component of your project.
  • CircleCI Integration: Understand how CircleCI is integrated into the development workflow to automate testing, linting, and deployment processes. Witness the benefits of continuous integration and delivery in action.

GitHub Repository: Access the full source code and project details in the GitHub repository. Dive into the codebase, explore the project structure, and gain hands-on experience with these powerful technologies working together in harmony. This real-world example will provide valuable insights for your projects and development endeavors.

Click here to check the repository.

htmx4

HTMX Commonly Used Features

Like any other package, library, or framework, HTMX offers critical functions and critical features.

  • hx-http-method

    • Issues a request to the given URL
    • Examples:
      • hx-get
      • hx-post
      • hx-put
      • hx-patch
      • hx-delete
  • hx-target

    • Define response target for HTMX
    • Examples:
      • hx-target="#search-results"
      • hx-target="body"
      • hx-target="next .error"
      • hx-target="closest tr"
  • hx-trigger

    • Define what should trigger the action
    • Examples:
      • hx-trigger="click"
      • hx-trigger="change, keyup delay:200ms changed"
      • hx-trigger="revealed"
      • hx-trigger="load"
  • hx-swap

    • Define which content should be swapped
    • Examples:
      • hx-swap="outerHTML"
      • hx-swap="innerHTML"
      • hx-swap="none"
  • hx-select

    • Define a subset of the response HTML to swap
    • Examples:
      • hx-select="tbody > tr"
  • hx-include

    • Include additional element values in an AJAX request
    • Examples:
      • hx-include="[name='email']"
  • hx-push-url

    • Specify if the request's URL should be pushed into the browser’s navigation bar
    • Examples:
      • hx-push-url="true"
  • hx-confirm

    • Define confirmation action message before issuing a request
    • Examples:
      • hx-confirm="Are you sure you wish to delete your account?"

Optimizing Performance

When working with HTMX and Tailwind CSS in conjunction with Django, it's essential to keep a few key considerations in mind:

HTMX: Prioritize minimizing the volume of data exchanged between the server and the client. Transmit only the essential data required to update the page. This practice can significantly reduce network latency and enhance page load times.

Tailwind CSS: Tailwind CSS empowers you to generate an optimized, production-ready CSS file. Take advantage of tools like PurgeCSS to eliminate unused styles, resulting in a more compact CSS file that loads quickly. When combined with minification and network compression, it often yields CSS files that are less than 10kB, even for extensive projects.

Django Template Caching: Leveraging Django's template caching can yield substantial speed improvements in page rendering. However, it's crucial to approach caching carefully, conducting a comprehensive assessment of caching conditions to ensure that we cache only what can be cached.

Alternative integration for HTMX and Tailwind CSS

While a direct integration of HTMX and Tailwind CSS provides a lightweight and flexible approach, some developers may find value in specialized packages that simplify the process or offer additional tools and functionality.

If you're looking for enhanced request handling specific to HTMX technology, the django-htmx package provides a solution. It enriches requests with HTMX-related information, for example, by including whether it's an HTMX request, the target element, and the current URL. This middleware streamlines the development process, making working with HTMX in your Django views easier.

Additionally, django-htmx offers a range of pre-built classes optimized for use with HTMX. Explore the package's documentation here for more information.

If your primary focus is on integrating Tailwind CSS effectively, the django-tailwind package comes to your aid. It offers a custom template tag that simplifies the inclusion of Tailwind CSS styles in your Django templates. One standout feature is the option to purge the CSS file generated by Tailwind CSS, allowing you to include only the styles that are used in your project. This optimization reduces the size of your CSS file, resulting in faster load times.

Additionally, django-tailwind provides valuable tools for local development and debugging. Delve into the package's documentation here to explore its full capabilities.

Resources

Conclusion

Key takeaways from our exploration include the importance of efficient data exchange, optimizing CSS for swifter performance, and the potential advantages of leveraging specialized Django packages tailored for HTMX and Tailwind CSS.

These insights are crucial in the modern web development landscape as the demand for fast, responsive, and interactive applications grows.

Our exploration of Django, HTMX, and Tailwind CSS showed us how to create modern, efficient web applications. With a solid foundation, you're now ready to build user-friendly, high-performance projects. Best of luck with your web development adventures!

If you have further questions or need guidance on any of these technologies, do not hesitate to reach out to our team. We are always here to assist and propel your web development projects to success.

Patryk Młynarek - Backend Engineer

Patryk Młynarek

Backend Engineer

Patryk is a experienced Senior Python Developer who puts business value on the first place. Web applications enthusiast from initial development to server maintenance, ensuring the entire process runs smoothly. In his free time, Patryk enjoys playing board games and motorcycling.