How to create Conditional HX-Triggers based on Element Visibility with HTMX

Date: 2024-10-23 | create | tech | htmx | projects | one-million-checkboxes |

I recently released One Million Checkboxes - a globally synced display of 1 million checkboxes using HTMX to drive the UI. Under the hood it uses polling to rerender sections of the grid. However rendering everything at once is too costly (~5mb per reload) so I needed to implement conditionals to only pull UI sections it needs (~3.6kb per reload) based on what the user's browser is looking at.

I implemented this using HTMX's trigger conditionals to call a custom function determining if the target element was visible or not.

Here we'll explore how this works so you can implement something similar in your own app.

App Overview

First an overview of One Million Checkboxes to give you a better idea of how this visibility conditional works and fits into the broader system.

  • A display of One Million Checkboxes
  • Split into grid sections of 1000 checkboxes
  • Each grid has a unique Id of format CheckboxGrid_STARTINDEX which we use as an HTMX Target
  • Each grid has its own HTMX poller using hx-trigger
  • On trigger, it checks if it's visible using HTMX conditionals and if so fetches the new version of the grid and swaps out its innerHTML

The grid HTML looks like this:

<div 
    id="CheckboxGrid_999000" 
    hx-get="/?start=999000" 
    hx-target="#CheckboxGrid_999000" 
    hx-swap="innerHTML" 
    hx-trigger="every 3.641347793457788s [isElementVisible(CheckboxGrid_999000)]" 
    class="grid place-items-center">

<!-- Checkbox HTML omitted for clarity -->

</div>

Notable:

  • hx-trigger every x seconds
  • Uses a helper function isElementVisible with the element's id as a conditional to see if it should trigger or not

HTMX Conditionals on Element Visibility

HTMX allows conditional triggering with the syntax hx-trigger="TRIGGER [CONDITIONAL]". It currently does not have a built-in conditional for whether the element is visible or not so I had to roll my own.

isElementVisible takes in a reference to an HTML element and tries to determine if the element is visible by comparing the window with the bounding box of the element. Honestly this API is confusing as both the window and element positions change on scroll but I've cross-referenced it with several answers and it works in prod so seems to work as expected.

function isElementVisible(element) {

    if(!element) {
        return false 
    }

    const elementRectangle = element.getBoundingClientRect()
    const elementTop = elementRectangle.top 
    const elementBottom = elementTop + elementRectangle.height

    // Source: https://stackoverflow.com/questions/487073/how-to-check-if-element-is-visible-after-scrolling
    const isVisible = elementTop < window.innerHeight && elementBottom >= 0

    return isVisible
}

To call this function with HTMX:

  • Include the function on the webpage (script tag or import)
  • Call this function inside hx-trigger as a conditional, passing in the element's id

Next

You can see this code in action yourself on One Million Checkboxes.

If you liked this post you might also like:

Want more like this?

The best / easiest way to support my work is by subscribing for future updates and sharing with your network.