DEV Community

Cover image for Global progress bar for htmx
Amal Shaji
Amal Shaji

Posted on • Originally published at amalshaji.com

Global progress bar for htmx

Introduction

One of the cool features of htmx is that it lets you add a progress bar to your ajax requests with ease.
The request-indicator (hx-indicator) toggles the target element's (progress indicator element) opacity to 1 during the request and to 0 when the request ends.

When htmx issues a request, it will put a htmx-request class onto an element (either the requesting element or another element, if specified). The htmx-request class will cause a child element with the htmx-indicator class to transition to an opacity of 1, showing the indicator.

This post is about adding a global progress bar for htmx. This way, you can define the progress bar once and attach it to all your htmx requests.

Progress bar

Add the following progress bar to the top of the base template.

<div class="progress" style="height: 3px; background-color: white;">
      <div class="indeterminate" style="background-color: red;"></div>
</div>
Enter fullscreen mode Exit fullscreen mode

The associated css:

.progress {
  position: fixed;
  top: 0;
  z-index: 1000;
  height: 4px;
  width: 100%;
  border-radius: 2px;
  background-clip: padding-box;
  overflow: hidden;
}
.progress .indeterminate:before {
  content: "";
  position: absolute;
  background-color: inherit;
  top: 0;
  left: 0;
  bottom: 0;
  will-change: left, right;
  -webkit-animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395)
    infinite;
  animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;
}
.progress .indeterminate:after {
  content: "";
  position: absolute;
  background-color: inherit;
  top: 0;
  left: 0;
  bottom: 0;
  will-change: left, right;
  -webkit-animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1)
    infinite;
  animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1)
    infinite;
  -webkit-animation-delay: 1.15s;
  animation-delay: 1.15s;
}
.progress {
  display: none;
}
.htmx-request .progress {
  display: inline;
}
.htmx-request.progress {
  display: inline;
}
@-webkit-keyframes indeterminate {
  0% {
    left: -35%;
    right: 100%;
  }
  60% {
    left: 100%;
    right: -90%;
  }
  100% {
    left: 100%;
    right: -90%;
  }
}
@keyframes indeterminate {
  0% {
    left: -35%;
    right: 100%;
  }
  60% {
    left: 100%;
    right: -90%;
  }
  100% {
    left: 100%;
    right: -90%;
  }
}
@-webkit-keyframes indeterminate-short {
  0% {
    left: -200%;
    right: 100%;
  }
  60% {
    left: 107%;
    right: -8%;
  }
  100% {
    left: 107%;
    right: -8%;
  }
}
@keyframes indeterminate-short {
  0% {
    left: -200%;
    right: 100%;
  }
  60% {
    left: 107%;
    right: -8%;
  }
  100% {
    left: 107%;
    right: -8%;
  }
}
Enter fullscreen mode Exit fullscreen mode

Then, add a progress attribute to all your htmx requests hx-indicator=".progress"

Demo

Top comments (2)

Collapse
 
zodman profile image
Andres 🐍 in 🇨🇦

wow! excelnt article!

Collapse
 
ayoub_anbara profile image
ayoub anbara 🇲🇦

Thank you.
Just a remark, hx-indicator is inherited and can be placed on a parent element instead to attach it to every htmx requests.
Reference