Pop removed items out

Pull a removed item out of layout so neighbours move as it fades.

Emil Kowalski@emilkowalski
Notice how in the correct example chips move instantly to their new position when a chip is removed. That's because of the `popLayout` mode on AnimatePresence in motion/react which creates a smoother, faster transition when removing an element.

Shown in Demo 1: the same chips, sync next to popLayout. Demo 2 deletes them fast from a tag input.

Jan 12, 2026View on X ↗

From emil-design-eng; pane 3 is Una Kravets’ View Transitions reply.

Remove a chip

Remove a chip in each pane, then raise the duration.

mode="sync"Bad
    +180ms
    mode="popLayout"Good
      +0ms
      View TransitionsNative
        +0ms

        <ul className="relative flex flex-wrap gap-2">
          <AnimatePresence mode="popLayout" initial={false}>
            {chips.map((chip) => (
              <motion.li
                key={chip}
                layout
                initial={{ opacity: 0, scale: 0.95 }}
                animate={{ opacity: 1, scale: 1 }}
                exit={{ opacity: 0, scale: 0.95, transition: { duration: 0.18 } }}
                transition={{ duration: 0.25, ease: [0.23, 1, 0.32, 1] }}
              >
                {chip} <button onClick={() => remove(chip)}>×</button>
              </motion.li>
            ))}
          </AnimatePresence>
        </ul>
        chip.style.viewTransitionName = `chip-${id}`;
        document.startViewTransition(() => chip.remove());
        
        ::view-transition-group(*) {
          animation-duration: 250ms;
          animation-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
        }

        Delete fast in a tag input

        Add a tag with Enter, then hold Backspace.

        mode="sync"Bad
          –
          mode="popLayout"Good
            –

            Why it matters, pros and cons

            Why it matters

            In sync mode the leaving item holds its slot, so the list freezes, then jumps.

            Pros

            • Neighbours move on the click's frame.
            • Rapid removals overlap instead of queueing.
            • Same durations, less waiting.

            Cons

            • Parent needs a position; custom children must forward refs.
            • The exit can overlap the incoming neighbour.
            • For a swap in one slot, use mode="wait".