Skip to content

Flip Card

<quiet-flip-card> stable since 1.0

Flip cards display information on two sides, allowing users to flip between the front and back with the click of a button.

Meowy McGee

Freedom's just another word for nothing left to lose.
Edit
Update
<quiet-flip-card id="flip-card__overview">
  <quiet-card>
    <quiet-avatar image="https://images.unsplash.com/photo-1672487209629-4d52e0c043d0?q=80&w=256&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></quiet-avatar>
    <h3 class="name">Meowy McGee</h3>
    <div class="tagline">Freedom's just another word for nothing left to lose.</div>
    <div class="buttons">
      <quiet-button data-flip-card="toggle">
        <quiet-icon slot="start" name="edit"></quiet-icon>
        Edit
      </quiet-button>
    </div>
  </quiet-card>

  <quiet-card slot="back">
    <form>
      <quiet-text-field label="Name" name="name" value="Meowy McGee"></quiet-text-field>
      <quiet-text-area label="Tagline" name="tagline" value="Freedom's just another word for nothing left to lose."></quiet-text-area>
      <div class="buttons">
        <quiet-button type="submit" variant="primary">
          Update
        </quiet-button>
      </div>
    </form>
  </quiet-card>
</quiet-flip-card>

<script>
  const flipCard = document.getElementById('flip-card__overview');
  const form = flipCard.querySelector('form');
  const nameTextField = form.querySelector('quiet-text-field[name="name"]');
  const tagLineTextArea = form.querySelector('quiet-text-area[name="tagline"]');

  form.addEventListener('submit', event => {
    flipCard.querySelectorAll('.name').forEach(el => el.textContent = nameTextField.value);
    flipCard.querySelectorAll('.tagline').forEach(el => el.textContent = tagLineTextArea.value);
    flipCard.flipped = !flipCard.flipped;
    event.preventDefault();
  });
</script>

<style>
  #flip-card__overview {
    max-width: 20rem;

    /* Front */
    quiet-card:not([slot="back"]) {
      &::part(body) {
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: space-between;
        text-align: center;
        gap: 0.5rem;
      }

      quiet-avatar {
        --size: 5rem;
      }

      .name {
        margin-block: 0;
      }

      .tagline {
        margin-block-end: 1rem;
      }
    }

    /* Back */
    quiet-card[slot="back"] {
      background: var(--quiet-paper-color);

      &::part(body) {
        margin-block: auto;
      }

      form {
        display: flex;
        flex-direction: column;
        gap: 1.5rem;
      }
    }

    .buttons {
      text-align: center;
    }        
  }
</style>

Examples Jump to heading

Flip card basics Jump to heading

Flip cards span the full width of their container, by default. The height is determined by the content you slot in. The flip card will grow to fit the content of the front or back side, whichever is greater.

The most basic flip card requires two child elements. Content in the default slot will be shown on the card's front side and content in the back slot will be shown on the card's back side.

<quiet-flip-card>
  <div>Front content</div>
  <div slot="back">Back content</div>
</quiet-flip-card>

Flip cards work with any content, but they work exceptionally well with cards.

Flipping the card Jump to heading

You can flip a card programmatically by obtaining a reference to it and setting the flipped property to true or false.

const flipCard = document.querySelector('quiet-flip-card');

// Flip the card
flipCard.flipped = true;

// Flip it back
flipCard.flipped = false;

However, it's often more convenient for a button to control the flip card without additional scripting. In this case, you can add the data-flip-card="toggle *" attribute to any button in the document, where * is the target flip card's id. If the button is inside of a flip card, the ID can be omitted.

Front content Back content Toggle
<quiet-flip-card id="flip-card__toggle">
  <quiet-card>Front content</quiet-card>
  <quiet-card slot="back">Back content</quiet-card>
</quiet-flip-card>

<quiet-button data-flip-card="toggle flip-card__toggle">
  Toggle
</quiet-button>

<style>
  #flip-card__toggle {
    max-width: 20rem;
    margin-block-end: 1rem;
  }
</style>

To flip the card to a specific side, use data-flip-card="front *" or data-flip-card="back *". Again, the ID can be omitted if the button is inside the flip card.

Front content Back content Show the front Show the back
<quiet-flip-card id="flip-card__sides">
  <quiet-card>Front content</quiet-card>
  <quiet-card slot="back">Back content</quiet-card>
