RSS FeedTwitterMastodonBlueskyShare IconHeart IconGithub IconArrow IconClock IconGUI Challenges IconHome IconNote IconBlog IconCSS IconJS IconHTML IconMedia IconGit IconSpeaking IconTools Icon
Text emphasized alt text example
My google avatar.

Steal this popover code

4 min read
csshtml

Popovers are pretty rad, as are dialogs, but animating them isn't easy.

  1. the browser toggles display
  2. the elements enter and exit the top layer
    (aka: the DOM penthouse)

Popovers are basically being appended or removed, and display is toggled between block and none.


Ew, how do we deal with that?

Steal this basic setup #

This next section is optimized for you to steal, but you can also just peep the Codepen and take it from there.

HTML #

Button that opens the popover:

<button popovertarget="my-tooltip">?</button>

The [popover]:

<p id="my-tooltip" popover>tip</p>

CSS #

This is a bit tricky. At least I think so.

[popover] {
  &, &::backdrop {
    transition: 
      display .5s allow-discrete, 
      overlay .5s allow-discrete, 
      opacity .5s;
    opacity: 0;
  }

  &::backdrop {
    background: black;
  }

  &:popover-open {
    opacity: 1;

    &::backdrop {
      opacity: 0.5;
    }
  }

  @starting-style {
    &:popover-open,
    &:popover-open::backdrop {
      opacity: 0;
    }
  }
}

CSS snippet explained #

This isn't a deep dive, find a good one from Una here, but is a 2m overview.

Transition setup #

  1. sets any popover and their backdrops to 0 opacity
  2. sets up a transition for that opacity
  3. with a matching duration to opacity, display and overlay use a new keyword allow-discrete that signals these properties toggle any new values after the duration has run
[popover] {
  &, &::backdrop {
    transition: 
      display .5s allow-discrete, 
      overlay .5s allow-discrete, 
      opacity .5s;
    opacity: 0;
  }
}

Display and entering/exiting the top-layer will now only change after opacity has finished fading

Popover showing #

  1. sets any popover to opacity 1 when :popover-open
  2. sets the backdrop to half opacity
[popover] {
  &:popover-open {
    opacity: 1;

    &::backdrop {
      opacity: 0.5;
    }
  }
}

Entry animation prep #

Since popovers enter the top layer, and we're using transitions, we need a way to tell the browser what styles to start the transition from. Enter @starting-style

  1. When the popover is opened
  2. Start the backdrop and popover with opacity 0
[popover] {
  @starting-style {
    &:popover-open,
    &:popover-open::backdrop {
      opacity: 0;
    }
  }
}

This will then transition from the starting style, to the popover showing styles.

JS #

Nothing to see here.

Try it #

Mentions #

Join the conversation on

33 likes
9 reposts
  • 7 Juicy Herbs For Inner Nourishment
  • Jeroen Zwartepoorte
  • Thomas Broyer
  • Vadim Makeev
  • Steven Fail / imgradeone
  • Apple Annie :prami:
  • Bramus
  • Giana ✨
  • Seb Adler ???? Seoseb

@argyleink Thank you! I have wanted to build exactly this but I had a hard time understanding the documentation for starting-style and eventually just decided to wait for better guides and better browser support.

Anton ????????????????Anton ????????????????

@argyleink I think I might pop over later and steal this code, Adam.

Matthias OttMatthias Ott

@argyleink love this!
and +1 for the SOAD reference

Max BöckMax Böck

@argyleink AND:
✅ no JS!

Incredible. It’d be nice to make a lightbox similar to this with no JS.

Luke DornyLuke Dorny

@argyleink are you using something for the h2s that's not supported in Firefox?

I'm seeing h2 colliding with text

Liminal witch ????‍♀️ SarahLiminal witch ????‍♀️ Sarah

@xgebi thanks for reporting!

I checked in Firefox developer edition and it wasnt broken (screenshot attached), so I decided to leave it and wait for the browser to resolve it itself

Adam ArgyleAdam Argyle

@argyleink I love the absence of JS code <3

Seb Adler ???? SeosebSeb Adler ???? Seoseb

@argyleink @jensimmons Just noticed that in STP, the 2nd time you open the popover, the "tip" text is missing. Looks like a bug.

Jeroen ZwartepoorteJeroen Zwartepoorte

Crawl the CSS Webring?

previous sitenext site
a random site