<i>felis catus</i>
      <img src='https://assets.codepen.io/5928893/cat--resized.png' alt="cat" width="200" height="200" />
    <div class="divider"></div>
      Be a <a href="#" data-popoverhovertarget="nyan-cat">nyan cat</a>, feel great about it, be annoying 24/7 poop rainbows in litter box all day climb into cupboard and lick the salt off rice cakes scratch at the door then walk away
      Mice attack curtains love you, then bite you try to hold own back foot to clean it but foot reflexively kicks you in face, go into a rage and bite own foot, hard cat mojo hide head under blanket so no one can see. Stare at ceiling scratch leg; meow for can opener to feed me bite off human's toes but lick human with sandpaper tongue and break lamps and curl up into a ball but scratch the <a href="#" data-popoverhovertarget="postman">postman</a> wake up lick paw wake up owner meow meow, so sun bathe.
      Kitty loves pigs bite plants, cattt catt cattty cat being a cat purr for no reason get video posted to <a href="#" data-popoverhovertarget="internet">internet</a> for chasing red dot for eat an easter feather as if it were a bird then burp victoriously, but tender. And sometimes switches in french and say "miaou" just because well why not. Twitch tail in permanent irritation.
<div id="nyan-cat" class="elevation-1" popover>
    <source media="(prefers-reduced-motion: no-preference)" srcset="https://assets.codepen.io/5928893/nyan-cat.webp" />
    <source media="(prefers-reduced-motion: no-preference)" srcset="https://assets.codepen.io/5928893/nyan-cat.gif" />
    <img src="https://assets.codepen.io/5928893/nyan-cat.png" alt="nyan cat" width="150">
  <div class="popup-text">Nyan Cat</div>
<div id="postman" class="elevation-1" popover>
    <source media="(prefers-reduced-motion: no-preference)" srcset="https://assets.codepen.io/5928893/postman.webp" />
    <source media="(prefers-reduced-motion: no-preference)" srcset="https://assets.codepen.io/5928893/postman.gif" />
    <img src="https://assets.codepen.io/5928893/postman.png" alt="Postman Pat" width="150">
  <div class="popup-text">Postman</div>
<div id="internet" class="elevation-1" popover>
    <source media="(prefers-reduced-motion: no-preference)" srcset="https://assets.codepen.io/5928893/internet.webp" />
    <source media="(prefers-reduced-motion: no-preference)" srcset="https://assets.codepen.io/5928893/internet.gif" />
    <img src="https://assets.codepen.io/5928893/internet.png" alt="Cat using keyboard" width="150">
  <div class="popup-text">Internet</div>
@layer demo {
  [popover] {
    top: calc(var(--bottom) * 1px);
    background: var(--surface-2);
    margin: 0;
    border: 0;
    padding: 0;
    overflow: hidden;
    border-radius: var(--radius-2);
    transition: opacity 0.2s, transform 0.2s;
    opacity: var(--open, 0);
    box-shadow: var(--shadow-4);
    transform: translateX(calc(var(--width) * var(--offset)))
      translateY(calc((1 - var(--open, 0)) * 5%));

  .popup-text {
    padding: var(--size-4);
    font-weight: var(--font-weight-6);

  [popover]:open {
    --open: 1;

  [popover].left {
    --offset: -0.25px;
    left: calc(var(--right) * 1px);
  [popover].right {
    --offset: -0.75px;
    left: calc(var(--left) * 1px);

  a {
    color: var(--indigo-4);

@layer base {
  *:before {
    box-sizing: border-box;

  body {
    display: grid;
    place-items: center;
    min-height: 100vh;
    overflow: auto;
    font-family: "Google Sans", sans-serif, system-ui;

  :where([popover]) {
    margin: auto;
    border-width: initial;
    border-style: solid;

  span {
    display: inline-block;
    translate: 0 60%;

  header {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-rows: 1fr 1fr;
    align-content: center;
    justify-content: center;

  header img {
    grid-column: 2;
    grid-row: 1 / -1;
    object-fit: cover;
    height: 100%;

  article > * + * {
    margin-top: var(--size-4);

  h1 {
    margin: 0;
    align-self: end;

  article {
    padding: var(--size-4);
    padding-bottom: var(--size-12);

  .divider {
    background: var(--text-2);
const HOVER_TRIGGERS = document.querySelectorAll("[data-popoverhovertarget]");

const SHOW = (trigger, tooltip) => () => {
  const {
  } = trigger.getBoundingClientRect();
  tooltip.style.setProperty("--top", top);
  tooltip.style.setProperty("--right", right);
  tooltip.style.setProperty("--bottom", bottom);
  tooltip.style.setProperty("--left", left);
  tooltip.style.setProperty("--width", width);
  tooltip.style.setProperty("--height", height);

  tooltip.className = left > window.innerWidth * 0.5 ? "right" : "left";

  if (!tooltip.matches(":open")) tooltip.showPopover();

  const POPUP = document.querySelector(
  TRIGGER.addEventListener("pointerenter", SHOW_POP);
  TRIGGER.addEventListener("focus", SHOW_POP);

const closePopUps = () =>
  document.querySelectorAll("[popover]").forEach((pop) => {
    if (pop.matches(":open")) pop.hidePopover();
window.addEventListener("resize", closePopUps);

External CSS

  1. https://codepen.io/web-dot-dev/pen/XWqWYgB.css
  2. https://codepen.io/web-dot-dev/pen/ZExZWBQ.css

External JavaScript

  1. https://codepen.io/web-dot-dev/pen/XWqWYgB.js
  2. https://codepen.io/web-dot-dev/pen/ZExZWBQ.js