How to recreate Google Search Result Movie Cards

We love looking up movies by genre or the year, what's neat is that Google displays that search result as a list of cards. Each card displays official movie poster then upon hover interaction that card expands its width and changes background image to specific memorable scene from that movie and reveals additional information such as title, rating, and time duration.

The way that Google animated the cards is odd yet simple, motivating me to write this breakdown/tutorial.


Features of Cards

The interactivity of the cards are simple, there's only four features.

  1. Expand card towards the right, neighboring cards to the right of the expanding card shift to the right.
  1. Expand card towards the left, neighboring cards to the left of the expanding card shift to the left.
  1. Subsequent expanding cards will restore original width of previous active expanded card.
  1. Expanding card that's overlapped by scroll container will cause scroll container to change scroll position to align that card to scroll container's edge.

My assumption on how Google animated the Cards

Google is known for optimizing the heck out of everything, afterall they create Chrome just to run JavaScript faster. So my expectation was that they would animate the cards with CSS composite only properties i.e. transform. This would allow the browser to skip doing expensive layout and painting caculations for every frame throughout the entire animation instead just do composite.

The downside of animating with just scale and translate is that you would have to write quite a bit of code to shift all the elements as well as the expanding and collapsing effect. But the performance gains are worth it in my opinion because the animation will run smoothly on low end mobile devices that lack fast CPUs.

So upon inspecting Google's implementation I was shocked they didn't utilize transform, instead they straight up animate the width of the card! When the card's width increases, the neighboring cards get pushed to the right. There's more logic on what determines which neighboring cards get pushed, but let's jump into the breakdown and diagrams first.

We're going to recreate the card list using SolidJS and a bit of CSS transition magic.

Missing features from Google

  • Allow scrolling to the left to see first card after fakeCard collapses.
  • Show right arrow indicator when scrolled at rightmost end then user expands card towards the right.

Minor improvments

  • When scrolling via buttons, if card is overlapped, scrolls at container distance, resulting in new card to be overlapped. Mine scrolls at container distance plus amount that card overlapped, resulting that new card is aligned

Missing features from Google

  • Allow scrolling to the left to see first card after fakeCard collapses.
  • Show right arrow indicator when scrolled at rightmost end then user expands card towards the right.

Minor improvments

  • When scrolling via buttons, if card is overlapped, scrolls at container distance, resulting in new card to be overlapped. Mine scrolls at container distance plus amount that card overlapped, resulting that new card is aligned