Error that cost me several nights - turbo frame and display contents

12 marca 2025

If you're using the Pagy gem with Ruby on Rails and Hotwire, turbo frame is a simple way to implement efficient pagination with infinite scroll. Turbo_frame_tag allows for dynamic updating of lists or individual elements on a page. In most browsers, turbo frame behaves like display: block.

If you're having issues with incorrect display of a list of elements, where each element is wrapped in a turbo frame, you should use the solution suggested on Stack Overflow and set display: contents for all turbo frame elements.

I used this solution in my code.

However, when adding pagination using loading: lazy, the code didn't work.

My code looked like this:

Fetching the product list in the controller:

Product list

I needed to set display: contents; for turbo frame to display products in a masonry grid format.

display: contents; makes the turbo frame invisible to the DOM.

Partial with pagination

And there was also an index.turbo_stream.erb file, which additionally handled the turbo_stream format for the index action.

This code was shamelessly correct. It always worked in every project where I used it. But this time, it didn't work.

loading: lazy only works when the turbo frame is visible in the browser and must have a path set to load (the src parameter). Because display: contents makes the turbo frame invisible to Turbo, loading: lazy doesn't work.

Turbo is a JavaScript mechanism that operates on DOM elements. Removing display: contents and reorganizing the HTML can help solve the problem.

Worth remembering.

A Turbo frame with loading: :lazy won't work with display: contents;.