Pure CSS Flip Cards using Bootstrap 4 and CSS Grid [No JS]


Pure CSS Flip Cards using Bootstrap 4 and CSS Grid [No JS]
Last Updated: Sep 10, 2017

The Problem

I've wanted to create flipping cards for my website that would resize on different screen sizes using Bootstrap 4's .card class. At first I wanted to find a solution that was purely HTML and CSS. So I started searching online for some answers, but almost all of them lead to either having to set a fixed width, fixed height or too much JavaScript (or even combinations).

I finally realized that I had to combine some of the features on all the code I had seen to make it work. After a lot of tinkering around with bits of code, I came accross a video about CSS Grid by Morten Rand-Hendriksen. After watching it I realized that I could use CSS Grid to stack two objects in the same location and use some basic transformations to create my Flipping Cards.

The Solution

The most important part of creating a flipping object is the structure of your HTML. You need:

  • A container to hold the two cards
  • A flipper to carry out the transformation (rotate 180 degrees)
  • A container for the front side
  • A container for the back side

So your structure should look something like this:

<div class="card-container">
    <div class="card-flip">
        <div class="front">
        </div>
        <div class="back">
        </div>
    </div>
</div>

Now that we have the basic HTML needed for our flipping cards, we need the appropriate CSS to make the content flip:

.card-container {
  perspective: 700px;
}

.card-flip, .card-container {
  transform-style: preserve-3d;
  transition: all 0.7s ease;
}

.card-flip div {
  backface-visibility: hidden;
  transform-style: preserve-3d;
}

.back {
  transform: rotateY(-180deg);
}

.card-container:hover .card-flip {
  transform: rotateY(180deg);
}

To break this down:

  • perspective is used to allow a 3D effect for our transformation.
  • transform-style: preserve-3d keeps the 3D effect during transformations.
  • transition eases the transformation effect to make it look nicer.
  • backface-visibility: hidden just hides the back sides of each card.
  • transform is used to:
    1. rotate the back side by 180 degrees so that when the front side is shown, the back side is hidden.
    2. rotate the flipper by 180 degrees so that both cards inside the container flip by 180 degrees.

Now the problem is that our cards do not stack up. This is where CSS Grid comes in handy!

To make our cards stack up, we need to make some small additions to our CSS:

.card-flip {
  display: grid;
  grid-template: 1fr / 1fr;
  grid-template-areas: "frontAndBack";
  transform-style: preserve-3d;
  transition: all 0.7s ease;
}

.front {
  grid-area: frontAndBack;
}

.back {
  grid-area: frontAndBack;
  transform: rotateY(-180deg);
}

What we just did was introduce CSS Grid to our cards. This being broken down:

  • display: grid on the card flipper allows to use CSS Grid to set positions for the contents of that container
  • grid-template: 1fr/1fr instructs our grid to have a 1 X 1 layout
  • grid-template-areas is used to name the areas of your template for convenience purposes(this is not necessarily needed)
  • grid-area defines the location of the cards(this is what finally stacks our cards on top of each other, since we placed them on the same area)

Now to combine Bootstrap 4 and our Flipping Cards container, we need to adjust our HTML:

<div class="row">
    <div class="card-container col-md-*">
        <div class="card-flip">
            <div class="front card">
                <!-- Card Contents Here -->
            </div>
            <div class="back card">
                <!-- Card Contents Here -->
            </div>
        </div>
    </div>
</div>

By creating a .row and .col-md-* we can place as many Flipping Cards as we want, allowing them to flow on different rows and adjust on different screen sizes.

The .card is used to make our front and back sides look like cards. Then we can place contents inside the cards as we would usually do with normal cards.

Note: Since there are two cards in the same location, Card Overlay Images might not work exactly as intended. i.e. if the front of your card is an overlay and the contents of the back card are larger than the contents of the front, the height of both cards will be the height of the back side, meaning that the image will cover only the front side's original area.

Now to make our cards have the same height on larger devices, we need to make our .card-container use Grid as well:

.card-container {
  display: grid;
  perspective: 700px;
}

This wraps it all up! Hope you enjoyed this post. Please leave any suggestions or comments using the contact form below.

See full code on CodePen.

Contact


Nicolas Kadis
21 Mascot Square
Colchester, Essex
CO4 3GA
United Kingdom
Phone: 07548610517