</quiet-flip-card>

<quiet-button data-flip-card="front flip-card__sides">
  Show the front
</quiet-button>

<quiet-button data-flip-card="back flip-card__sides">
  Show the back
</quiet-button>

<style>
  #flip-card__sides {
    max-width: 20rem;
    margin-block-end: 1rem;
  }
</style>

Changing the orientation Jump to heading

Use the orientation attribute to set the flip animation to horizontal (default) or vertical.

A beautiful food dish surrounded by kibbles

Kitty Bowl

Our signature dinner plate.

$9.99

Features

  • Stylish design
  • Durable ceramic
  • Easy to clean
  • Dishwasher safe
  • Perfect for treats
  • Made in the USA
<quiet-flip-card orientation="vertical" style="max-width: 300px;" id="flip-card__vertical">
  <quiet-card>
    <img slot="media" src="https://images.unsplash.com/photo-1734654901149-02a9a5f7993b?q=80&w=800&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="A beautiful food dish surrounded by kibbles">
    <h3>Kitty Bowl</h3>
    <p>Our signature dinner plate.</p>
    <p><strong>$9.99</strong></p>
    <button type="button" data-flip-card="toggle">View features</button>
  </quiet-card>
  <quiet-card slot="back">
    <h3>Features</h3>
    <ul>
      <li><quiet-icon name="check"></quiet-icon> Stylish design</li>
      <li><quiet-icon name="check"></quiet-icon> Durable ceramic</li>
      <li><quiet-icon name="check"></quiet-icon> Easy to clean</li>
      <li><quiet-icon name="check"></quiet-icon> Dishwasher safe</li>
      <li><quiet-icon name="check"></quiet-icon> Perfect for treats</li>
      <li><quiet-icon name="check"></quiet-icon> Made in the USA</li>
    </ul>
    <quiet-button data-flip-card="toggle" icon-label="Close" appearance="text">
      <quiet-icon name="x"></quiet-icon>
    </quiet-button>
  </quiet-card>
</quiet-flip-card>

<style>
  #flip-card__vertical {
    quiet-card  {
      text-align: center;

      h3 {
        margin-block-start: 0;
      }

      p {
        margin-block-end: 1rem;
      }
    }
  
    img {
      width: 100%;
      height: auto;
      border-radius: 0.5rem;
    }
  
    ul {
      margin: 1rem 0;
    }

    li {
      list-style: none;
    }

    li quiet-icon {
      color: #60914a;
      vertical-align: -2px;
    }

    quiet-card[slot="back"] {
      &::part(body) {
        margin: auto 0;
      }

      quiet-button {
        position: absolute;
        top: 1rem;
        right: 1rem;
      }
    }
  }
</style>

Showing the backside initially Jump to heading

Add the flipped attribute to show the back of the flip card initially.

Flip
<quiet-flip-card id="flip-card__back" orientation="vertical" flipped>
  <div class="front" aria-label="Ace of hearts">
    <span class="corner" aria-hidden="true">A<br><quiet-icon name="heart" family="filled"></quiet-icon></span>
    <span class="corner" aria-hidden="true">A<br><quiet-icon name="heart" family="filled"></quiet-icon></span>
    <quiet-icon name="heart" family="filled" aria-hidden="true"></quiet-icon>
  </div>
  <div slot="back" class="back" aria-label="Flip the card to reveal what it is"></div>
</quiet-flip-card>

<quiet-button data-flip-card="toggle flip-card__back">
  Flip
</quiet-button>

<style>
  #flip-card__back {
    width: 150px;
    height: 230px;
    margin-block-end: 1rem;

    .front,
    .back {
      border-radius: 1rem;
    }

    .back {
      background-color: #366BE8;
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='82' height='82' viewBox='0 0 120 120'%3E%3Cpolygon fill='%233B82F6' points='120 120 60 120 90 90 120 60 120 0 120 0 60 60 0 0 0 60 30 90 60 120 120 120 '/%3E%3C/svg%3E");
    }

    .front {
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 4rem;
      background-color: white;
      border: solid 1px lightgray;
      color: #b91c1c;
      line-height: 1;

      .corner {
        display: flex;
        flex-direction: column;
        font-size: 1.5rem;
        justify-content: center;
        align-items: center;

        &:nth-child(1) {
          position: absolute;
          top: 0.75rem;
          left: 0.75rem;
        }

        &:nth-child(2) {
          position: absolute;
          bottom: 0.75rem;
          right: 0.75rem;
          scale: 1 -1;
        }

        quiet-icon {
          font-size: 1.25rem;
        }
      }      
    }
  }
