Skip to content
Theme:

Popover element entry and exit animations in a few lines of CSS

Creating entry and exit animations for elements has always been tedious. It typically involves defining entry and exit @keyframes, some classList dance, timeout management, listening for transitionend/animationend events, etc. I have written code like that many times. Boring!

Nowadays, we can do it with just a few lines of pure CSS, without a single line of JS. The snippet below uses a few modern Web featues: popover element, CSS nesting, transitioninig properties with discrete animation behaviour and @starting-style. It’s packed with many goodies for such a tiny snippet, isn’t it?

<button popovertarget="pop">Open popover</button>
<div popover id="pop">If this isn't cool, I don't know what is!</div>
[popover] {
  transition: opacity 0.2s, transform 0.2s, display 0.2s allow-discrete;

  opacity: 0;
  transform: translateY(3rem);

  &:popover-open {
    opacity: 1;
    transform: none;

    @starting-style {
      & {
        opacity: 0;
        transform: translateY(-1rem);
      }
    }
  }
}

See the Pen Popover animation toggle in/out by Pawel Grzybek (@pawelgrzybek) on CodePen.

Baseline: @starting-style is newly available

  • Google Chrome 117 2023.09.12
  • Microsoft Edge 117 2023.09.15
  • Firefox 129 2024.08.06
  • Safari 17.5 2024.05.13

Everything I presented here I learned from “Using @starting-style and transition-behavior for enter and exit stage effects” by Adam Argyle and “Four new CSS features for smooth entry and exit animations” by Una Kravets and Joey Arhar. Thanks, web folks for sharing knowledge 🫶

Comments

  • j
    josh

    This is awesome, but unfortunately it only works in Chrome for now.

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Paweł Grzybek
      Paweł Grzybek

      for now

      😉

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • S
    Siroj Turgunboyev

    Great!

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • C
    Css Tester

    Hi,

    I read your article and I was wondering if I can show the popover only on mobile. It does work with display: block and position: static, which I apply on mobile using a media query. But if I resize my inspector from small to large, it stays fixed. Do you know a solution for this?

    To put it simply, I’d like it to be fixed on mobile and static on desktop. However, when it’s open and I switch views, it should go back to fixed or unset. Let me know if you have any ideas!

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • P
      Pawel Grzybek

      A little CodePen example would be so so helpful. I don’t see a reason why the scenario you described should be impossible. Please craft a minimal reproducible example on CodePen.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
      • C
        Css Tester

        Thank you for your response. I’ve tried to recreate my situation as accurately as possible. Apologies for the complexity.

        https://codepen.io/92b420/details/yLmjpdR

        👆 you can use Markdown here

        Your comment is awaiting moderation. Thanks!
        • Pawel Grzybek
          Pawel Grzybek

          I see your issue now and I also understand your intention. I can explain what is going on. When the dialog or popover is open, browsers draws these elements on a separated layer. Google Chrome dev tools nicely show a "top layer" label on open dialogs and popovers. I am afraid in your case, you need a little bit of JS to make sure that your popover is closed when it hits particular breakpoint. This is not the most optimal but definitely a working solution you can use as a base for the solution of your problem.

          const popover = document.getElementById("filter-popover");
          const mq = '(min-width: 768px)'
          
          window.addEventListener('resize', () => {
            if(window.matchMedia(mq).matches) {
              popover.hidePopover()
            }
          })
          

          Also MDN has a great resource that explains the concept of top layer. Have a look. I hope that helped.

          https://developer.mozilla.org/en-US/docs/Glossary/Top_layer

          👆 you can use Markdown here

          Your comment is awaiting moderation. Thanks!
          • C
            Css tester

            Thank you for your response. I had already fixed it myself with JavaScript. I'm hoping for a pure css fix.. looks like it's not possible.

            👆 you can use Markdown here

            Your comment is awaiting moderation. Thanks!

Leave a comment

👆 you can use Markdown here

Your comment is awaiting moderation. Thanks!