Build a Card that flips on ‘click’ with HTML, CSS, and Vanilla Javascript (Part 1)

Carla Kroll
Coding with Carla
Published in
12 min readMay 27, 2019

There is a feature that I see a lot that I think is a great learning tool for HTML, CSS, and Vanilla Javascript. A three card in-line feature is very useful. It shows information or images on the front and can be clicked to flip around and show additional information on the back.

During this written tutorial I will go over HTML, CSS, and the Javascript. This write-up is intended for beginners, and throughout I will review why each line exists. At the end of tutorial you should, hopefully, have an understanding of the logic behind approaching this type of feature.

Let’s start by using Codepen. Codepen is a great tool to build out fun things, practice, and learn by checking out other people’s work as well.

You can open a free account with Codepen, but if you prefer not to do so, you can also use any code editor you like. I recommend VS Code or Atom for your editor. I personally use VS Code in my day to day coding expeditions. All of my screenshots will be views of my Codepen from here forward. Feel free to follow along!

Ok, so let’s start with a clean slate. If you are using Codepen you will see 3 sections: HTML, CSS, and Javascript. If you are using a code editor, create 3 new files all in the same folderindex.html style.css and index.js.

If you are using code editor, set up your blank index.html page with this starter markup:

<!DOCTYPE html>
<html>
<head>
<meta charset=”UTF-8">
<title>Coding with Carla - Card Flip Feature</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- Your code will go between the body tags and ABOVE the script tag-->
<script src="index.js"></script>
</body>
</html>

If you are using Codepen, your new pen should start out as below. I personally prefer to have my code to the left of my preview browsers as shown below. You can change this by clicking the “Change View” button and selecting your preferred display.

Initial blank Codepen

Let’s start by building out the HTML foundation. This will give us a structure to work with.

First, we need a container that will hold the three cards. For this container, I will use the element called <section>. The section tag does exactly what the name implies. It is defining a section of the page.

Section tag to define container

You’ll notice that the first tag looks like this: <section> and then there is a second tag like this: </section>. These are opening and closing tags. There are some tags that are “self-closing” and we’ll get to at least one of those later on, but typically, most tags need an opening and a closing tag.

Ok, now within this container, lets place in cards within the section container using the <div> tag. div tags are division tags. They are very commonly used in HTML.

Three div tags, one for each card

Let’s take a look at what we’ve got so far. We have 3 <div> elements sitting inside of the opening and closing <section> tags.
This is called nesting. Now, the <section> tag is the Parent to the div tags, and the <div> tags are the Children of the section tag, and each of the div tags are Siblings to one another.

<section>
<div></div>
<div></div>
<div></div>

</section>

Although we have a container and 3 card elements, you’ll notice that our page is still blank. This is because we have no content and have not added any styles yet. Let’s go ahead and start working on that.

First, I am going to add some placeholder text. This text will go away later, but will help us to style the cards to start.

Within each opening and closing<div> add placeholder text

<section>
<div>Card 1 placeholder</div>
<div>Card 2 placeholder</div>
<div>Card 3 placeholder</div>

</section>

This gives us a visual to work with.

Let’s begin styling.

At this point, we are going to start moving back and forth from the HTML to the CSS. If you are using a code editor, it will be a good idea to keep both the index.html and style.css files open.

Some basics with CSS are IDs and Classes. IDs are initiated within the CSS file using a hashtag # and Classes are initiated with a period . or dot.
Id’s should not be used more than one time per page. If there is a possibility that a style being written could be utilized more than one time, we should use classes.

First thing I am going to do is get the three placeholders to align horizontally. We will do this using Flexbox. Flexbox is a built in part of CSS. It is compatible with all current browsers with partial support for IE 11. I do not typically strive to accommodate outdated browsers like IE 10and older, unless specifically requested by clients.

Every html element is treated like a box. Every. Single. Element. So, right now you have a section element that is a box and 3 div elements that are all each their own boxes. With CSS we can determine how they are displayed with the display property.

