<main>
<article>
<header>
<h1>Cats</h1>
<i>felis catus</i>
<img src='https://assets.codepen.io/5928893/cat--resized.png' alt="cat" width="200" height="200" />
</header>
<div class="divider"></div>
<p>
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
</p>
<p>
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.
</p>
<p>
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.
</p>
</article>
</main>
<div id="nyan-cat" class="elevation-1" popover>
<picture>
<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">
</picture>
<div class="popup-text">Nyan Cat</div>
</div>
<div id="postman" class="elevation-1" popover>
<picture>
<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">
</picture>
<div class="popup-text">Postman</div>
</div>
<div id="internet" class="elevation-1" popover>
<picture>
<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">
</picture>
<div class="popup-text">Internet</div>
</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 {
*,
*:after,
*: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 {
top,
bottom,
left,
right,
width,
height
} = 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();
};
HOVER_TRIGGERS.forEach((TRIGGER) => {
const POPUP = document.querySelector(
`#${TRIGGER.getAttribute("data-popoverhovertarget")}`
);
const SHOW_POP = SHOW(TRIGGER, POPUP);
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);