Skip to the content

Focus grid

A grid of pictures, written as plain markup: a box, one child per cell, a picture in each, a caption if you want one, any number of cells and pictures of any proportions.

Become a member to unlock the full effect today.

Join now

Already a member? Sign in

Documentation

  1. Copy to Webflow

    Add Geist and Geist Mono to your site's fonts (Site settings, Fonts, Google Fonts) before pasting: Webflow removes any font your site has not installed.

  2. Add custom CSS

    Give the box a grid of its own: display: grid, its columns and its gaps, at every breakpoint you want, and a height, or cells that give it one. The Embed takes the tracks over from there and reads four variables, --focus-grid-accent (the keyboard ring), --focus-grid-dim (how far the pictures out of focus fall back), --focus-grid-scrim (the shade under a caption) and --focus-grid-fade: set them on the box in a rule of your own. Leave the transform of a picture to the engine.
  3. Add custom JS

  4. Use it on your own elements

    Custom attributes
    Select the element on the canvas and open the Settings panel. Under Custom attributes, add a pair: the name on the left, the value on the right.
    Custom attributeWhat it does
    data-focus-grid Marks the box whose direct children are the cells. It takes no value: leave the value field empty. That box is the grid: it must be a grid in the Designer, with its columns and gaps, and it keeps the height the page gave it. The settings below go on the same element.
    data-focus-grid-caption On the caption of a cell. It takes no value. A marked caption is shown only on the cell in focus, rising from its foot; it stays in the page for screen readers. A figcaption needs no mark, and a cell with no caption is fine. [ Optional ]
    data-focus-grid-picture On the picture of a cell, only when it is not the first image or video in it. It takes no value. Without it the engine takes the first img or video of each cell. [ Optional ]
    data-focus-grid-state Written by the engine on the box: ready once mounted, measure for the instant it reads the page again. The cell in focus carries data-focus-grid-active, the box data-focus-grid-lit while a cell is in focus, and every cell data-focus-grid-cell. Never written by hand; the stylesheet reads them, and so can a rule of yours. [ Optional ]
    Settings
    Every setting is a custom attribute too, added the same way and on the same element. An attribute always wins over the defaults written in the code.
    AttributeDefaultWhat it is
    data-focus-grid-start 0 The cell in focus when nobody is on the grid, counted from 1: the grid opens on it and comes back to it when the pointer leaves.
    data-focus-grid-grow 2.2 Size of the column and of the row of the cell in focus, against a track at rest.
    data-focus-grid-give 0.3 How much the tracks right next to the focus shrink, 0 to 1; the next ones give half of that, then a third.
    data-focus-grid-reveal 0.6 How still a picture stays while its cell changes size, 0 to 1.
    data-focus-grid-settle 1.2 Time the grid takes to come to rest after a change of focus, in seconds.
    data-focus-grid-bounce 0.3 Overshoot of the springs, 0 to 1: how far the tracks go past their place before coming back.

What it does

Focus grid is a cursor animation for Webflow and vanilla JavaScript, with no library. Also called expanding image grid on hover, grid hover expand effect or image grid hover effect.

A grid of pictures, written as plain markup: a box, one child per cell, a picture in each, a caption if you want one, any number of cells and pictures of any proportions. The cell under the pointer takes room, and it takes it from the whole grid: its column widens from top to bottom, its row grows taller from side to side, the nearest tracks give way the most and the far ones hardly move, so the grid stays one full rectangle with the same gaps and nothing ever covers anything. Every track runs on a damped spring, the far ones a little late, which reads as one slow move of matter with a soft overshoot at the end. A picture is never stretched: it is held by its middle at the size of its cell in focus, so a cell that opens shows more of the picture and a cell that closes crops it. The pictures out of focus fall back and the caption of the cell in focus rises from its foot. Each cell stays a real link. The keyboard does what the pointer does: Tab from cell to cell, the arrows across the grid, Enter to open, Escape to let go. On a touch screen, where nothing hovers, a tap brings a cell into focus and a second tap opens it, and a finger that slides sideways carries the focus from cell to cell while the page still scrolls up and down. The number of columns is the page's own CSS, breakpoints included; a short last row is closed by its last cell. Without JavaScript the grid is a plain grid with every caption in sight. Reduced motion respected. No library. Pattern type expanding image grid, hover gallery, focus gallery.

Updated

Questions

Put the custom attribute data-focus-grid on the grid whose direct children are the cells, a Collection List for one, and paste the Embed. The grid keeps the columns and gaps you set in the Designer; the cell under the pointer makes its whole column and row grow, and the others give way.

No, it loads nothing. One damped spring per column and per row writes the tracks of a CSS grid as fr shares at every frame, so the grid stays a full rectangle with the same gaps and no cell ever covers another.

Never. Each picture is drawn once at the size of its cell in focus and held by its middle, so a cell that opens shows more of the picture and a cell that closes crops it. data-focus-grid-reveal goes from 0, the picture follows its cell as a cover would, to 1, the picture does not move at all.

A tap brings a cell into focus and shows its caption, and a tap on the cell already in focus opens its link. A finger that slides sideways carries the focus from cell to cell, while a slide up or down still scrolls the page.

data-focus-grid-start="6" keeps the sixth cell in focus whenever nobody is on the grid, so the page opens on a composition. data-focus-grid-grow is the size of the focused column and row against the others, 2.2 by default, and data-focus-grid-settle the time the grid takes to come to rest, 1.2 seconds.