In CSS, let’s write an ID called container and assign a property called display with a value of flex. There are quite a few display options, but for our purposes today, the flex value will work perfectly.

Every CSS selector has to have opening and closing curly braces { }, and, at the end of each line in those braces you need a semicolon ;. So our container id should look like this:

#container {
display: flex;
}

Now that we have part of CSS written, let’s add that ID to our HTML by assigning it to the section element.

<section id=”container”>
<div>Card 1 placeholder</div>
<div>Card 2 placeholder</div>
<div>Card 3 placeholder</div>
</section>

Great! Now we can see that our placeholders are all displaying on the same line.

By default, display: flex sets its children into a row. What we can do now, is set those 3 placeholders to be centered in the middle of the page by using more flexbox options. Before we add more flexbox though, lets start by adding a height of 100vh to the container. Using vh stands for view height which means that the element with the id of container will take the the full height of the view port.

height: 100vh;

What’s the viewport? Good question!
The viewport the visible area of your web page.

Now, let’s add in our CSS to the container specifying centering our content horizontally and vertically.

Note: /* */ in CSS will comment multiple lines. Comments help you to make notes as your coding so that when you go back later, you can know why lines are written.

justify-content: center; /* this will center row horizontally */align-items: center; /* this will center row vertically */

So far, your CSS should look like this:

#container {
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
}

Are your placeholders all aligned horizontally now?

Should currently display like this

Side note: If you’d like to learn more flexbox, check out this great zombie game by geddski.

It’s time to start styling your cards. Since all 3 cards will have similar styles, we will use a class so that we can apply it multiple times to different elements in our html. We will call this class .card.

I am going to start with the background color of the cards. I like the color orange, so let’s use the color #F76014.
Wait, that’s orange?
This is called a hex color. You can find your favorite hex color at this HTML Color Codes website.

.card {
background-color: #F76014; /* Yep, that's orange */
}

Let’s add this class to our div elements now by adding class="card" to each one.

You can see now that each placeholder has an orange background. Next, lets separate these cards from each other. Right now they are touching and we cannot tell where one ends and the next begins.

As I mentioned before, each element is treated like a box. Each box comes with its own packaging.

The very outer portion is the margin. The margin acts like a force field that will determine how close the surrounding boxes can get. Directly inside the margin is the border. This border is not required to be visible, but every element has one available. The next layer is the padding. This will stretch out the inner portion of the box, pushing away the border and the margin. Finally inside all of that stuff is your content.

Since we don’t want these cards to touch, let’s build our force field (margin).
We can determine if we only want top, bottom, left, right, or some combination of these. For these purposes, we are going to set the same number for all sides. By setting margin: 15px we are telling that class to apply that number to all 4 sides.

.card {
background-color: #F76014;
margin: 15px;
}

I think we are in a good place to add in a picture. For demo purposes I really like the website Unsplash. You can use their images for free. I highly recommend giving credit to the photographers where you can.

My go-to is using dog images. Click on the image you like. You can download for free, or you can copy the image address, which is what I do most of the time when using sample images.

You’ll just need to right click on that image and click Copy image address.

Now, back in your HTML, let’s add a new element.

In the first card div, remove the placeholder text, and in its place, add in an image tag <img />. Image tags are self-closing, however, they need a bit of information inside of the tag to specify the image your are adding.

You need the source of the image and an alt tag. Although alt tags are not required, I really recommend using them because they are very helpful with accessibility for impaired users as well as things like SEO (search engine optimization).

<img src="" alt="" />

This is the start of our image tag. Now we just need to add in our puppy image link to the source and we can name it in the alt tag.

<img src="https://images.unsplash.com/photo-1548199973-03cce0bbc87b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3300&q=80" alt="Cute Puppies Running" />

This image tag should go in our first card div, which will replace the placeholder text.

