How to Build a Horizontal Masonry Layout in Webflow
This tutorial provides a comprehensive guide to constructing a responsive horizontal masonry layout in Webflow, utilizing Flexbox to achieve a clean, no-code solution. The instructor moves beyond vertical layouts to demonstrate how images can fill horizontal rows while strictly respecting their original aspect ratios, a method inspired by classic CSS techniques. By starting with static elements and progressing to dynamic content, the video ensures viewers understand the foundational mechanics of Flexbox properties—specifically wrapping and sizing behavior—to create a visually cohesive gallery that functions seamlessly across all device sizes.
A central pillar of this lesson is the strict adherence to web accessibility standards. The layout is constructed using unordered lists (<ul>), which allows screen readers to correctly interpret the gallery as a structured sequence of connected items rather than a collection of unrelated div blocks. The tutorial addresses complex edge cases, such as the visual formatting of the final row, by introducing a "phantom" empty list item. Crucially, the presenter explains how to hide this decorative element from assistive technology using the aria-hidden attribute, ensuring the visual fix does not compromise the user experience for those relying on screen readers.
Finally, the video expands the utility of this layout by integrating it with Webflow’s Content Management System (CMS) and adding professional polish through animation. Viewers will learn to manipulate the "Last Item" selector within a collection list to replicate the layout logic dynamically, using custom fields to manage accessibility attributes. The session concludes by demonstrating how to fine-tune responsiveness by switching between viewport height and width units for tablets and mobile devices, and implementing a staggered GSAP animation to create a sophisticated, dynamic entry effect for the gallery items.
Key Takeaways
- Semantic Structure for Accessibility: The foundation of the layout should be an unordered list rather than a standard div container; this explicitly communicates to screen readers that the content belongs to a single, structured set, making navigation smoother for users utilizing assistive technology.
- Flexbox Logic and Object Fit: To ensure images fill rows without distortion, the container must wrap children while the items are set to grow and shrink uniformly (
grow: 1,shrink: 1). Concurrently, applyingobject-fit: coverto the images preserves their aspect ratios regardless of the parent container's fluctuating dimensions. - The "Empty Item" Technique: To prevent the final item in a gallery from expanding awkwardly to fill the entire remaining row space, add an empty list item with a
growvalue of 10 and ashrinkvalue of 0. This forces the empty item to take up the excess space, maintaining the visual integrity of the last image. - CMS Integration via Custom Attributes: When adapting this layout for a CMS Collection, use the "Last Item" pseudo-selector to target the empty spacer element. To maintain accessibility, bind the
aria-hiddenattribute to a custom text field in the CMS, setting it to "true" only for the empty item so screen readers ignore it. - Responsive Unit Switching: While
36vh(Viewport Height) functions well for desktop layouts, sizing must be adapted for smaller screens. The tutorial recommends switching to Viewport Width (vw) units orAutofor landscape and portrait mobile breakpoints to ensure the layout accommodates the change in orientation and aspect ratio.
Timestamps
Layout & Styling
- 03:42 - Set Main Container padding to 8rem (top/bottom) and 6rem (left/right), and max-width to 90rem.
- 04:14 - Add a list element, apply the
gallery listclass, set Display to Flex, and Gap to 0.5rem,. - 05:15 - Remove default list styling by selecting "No Bullets" in the Element Settings panel.
- 05:31 - Set the
gallery itemheight to 36vh as an initial value for desktop screens. - 06:26 - Set
gallery item imagewidth and height to 100% to fill the parent container. - 07:25 - Enable Flex Wrap on the
gallery listto allow children to stack into multiple rows. - 08:22 - Set Flex Child Grow and Shrink properties to 1 on
gallery itemto ensure rows fill completely. - 09:13 - Apply
object-fit: coverto images to preserve aspect ratios while resizing.
Handling Edge Cases & Accessibility
- 10:19 - Create an empty list item with combo class
cc-last, setting Shrink to 0 and Grow to 10 to manage the final row's layout,. - 11:15 - Add the
aria-hidden="true"attribute to the empty list item to hide it from screen readers. - 12:14 - Switch sizing units for Landscape mobile: set Width to 28vw and Height to Auto.
- 12:39 - Set the empty list item's display property to Hidden on the mobile portrait breakpoint.
CMS Integration & Animation
- 15:58 - Use the "Last Item" selector on the Collection List Item to target the empty spacer element dynamically.
- 17:16 - Add the
aria-hiddenattribute to the Collection Item and bind its value to the CMS text field. - 18:15 - Add the custom attribute
fc-gsap-staggered="list"to the gallery list element to enable the GSAP animation.
Technical Tutorial: Building an Accessible Horizontal Masonry Layout
This guide details how to construct a flexbox-based masonry grid that maintains image aspect ratios, adapts to all device sizes, and adheres to accessibility standards.
Step 1: Set Up the Container Structure
Timestamp Reference: 03:18 - 04:07
- How:
- Add a Section element.
- Inside the section, add a Div Block and give it a class (e.g.,
Main Container). - Set the
Main Containerpadding to8rem(top/bottom) and6rem(left/right). Set theMax Widthto90rem. - Add a Div Block inside the container to serve as the
Section Content Wrapper.
- Why: This establishes a clean base structure that ensures content is centered and breathing room is maintained on large screens.
Step 2: Configure the Semantic List (The Grid)
Timestamp Reference: 04:14 - 05:15
- How:
- Add a List element inside the wrapper and apply the class
Gallery List. - Set the Display property to
Flex. - Set the Gap to
0.5remand remove default padding (Left/Bottom to0). - In the Element Settings panel, select "No Bullets".
- Why: Using an unordered list (
<ul>) provides semantic meaning, telling screen readers that the images are a connected sequence of items rather than unrelated elements,. Flexbox provides the calculation engine for the grid.
Step 3: Define Item Sizing and Image Properties
Timestamp Reference: 05:24 - 06:51
- How:
- Delete all but one list item. Give the remaining item the class
Gallery Item. - Set the Height to
36vh(36% of viewport height). - Place an Image element inside the item. Give it the class
Gallery Item Image. - Set the Image Width and Height to
100%.
- Why: Setting height in
vhunits creates a row height relative to the user's screen size. Setting image dimensions to 100% ensures the image completely fills its parent container.
Step 4: Enable Flex Wrapping and Growth Logic
Timestamp Reference: 07:03 - 09:13
- How:
- Select the
Gallery Listand set Flex Wrap toWrap. - Select the
Gallery Itemand set Flex Grow to1and Flex Shrink to1. - Select the
Gallery Item Imageand set Object Fit toCover.
- Why:
- Wrap: Allows items to stack into multiple rows.
- Grow/Shrink: Forces items to expand dynamically to fill the available width of the row, creating the masonry effect.
- Object Fit: Prevents the images from stretching or squashing as the parent container changes shape, preserving the original aspect ratio.
Step 5: Handle the Final Row (The Empty Spacer)
Timestamp Reference: 09:38 - 10:40
- How:
- Add a new, empty List Item to the end of the list.
- Apply the
Gallery Itemclass and a combo classcc-last. - Set Flex Shrink to
0and Flex Grow to10.
- Why: Without this, the final image in the last row will expand to fill the entire row width, which often looks awkward. This "phantom" spacer consumes the excess space.
Step 6: Ensure Accessibility for the Spacer
Timestamp Reference: 10:43 - 11:30
- How:
- Select the empty list item (
cc-last). - Add a custom attribute:
aria-hidden="true".
- Why: An empty list item can confuse screen readers, which might announce "Item" with no content. This attribute instructs assistive technology to ignore the element entirely.
Step 7: Adjust for Responsiveness
Timestamp Reference: 11:35 - 12:39
- How:
- Tablet: Change
Gallery Itemheight to28vh. - Mobile Landscape: Change Width to
28vwand Height toAuto. - Mobile Portrait: Change Width to
Auto, Height to45vh, and set the empty spacer item to Display: Hidden.
- Why:
- Tablet:
36vhis often too tall for tablet aspect ratios. - Mobile Landscape: The viewport is short but wide, so switching to
vw(viewport width) units maintains better proportions. - Mobile Portrait: Images act as a standard vertical stack; the spacer is no longer needed to fill gaps.
- Tablet:
Step 8: Integrate with CMS (Optional)
Timestamp Reference: 15:00 - 15:58
- How:
- Connect a Collection List and apply the
Gallery Listclass to the wrapper. - Include an empty item in your CMS collection (no image set).
- Select the List Item element in the Designer.
- In the Selector field, choose "Last Item".
- Apply the spacer logic (Grow: 10, Shrink: 0) to this pseudo-selector.
- Why: This allows you to apply the "phantom spacer" technique dynamically without manually adding a static div to a dynamic list.
Step 9: Manage CMS Accessibility
Timestamp Reference: 16:20 - 17:24
- How:
- In your CMS Collection settings, add a text field named
Aria Hidden. - Set the value to
truefor the empty spacer item andfalsefor all other items. - In the Designer, select the Collection Item.
- Add the custom attribute
aria-hiddenand bind its value to the CMS field.
- Why: This programmatically hides only the empty spacer from screen readers while keeping legitimate content accessible.
Step 10: Add Staggered Animation (Optional)
Timestamp Reference: 17:36 - 18:21
- How:
- Add the GSAP library code to your project (referenced in video description).
- Select the
Gallery List. - Add the custom attribute
fc-gsap-staggered="list".
- Why: This applies a pre-configured animation script that makes images slide and fade in sequentially as the user scrolls.
FAQs
How to build a responsive horizontal masonry layout in Webflow?
To create this layout without code, apply display: flex with flex-wrap: wrap to an unordered list container. Set the child list items to grow: 1 and shrink: 1 with a fixed viewport height (e.g., 36vh), allowing them to dynamically resize and fill rows while respecting the container's width.
How to prevent the last Flexbox item from stretching to fill the row?
Insert an empty list item at the end of your list and apply a grow value of 10 and a shrink value of 0. This "phantom" element forces the empty space to be consumed by the invisible item, preventing the final image from expanding awkwardly to fill the remaining row width.
How to preserve image aspect ratios in a flexible grid layout?
Set the image width and height to 100% to ensure they fill their parent container, then apply the object-fit: cover property within the Style panel. This ensures that even as the parent flex item expands or shrinks to fit the row, the image maintains its original proportions without distortion.
How to make a Webflow CMS gallery accessible to screen readers?
Structure your gallery using an unordered list (<ul>) to communicate connected content, and use the "Last Item" selector to target any layout spacers. Bind the aria-hidden attribute to a custom CMS text field, setting the value to "true" specifically for empty spacer items so assistive technology ignores them.