</style>

Setting focus on flip Jump to heading

Use the autofocus attribute to assign focus to a specific element when the flip card turns over.

Flip the card to observe autofocus. The text field will receive focus as soon as you flip it. Flip
<quiet-flip-card id="flip-card__autofocus">
  <quiet-card>
    Flip the card to observe autofocus. The text field will receive focus as soon as you flip it.
  </quiet-card>

  <quiet-card slot="back">
    <quiet-text-field label="Enter a value" autofocus></quiet-text-field>
  </quiet-card>
</quiet-flip-card>

<quiet-button data-flip-card="toggle flip-card__autofocus">
  Flip
</quiet-button>

<style>
  #flip-card__autofocus {
    max-width: 20rem;
    margin-block-end: 1rem;
  }
</style>

Centering content vertically Jump to heading

The height of a flip card is the height of its tallest side. If you're using cards, you can vertically center the shorter side with a few lines of CSS applied to the card's body part.

Front content, nicely centered Lorem iaculis aenean venenatis conubia vivamus eros himenaeos egestas. Facilisi suspendisse ultrices natoque aliquet et nibh venenatis fames. Facilisi tempor pellentesque auctor ligula fusce. Flip
<quiet-flip-card id="flip-card__centering">
  <quiet-card>
    Front content, nicely centered
  </quiet-card>
  <quiet-card slot="back">
    Lorem iaculis aenean venenatis conubia vivamus eros himenaeos egestas. Facilisi suspendisse ultrices natoque aliquet et nibh venenatis fames. Facilisi tempor pellentesque auctor ligula fusce.
  </quiet-card>
</quiet-flip-card>

<quiet-button data-flip-card="toggle flip-card__centering">
  Flip
</quiet-button>

<style>
  #flip-card__centering {
    max-width: 20rem;
    margin-block-end: 1rem;

    quiet-card::part(body) {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100%;
    }
  }
</style>

API Jump to heading

Importing Jump to heading

The autoloader is the recommended way to import components but, if you prefer to do it manually, the following code snippets will be helpful.

CDN npm

To manually import <quiet-flip-card> from the CDN, use the following code.

import 'https://cdn.jsdelivr.net/npm/@quietui/quiet@1.0.0/dist/components/flip-card/flip-card.js';

To manually import <quiet-flip-card> from npm, use the following code.

import '@quietui/quiet/dist/components/flip-card/flip-card.js';

Slots Jump to heading

Flip Card supports the following slots. Learn more about using slots

Name Description
(default) The content to show on the front of the card.
back The content to show on the back of the card.

Properties Jump to heading

Flip Card has the following properties that can be set with corresponding attributes. In many cases, the attribute's name is the same as the property's name. If an attribute is different, it will be displayed after the property. Learn more about attributes and properties

Property / Attribute Description Reflects Type Default
flipped Flips the card. boolean false
orientation Determines the flip direction. 'horizontal'
'vertical'
'horizontal'

Events Jump to heading

Flip Card dispatches the following custom events. You can listen to them the same way was native events. Learn more about custom events

Name Description
quiet-flip Emitted when the flip card is instructed to flip but before it actually flips. Calling event.preventDefault() will prevent the flip card from flipping.
quiet-flipped Emitted after the flip card has been flipped and the animation has completed.

CSS custom properties Jump to heading

Flip Card supports the following CSS custom properties. You can style them like any other CSS property. Learn more about CSS custom properties

Name Description Default
--flip-duration The duration of the card flip animation. 0.6s
--flip-easing The easing to use for the flip animation. cubic-bezier(0.4, 0.0, 0.2, 1)

Custom States Jump to heading

Flip Card has the following custom states. You can target them with CSS using the selectors shown below. Learn more about custom states

Name Description CSS selector
flipped Applied when the card is flipped over. :state(flipped)
Search this website Toggle dark mode Get the code on GitHub Follow @quietui.org on Bluesky Follow @quiet_ui on X
    No results found