Let’s do this for the other 2 placeholders as well. Feel free to pick any image from unsplash that you like.

We now have 3 cards with 3 different images. Excellent!

The problem that we have now, is that images are HUGE! We could reduce those sizes down in the card class, but let’s think about this for a minute.

We are building cards that are going to flip to the back on click. That means we have a front part of the card AND a back.

Let’s add those to our card div and then we can resize our images.

I’m going to start by adding 2 new divs. I’ll also add in the class of front to the first of the divs and back to the other. Then, let’s move the image tags into the divs with the class of front. Now your HTML should look like this:

<section id=”container”>
<div class=”card”>
<div class=”front”>
<img src=”https://images.unsplash.com/photo-1548199973-03cce0bbc87b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3300&q=80" alt=”Cute Puppies Running” />
</div>
<div class=”back”></div>
</div>
<div class=”card”>
<div class=”front”>
<img src=”https://images.unsplash.com/photo-1444212477490-ca407925329e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2000&q=80" alt=”Three dogs looking on”>
</div>
<div class=”back”></div>
</div>
<div class=”card”>
<div class=”front”>
<img src=”https://images.unsplash.com/photo-1541599540903-216a46ca1dc0?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1951&q=80" alt=”Puppy in a drawer”>
</div>
<div class=”back”></div>
</div>
</section>

Side note: when building out features, it is very common to have to adjust, add, move, replace elements and css as you go. It’s important to be fluid while building things.

It’s time resize the width and height so that we can see our images better.

In our CSS file, lets set the class .card to have a height of 200px and width of 300px. This will give us a landscape image for any card that is built.

.card {
background-color: #F76014;
width: 300px;
height: 200px;
}

Our pictures are still HUGE! This is because we need to tell our pictures that they are only allowed to be a certain size. Lets take another quick look at part of our HTML:

<div class="card">
<div class="front">
<img src="https://images.unsplash.com/photo-1541599540903-216a46ca1dc0?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1951&q=80" alt="Puppy in a drawer">
</div>
<div class="back"></div>
</div>

You can see we have the div with a class of .card as the parent of .front and .back and we have image tags inside of the front tag. We will eventually add images to the .back class as well. We can now specify our CSS to only target the image tags that are nested within those classes.

.front > img {
height: 200px;
width: 300px;
}

By using the character > we can select all <img> elements where the parent has the .front class. BUT WAIT THERE’S MORE! We want to do the same thing with the class of .back, so let’s add that to this same css rule. We do this by just separating the selectors with a comma:

.front > img, .back > img {
height: 200px;
width: 300px;
}

You could write each of those individually, however, the fewer lines you write, the less likely you are to make a mistake.

Hover effect

It seems like a good time to give the front of the cards an effect when you hover over it.

When you want to target a piece of your HTML on hover, you can add on to the selector with :hover. For example, every time a user “hovers” over the card, it will be clickable, so we should change the cursor to pointer. Let’s start there.

Below our card class, let’s add a new rule called .card:hover and inside of that rule, we’ll add a declaration of cursor: pointer.

.card:hover {
cursor: pointer;
}

There are many different cursor options you can use for different situations, but we specifically want the pointer in this instance.

Now let’s work on the color changing on hover next.
Currently our card has a background color set to #F76014, but we can’t see it because we have an image sitting on top of that color. With this in mind, let’s change the opacity of our picture on hover and allow some of that color to come through.

We are going to target the images that are nested in the .front class to change on hover. To do this we will add:

.front > img:hover {
opacity: 0.5;
}

Opacity is on a scale of 0 -1 in CSS. By setting opacity to 0.5 we are telling the image to reduce to 50% on hover. You can play with that number to a setting that you prefer. In our example, the half-way point works great.
Your images should now have color overlay on hover, something like this:

First image showing color on hover

It looks like the front of our cards are done! Check out parts 2 and 3 of this series, coming soon, to learn how to add the back of the card and the javascript to flip the card in a click event.

--

--