Creating a modal window is a pretty common task when building a new website but sometimes it is not obvious how to do it by just using HTMX and Alpine.js. Both libraries are going to be complementary in building a proper modal window experience.
In the example below, we are going to build a modal window that will be opened by clicking on a link. The content will be loaded into a modal window. To dismiss the window user has to click outside of the modal window or hit the escape button. One additional feature that we will add is the possibility to share a link after opening a modal window.
Let's start with the basic skeleton of our modal window experience. On the body element, we will specify several attributes for Alpine.js. x-data
attribute is responsible for declaring a new variable in Alpine.js called openModal
which holds a flag if the modal window is open or not. x-bind:class
is chanding CSS classes on body
element based on openModal
variable. In the example below it will add overflow-hidden
CSS class when the modal window is open.
In the post example, Tailwind classes are used to style the components. The overflow-hidden
class on body
element hides the main content scrollbar so it will be not possible to scroll the main content area. Later we will add a scrollbar on the modal window which allows to scroll modal's content.
<body x-data="{openModal: false}"
x-bind:class="openModal && 'overflow-hidden'">
<!-- Link template here-->
<!-- Modal template here -->
<!-- Don't forget to load libraries -->
<script defer src="/js/htmx.js"></script>
<script defer src="/js/alpine.js"></script>
</body>
</html>
The most important part of the implementation is the modal window below. It consists of three important parts. The main container has x-show
attribute for controlling when the modal window is open or closed. The x-on
action will close the modal window once the escape button is hit and it will change the URL.
The background overlay is a straightforward HTML element. It adds a layer below a modal window covering the main content. The example below has a dark background with some opacity so the content below is barely visible.
The main component in the example is the modal window itself. It has a fixed position and overflow-auto
CSS class which is for adding a scrollbar when the modal's content is larger than the window's height. There is x-on:click.outside
attribute which will close the modal. The div
element with id modal-content
is the wrapper where the content is going to be loaded.
<div x-show="openModal"
x-on:keydown.escape.window="openModal = false; history.pushState({}, '', '/')">
<!-- Background overlay -->
<div class="bg-slate-900/80 bottom-0 fixed left-0 right-0 top-0 z-20"></div>
<!-- Modal window styling-->
<div class="fixed bottom-0 p-6 left-0 overflow-auto right-0 top-0 z-30 lg:py-24">
<div class="container max-w-7xl mx-auto relative shadow-lg z-90"
x-on:click.outside="openModal = false; history.pushState({}, '', '/')">
<!-- Main content from HTMX will be inserted here-->
<div id="modal-content" class="bg-white p-6 rounded-lg lg:p-12"></div>
</div>
</div>
</div>
Let's create a basic link pointing at the URL with the desired content. Below you can find an example HTML which can be copied and pasted inside the codebase. Of course, links have to be changed. The code below will create a basic hyperlink. When the user clicks on it, the target URL with queried, and HTMX will find post-content
element which will be put into modal-content
. After that, Alpine.js will be informed that a modal window can be opened.
<a href="/some-content"
hx-get="/some-content"
hx-select="#post-content"
hx-target="#modal-content"
hx-push-url="true"
x-on:htmx:after-on-load="openModal = true">
Link pointing at the content
</a>
It is important to not forget to create under /some-content
URL a div
element with id post-content
. This element will be used by HTMX to load just a part of the response into the modal window instead of the whole response.
href
contains a link pointing at the content that we want to fetchhx-get
tells HTMX to trigger GET queryhx-select
will choose an HTML element from the responsehx-target
where the content is going to be appendedhx-push-url
changes the current URL so it will be possible to share itx-on:htmx:after-on-load
Alpine.js event triggered when HTMX event is finishedDjango admin theme built with Tailwind CSS to bring modern look and feel to your admin interface. Already contains several built-in features for smooth developer experience.
© 2023 - 2024 Created by unfoldadmin.com. All rights reserved.