<script type="module" src="https://unpkg.com/@auroratide/flip-card/lib/define.js"></script>
<section class="card-demos">
<article class="flip-demo">
<h2>Bland Flip</h2>
<div class="card regular-card">
<div class="flip-container">
<section class="front face" aria-hidden="false">
<figure>
<figcaption><strong>Pichu #172</strong></figcaption>
<img src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/172.png" alt="Tiny yellow mouselike creature" />
</figure>
</section>
<section class="back face" aria-hidden="true">
<header>
<p><strong>Pichu</strong></p>
<p class="type-tag electric">Electric</p>
</header>
<dl>
<dt>HP</dt>
<dd>20</dd>
<dd><div class="hp" role="meter" aria-valuenow="20" aria-valuemin="0" aria-valuemax="255" aria-label="HP" style="--value: 20;"></div></dd>
<dt>Atk</dt>
<dd>40</dd>
<dd><div class="atk" role="meter" aria-valuenow="40" aria-valuemin="0" aria-valuemax="255" aria-label="Attack" style="--value: 40;"></div></dd>
<dt>Def</dt>
<dd>15</dd>
<dd><div class="def" role="meter" aria-valuenow="15" aria-valuemin="0" aria-valuemax="255" aria-label="Defense" style="--value: 15;"></div></dd>
<dt>Sp.Atk</dt>
<dd>35</dd>
<dd><div class="spatk" role="meter" aria-valuenow="35" aria-valuemin="0" aria-valuemax="255" aria-label="Special Attack" style="--value: 35;"></div></dd>
<dt>Sp.Def</dt>
<dd>35</dd>
<dd><div class="spdef" role="meter" aria-valuenow="35" aria-valuemin="0" aria-valuemax="255" aria-label="Special Defense" style="--value: 35;"></div></dd>
<dt>Spd</dt>
<dd>60</dd>
<dd><div class="spd" role="meter" aria-valuenow="60" aria-valuemin="0" aria-valuemax="255" aria-label="Speed" style="--value: 60;"></div></dd>
</dl>
<footer>
<p>The Tiny Mouse Pokémon. It still can’t use electricity well. When it’s surprised or excited, it discharges electricity unintentionally.</p>
</footer>
</section>
</div>
</div>
<button>Flip Pichu</button>
</article>
<article class="flip-demo">
<h2>Cool Flip</h2>
<flip-card class="card">
<section slot="front" class="front">
<figure>
<figcaption><strong>Raichu #026</strong></figcaption>
<img src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/26.png" alt="Large orange mouselike creature" />
</figure>
</section>
<section slot="back" class="back">
<header>
<p><strong>Raichu</strong></p>
<p class="type-tag electric">Electric</p>
</header>
<dl>
<dt>HP</dt>
<dd>60</dd>
<dd><div class="hp" role="meter" aria-valuenow="60" aria-valuemin="0" aria-valuemax="255" aria-label="HP" style="--value: 60;"></div></dd>
<dt>Atk</dt>
<dd>90</dd>
<dd><div class="atk" role="meter" aria-valuenow="90" aria-valuemin="0" aria-valuemax="255" aria-label="Attack" style="--value: 90;"></div></dd>
<dt>Def</dt>
<dd>55</dd>
<dd><div class="def" role="meter" aria-valuenow="55" aria-valuemin="0" aria-valuemax="255" aria-label="Defense" style="--value: 55;"></div></dd>
<dt>Sp.Atk</dt>
<dd>90</dd>
<dd><div class="spatk" role="meter" aria-valuenow="90" aria-valuemin="0" aria-valuemax="255" aria-label="Special Attack" style="--value: 90;"></div></dd>
<dt>Sp.Def</dt>
<dd>80</dd>
<dd><div class="spdef" role="meter" aria-valuenow="80" aria-valuemin="0" aria-valuemax="255" aria-label="Special Defense" style="--value: 80;"></div></dd>
<dt>Spd</dt>
<dd>110</dd>
<dd><div class="spd" role="meter" aria-valuenow="110" aria-valuemin="0" aria-valuemax="255" aria-label="Speed" style="--value: 110;"></div></dd>
</dl>
<footer>
<p>The Mouse Pokémon. When electricity builds up inside its body, it becomes feisty. It also glows in the dark.</p>
</footer>
</section>
</flip-card>
<button>Flip Raichu</button>
</article>
</section>
/**
* TYPICAL CARD FLIP CSS
*/
.regular-card {
position: relative;
perspective: 100em;
}
.regular-card .flip-container {
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 0.75s ease-in-out;
}
.regular-card.flipped .flip-container {
transform: rotateY(-180deg);
}
.regular-card .face {
backface-visibility: hidden;
}
.regular-card .back {
position: absolute;
inset: 0;
transform: rotateY(180deg);
}
/**
* SPECIAL CARD FLIP CSS
*/
flip-card {
--card-depth: 0.333em;
--flip-height: 17.5em;
}
flip-card::part(edge) {
background-color: var(--blue);
}
flip-card:not(:defined) > [slot="back"] {
display: none;
}
/**
* BASE DEMO CSS
*/
:root {
--blue: oklch(51% 0.129 259);
--white: oklch(100% 0 0);
--yellow: oklch(86% 0.18 89);
--grey: oklch(32% 0 0);
--electric: oklch(66% 0.137 91);
}
*, *::before, *::after {
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
background: radial-gradient(circle at 5vw 70vh, hsl(321 86% 91% / 0.5), hsl(321 86% 91% / 0) 67%),
radial-gradient(circle at 50vw 5vh, hsl(120 50% 75% / 0.25), hsl(120 50% 75% / 0) 67%),
radial-gradient(circle at 80vw 95vh, hsl(45 80% 65% / 0.25), hsl(45 50% 65% / 0) 67%);
background-size: 100vw 100vh;
background-size: 100dvw 100dvh;
background-repeat: no-repeat;
}
.card {
width: 100%;
max-width: 15em;
aspect-ratio: 5 / 7;
border-radius: 0.75em;
}
.card p { margin: 0; }
.card section {
width: 100%;
height: 100%;
border: 0.5em solid var(--blue);
box-shadow: 0 0 0.15em 0.1em oklch(0% 0 0 / 0.75) inset;
border-radius: 0.75em;
background: radial-gradient(var(--white) 25%, var(--yellow));
}
.front figure {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 0;
padding-block: 1em;
}
.front figcaption {
font-size: 1.333em;
flex: 1;
display: flex;
align-items: center;
}
.front img {
flex: 6;
display: block;
width: 80%;
margin: 0 auto;
object-fit: contain;
}
.back {
padding: 1em 0.5em;
}
.back header {
display: flex;
align-items: center;
}
.back header > :first-child {
flex: 1;
}
.type-tag {
color: white;
font-size: 85%;
font-weight: bold;
text-align: center;
line-height: 1;
padding: 0.25em 1em;
border-radius: 1em;
}
.type-tag.electric { background-color: var(--electric); }
.back dl {
display: grid;
grid-template-columns: 5.5ch 4ch 1fr;
}
.back dt { font-weight: bold; }
.back dt + dd { text-align: end; }
.back dd { margin: 0; }
.back dd + dd { padding-inline: 0.5em; }
.back [role="meter"] {
height: 90%;
width: calc(100% * (var(--value) / 255));
border: 0.0625em solid;
}
.back footer {
font-size: 0.875em;
line-height: 1.25;
}
[role="meter"].hp {
background-color: oklch(63% 0.258 29);
border-color: oklch(46% 0.187 29);
}
[role="meter"].atk {
background-color: oklch(71% 0.163 52);
border-color: oklch(46% 0.187 29);
}
[role="meter"].def {
background-color: oklch(87% 0.167 94);
border-color: oklch(63% 0.119 94);
}
[role="meter"].spatk {
background-color: oklch(67% 0.15 265);
border-color: oklch(49% 0.105 266);
}
[role="meter"].spdef {
background-color: oklch(76% 0.174 137);
border-color: oklch(55% 0.123 137);
}
[role="meter"].spd {
background-color: oklch(69% 0.198 6);
border-color: oklch(50% 0.14 5);
}
.card-demos {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
gap: 3em;
}
.flip-demo {
display: flex;
flex-direction: column;
align-items: center;
}
.card {
margin-block-end: 1em;
}
button {
font-size: 1.25em;
border: none;
color: var(--white);
background-color: var(--grey);
padding: 0.75em 1.25em;
border-radius: 1.75em;
box-shadow: 0 0.1em 0.5em oklch(0% 0 0 / 0.333);
cursor: pointer;
}
button:hover,
button:focus {
color: var(--grey);
background-color: var(--white);
}
button:active {
box-shadow: none;
}
function flipRegular(elem) {
elem.classList.toggle("flipped")
const isFlipped = elem.classList.contains("flipped")
elem.querySelector(".front").setAttribute("aria-hidden", isFlipped.toString())
elem.querySelector(".back").setAttribute("aria-hidden", (!isFlipped).toString())
}
function flipSpecial(elem) {
elem.flip()
}
function setup() {
document.querySelectorAll(".flip-demo").forEach((demo) => {
const card = demo.querySelector(".card")
const button = demo.querySelector("button")
button.addEventListener("click", () => {
if (card.tagName === "FLIP-CARD") {
flipSpecial(card)
} else {
flipRegular(card)
}
})
})
}
setup()
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.