Skip to main content

Animate to and from display none with Framer Motion

To animate to and from display none using Framer Motion, will make use of variants. We set our two states, hidden and shown.

Within our hidden variant, will set the property onanimationend to display none. This will animate our menu from opacity 1, scale 1, and display block, to opacity 1 and scale 0, then once that animation is complete, will then apply display none.

const variants = {
  hidden: {
    opacity: 0,
    scale: 0,
    onanimationend: {
      display: "none",
    },
  },
  shown: {
    opacity: 1,
    scale: 1,
    display: "block",
  },
};
const variants = {
  hidden: {
    opacity: 0,
    scale: 0,
    onanimationend: {
      display: "none",
    },
  },
  shown: {
    opacity: 1,
    scale: 1,
    display: "block",
  },
};

And to implement this within our menu component, will pass the variants to our motion.ul, and animate between hidden and shown variants.

export default function Menu() {
  const [variant, setVariant] = React.useState("hidden");
  return (
    <>
      <button
        onClick={() =>
          setVariant((prevVariant) =>
            prevVariant === "hidden" ? "shown" : "hidden"
          )
        }
      >
        Toggle dropdown
      </button>
      <motion.ul variants={variants} initial="hidden" animate={variant}>
        <li>
          <button>Option 1</button>
        </li>
        <li>
          <button>Option 2</button>
        </li>
        <li>
          <button>Option 3</button>
        </li>
      </motion.ul>
    </>
  );
}
export default function Menu() {
  const [variant, setVariant] = React.useState("hidden");
  return (
    <>
      <button
        onClick={() =>
          setVariant((prevVariant) =>
            prevVariant === "hidden" ? "shown" : "hidden"
          )
        }
      >
        Toggle dropdown
      </button>
      <motion.ul variants={variants} initial="hidden" animate={variant}>
        <li>
          <button>Option 1</button>
        </li>
        <li>
          <button>Option 2</button>
        </li>
        <li>
          <button>Option 3</button>
        </li>
      </motion.ul>
    </>
  );
}

View Codesandbox