<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()

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.