October 4, 2020 ~ 5 min read

Create a neat RSVP card with pure CSS


GIF of RSVP card

I've been one of the lucky few who had a preview of @KevinJPowell's responsive web developer bootcamp on Scrimba. I cannot recommend it highly enough, as watching the course helped me immensely in writing this post!

With this post, you will learn how to create an RSVP card, with just CSS and HTML, for any occasion!

Also, I have to admit that I've been a massive Scrimba fan for a very long time and always keep telling everyone I meet at every meetup how great it is!

Naturally, if you fancy playing with my code, there is a playground.

If English is not your native language, like me, and you have never encountered RSVP cards before, RSVP is French for Répondez s'il vous plaît, meaning "Please respond" and is used widely in the UK, US, Canada, etc. as invitations to weddings and other formal occasions.

Start with simple HTML

Let's start with HTML representation of the card and have separate divs for card's front and back.

<html>
    <head>
        <link rel="stylesheet" href="index.css" />
    </head>
    <body>
        <div class="container">
            <div class="card">
                <div class="front">
                    <h1>Front</h1>
                </div>

                <div class="back">
                    <h1>Back</h1>
                </div>
            </div>
        </div>
    </body>
</html>

Image of rendered code above

Let's now add some basic CSS to prepare a container for where the card is going to be. We can use relative % units to make sure that everything is centred.

body {
    background: #b6d4df;
}

.container {
    position: absolute;
    background: none;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

Image of rendered code above

Let's now add the card.

Percentage values are that of the parent container. So when we use width and height of 100% on .card class, it will take the same size as .container class.

body {
    background: #b6d4df;
}

.container {
    position: absolute;
    width: 60%;
    height: 60%;
    background: none;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.card {
    position: relative;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

And we can now also add styles for each face of the card.

.front,
.back {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    text-align: center;
    border-radius: 15px;
    overflow: hidden;
    background: #fafafa;
    color: #333;
}

Image of rendered code above

Well, the card is there, but we see the back of it. That's because back is rendered later, so it's covering front. To show front, I need to add backface-visibility: hidden; to both sides and now just need to rotate it.

.front,
.back {
    /* the rest of CSS */
    backface-visibility: hidden;
}

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

Image of rendered code above

That's much better. Let's try to make it flip around when we hover over the card.

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

Image of rendered code above

We're getting there, but it's not what we quite wanted. The magic CSS line to flip the card is transform-style: preserve-3d;. I'm also going to add transition: all 0.8s ease; to .card to make the animation transition look more natural.

.card {
    position: relative;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    transition: all 0.8s ease;
}

o give the transition a slightly more polished look, let's add perspective: 1000px;.

.container {
    perspective: 1000px;
    position: absolute;
    width: 60%;
    height: 60%;
    background: none;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

GIF of rendered code above

Let's spruce up the wording, to make this design as close to real-life as we can, so you can reuse it for your own party!

And I'll add some fonts, while we're here.

<html>
    <head>
        <link rel="stylesheet" href="index.css" />
        <link href="https://fonts.googleapis.com/css?family=Tangerine&display=swap" rel="stylesheet" />
        <link href="https://fonts.googleapis.com/css?family=Playfair+Display&display=swap" rel="stylesheet" />
    </head>
    <body>
        <div class="container">
            <div class="card">
                <div class="front">
                    <h1>Your Invitation to Celebrate With Us</h1>
                    <p>Please turn the card to reply</p>
                </div>

                <div class="back">
                    <h1>RSVP</h1>
                    <p>We would be thrilled for you to celebrate with us.</p>
                    <button>Yes, I'd love to come</button>
                    <button>Unfortunately, I'm busy</button>
                </div>
            </div>
        </div>
    </body>
</html>

Image of rendered code above Image of rendered code above

Responsive typography

Having good effects is nice, but if the text looks bland, the card just won't cut it.

Normally, there are two most common issues with CSS. Being able to react to changing requirements with minimum changes and maintaining px values everywhere. :D

This is when rem comes to the rescue.

A rem is the font-size value to your root element, i.e <html> element.

By default, it's not written, but it's as if:

html {
    font-size: 16px;
}

That means that when we set font-size: 1rem; it's the same as font-size: 16px;. So if we want to scale things out, we change one value and everything follows suit.

Let's see what that would look like with our card.

h1 {
    font-family: 'Tangerine', cursive;
    font-weight: bold;
    font-size: 1.8rem;
    text-align: center;
}

.front h1 {
    padding: 3rem;
}

.back h1 {
    padding: 2rem;
}

p {
    font-family: 'Playfair Display', serif;
    padding: 1.8rem;
    font-size: 1rem;
    font-weight: normal;
    text-align: center;
}

button {
    padding: 1rem;
    font-size: 0.75rem;
}

Image of rendered code above Image of rendered code above

A nice touch would be to add some colour to the button when it's hovered over.

button:hover {
    cursor: pointer;
    background-color: lightgray;
}

Image of rendered code above

But hey, when the window is resized, it destroys the look of the card. Doesn't look that great.

Image of rendered code above

Image of rendered code above

To fix it, we can use min- max- prefixes on width and height.

container {
    perspective: 1000px;
    position: absolute;
    width: 60%;
    max-width: 30rem;
    min-width: 25rem;
    height: 60%;
    min-height: 17rem;
    max-height: 20rem;
    background: none;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

Image of rendered code above

And that's it! Hope you enjoyed the article! Feel free to comment and if you want to have a chat, reach out on Twitter.

Special thanks to @perborgen for inspiring this post ;)


Maxi Ferreira

Hey! Thanks for reading! Follow me on Twitter @alanmynah to let me know what you thought, keep in touch or ask questions. Would be super happy to have a chat!