Dynamic Grid Image Gallery in Webflow (No Code)

Intermediate 22:58 webflowcmsgallerylayoutattributesno-code

Build a CMS-driven grid gallery in Webflow where every image keeps its true aspect ratio, uncropped — set the columns per breakpoint with a few attributes.

Key takeaways

  • object-fit: cover is the wrong tool for a real gallery — it crops your images. The fix is to size each image by its own proportions, so every detail stays visible.
  • Within a row, each image's width is its aspect ratio divided by the sum of all the aspect ratios in that row, times the space available (100% minus the gaps).
  • You never set image widths yourself — the Designer width (keep it ~40–45%) only stops items stacking while you work; the script overwrites it with the computed value on the live site.
  • Column counts cascade like Webflow's own styles: a value set for a larger breakpoint flows down to smaller ones until you override it, and the default is two columns everywhere.
  • When the last row isn't full, the code pretends the empty slots hold images of the same (or the average) aspect ratio — so a lone leftover image gets a natural width instead of stretching across the whole row.

Video chapters

  1. 00:00 Intro
  2. 01:51 Highlighting the problem
  3. 02:58 Overview on the underlying structure
  4. 04:48 Explaining the setup and the attributes for the configuration
  5. 11:51 Solution showcase #1: 1 collection list with lightbox elements
  6. 13:15 Attributes default values
  7. 14:00 Adding animations
  8. 16:52 Not enough elements to fill up the last row
  9. 18:32 Solution showcase #2: 2 collection lists with lightbox elements
  10. 20:54 Solution showcase #3: 1 static list of images
  11. 22:24 Outro

You can build a dynamic, CMS-driven grid gallery in Webflow where every image keeps its exact aspect ratio — no cropping, no object-fit: cover, nothing cut off at the edges. Point it at a CMS collection (or just a handful of static images), tell it how many columns you want at each breakpoint, and the layout works out the rest.

The trick most tutorials reach for — object-fit: cover — trims your images to fit the grid. That’s fine for thumbnails, but it’s the wrong move for a real gallery, where every detail of the work is the whole point. This solution sizes each image by its own proportions instead, so a wide landscape shot and a tall portrait can share the same row and both stay perfectly intact.

It’s an attributes-only component: the code is already written and ships with the cloneable, so all you do is drop a few attributes on the right elements. It works with CMS or static images, with plain images or lightboxes, and you can run as many galleries as you like on a single page.

How it works

The math behind it. Take a row of, say, three images. For each one the script measures its aspect ratio (width ÷ height), then adds up all three. Each image gets a share of the row equal to its own ratio divided by that sum — a number smaller than one. Multiply that share by the space actually available (100% of the row minus the gaps between images) and you get a width that keeps the image’s proportions intact while the row stays perfectly filled. Wider images get wider columns, taller ones get narrower columns, automatically.

What you actually style. You don’t set the image widths yourself. In the Designer you give the gallery item a width of around 40–45% — purely so the items don’t pile on top of each other while you’re working — and the script overwrites it with the computed value once the page is live. Don’t go much below 40%, though: Webflow picks which responsive image size to generate from the width it sees in the Designer, so a tiny width makes it serve a small, pixelated file.

Columns per breakpoint. You declare the column count with columns-desktop, columns-tablet, columns-landscape and columns-portrait on the gallery wrapper. They cascade exactly like Webflow’s own styles: whatever you set for a larger breakpoint flows down to the smaller ones until one of them sets its own number. Set nothing at all and every breakpoint gets two columns.

The two edge cases it handles for you. First, the last row. When the images don’t divide evenly into your column count, a single leftover image has nothing to be sized against — so the code invents phantom images with the same aspect ratio (or, for two leftovers, the average of the two) and sizes the real ones as if the row were full. Second, the flicker: the widths can only be computed once every image has loaded, so there’s a brief flash on first paint. Cover it with a simple page-load fade on the gallery wrapper, and optionally a scroll-into-view animation on each item for a little life.

How to use it

  1. Clone the project. The script, the attributes, and a working sample gallery all come in the Webflow cloneable linked below. Start there so the attribute names match the code out of the box.

  2. Set up your content. For a CMS gallery, use a collection with a multi-image field and bind a collection list to it. For static images, a plain wrapper of images works just as well — nothing has to come from the CMS.

  3. Mark the gallery wrapper. On the collection list (or the static wrapper), set display: flex, direction row, and a gap you like, then add fc-gallery="list".

  4. Mark each item. On the gallery item — the collection item, or each static image wrapper — add fc-gallery="item", and give it a Designer width of about 40–45% so items don’t stack while you design. The script replaces that width on the live site.

  5. Handle lightboxes and images. If you use a lightbox, set its display to block (it defaults to inline-block) so it fills the item, link each one to its image, and give them a shared group name so they browse together. Set the image itself to display: block and width: 100%.

  6. Choose your columns. On the gallery wrapper, add columns-desktop, columns-tablet, columns-landscape and/or columns-portrait with the counts you want. Remember they cascade down, and leaving them all off gives you two columns everywhere.

  7. Smooth the load (optional). Add a page-load interaction that fades the gallery wrapper from opacity 0 to 100% to hide the initial calculation flicker, and a scroll-into-view slide/fade on each item to make the grid feel alive.

  8. Reuse it freely. Duplicate the gallery for a second layout with a different column setup, or drop more galleries on other pages — each one reads its own attributes independently.

Configuration reference

Attribute Values Default What it does
fc-gallery list | item Marks the gallery. Put list on the collection list (or the static wrapper) that holds your images, and item on each gallery item inside it. The script needs both to find your gallery and lay it out.
columns-desktop a number 2 How many columns the gallery has on the desktop breakpoint. Whatever you set here cascades down to smaller breakpoints until one of them sets its own value.
columns-tablet a number Overrides the column count on the tablet breakpoint. Leave it off to inherit the desktop value cascading down.
columns-landscape a number Overrides the column count on the landscape breakpoint. Leave it off to inherit whatever cascades down from above.
columns-portrait a number Overrides the column count on the portrait breakpoint. Leave it off to inherit the value from the breakpoint above.

Resources

Frequently asked questions

How do I make a Webflow image gallery where images keep their aspect ratio without cropping?
Skip object-fit: cover, which trims images to fit. Instead, size each picture from its aspect ratio relative to the others in its row so it fills its share of the width and stays whole. This component does that math for you, so a wide shot and a tall shot can sit side by side with nothing cut off.
Can I set a different number of columns for each breakpoint?
Yes. Add columns-desktop, columns-tablet, columns-landscape and columns-portrait to the gallery wrapper. Any value you set cascades down to smaller breakpoints until one of them defines its own, and if you set none the layout falls back to two columns everywhere.
Does this work with static images, or only CMS collections?
Both. The layout reads from any wrapper you mark as the gallery, so it works with a CMS collection list, a plain set of static images, and with or without lightboxes — you can even run several independent galleries on a single page.
Why do my gallery images look pixelated after I publish?
Webflow decides which responsive image size to generate from the width it sees in the Designer, so a very narrow item makes it serve a small file. Keep the gallery item's Designer width around 40–45% and the script will still resize it correctly on the live site.
What happens when the last row doesn't have enough images to fill it?
The code fills the empty slots with phantom images that share the same (or the average) aspect ratio as the real ones. That gives a single leftover image a natural width instead of letting it stretch across the entire final row.

← Back to the course

Also part of these courses