Advertisement

Fluid Morphing List Expansion

| by Vladimir | 2 min read | code by GSAP
Advanced

Tech & Dependencies

HTML CSS JavaScript
gsap flip-plugin

Features

  • Layout Morphing
  • FLIP Animation
  • State Management
  • Flexbox Transition

Browser Support

Chrome 60+ Edge 79+ Firefox 60+ Safari 11+

Core

Most interfaces treat layout changes as abrupt cuts in a film — jarring and disconnected. We reject this. UI should behave like matter, conserving momentum and mass. This component demonstrates the “impossible”: animating a flexbox container from a horizontal row to a vertical column seamlessly. It creates a sense of spatial continuity that makes the application feel not like software, but like a living organism adapting to user intent.

Core Technique

Animating width or height is expensive. Animating flex-direction is impossible with pure CSS. We solve this using the FLIP (First, Last, Invert, Play) technique, mastered here by the GSAP Flip plugin.

  1. Capture State: We record the geometry of every element in the row layout (Flip.getState).
  2. Instant Mutation: We immediately apply the expanded class, forcing the browser to recalculate the layout as a column.
  3. The Illusion: GSAP calculates the difference between the two states and instantly applies transform offsets to make elements appear to be in their old positions, then smoothly animates the transforms to zero.
  4. Absolute Positioning: Critical to this effect is absolute: true, which takes elements out of the document flow during the transition to prevent layout collision.

Customization

The beauty of Flip is its configurability. You can orchestrate the chaos of layout changes into a symphony.

Controlling the Flow

Flip.from(state, {
  duration: 0.6, // Slower for more drama
  ease: "power2.inOut",
  absolute: true, 
  
  // Handle elements entering the DOM (the hidden content)
  onEnter: elements => {
    gsap.fromTo(elements, 
      { opacity: 0, y: 10 }, 
      { opacity: 1, y: 0, duration: 0.3, delay: 0.3 }
    );
  },

  // Handle elements leaving (when closing)
  onLeave: elements => {
    gsap.to(elements, { opacity: 0, duration: 0.2 });
  }
});

Browser Support

Since this relies on JavaScript transformations rather than experimental CSS properties, support is rock solid across the board.

Advertisement