CSS Project: Building a Pure CSS Animated Custom Credit Card Form

Written by

in

In today’s digital landscape, the user experience is paramount. A well-designed, intuitive, and visually appealing interface can be the difference between a successful website and one that struggles to retain visitors. One crucial aspect of this experience is the handling of sensitive information, such as credit card details. While JavaScript often takes the lead in form validation and dynamic updates, CSS offers a powerful, elegant solution for creating a visually engaging and responsive credit card form. This project will guide you through building a pure CSS animated custom credit card form, offering a hands-on learning experience for beginners to intermediate web developers.

Why Build a CSS Animated Credit Card Form?

You might be wondering, “Why CSS?” when JavaScript seems like the obvious choice for form interactions. Here’s why:

  • Performance: CSS animations are generally hardware-accelerated, meaning they can perform smoothly even on less powerful devices.
  • Accessibility: Well-written CSS animations can be made accessible, ensuring a positive experience for all users.
  • Aesthetic Appeal: CSS allows for beautiful, subtle animations that enhance the user experience without being intrusive.
  • Learning Opportunity: Building this form is an excellent way to solidify your understanding of CSS concepts like transitions, transforms, and keyframes.

This project goes beyond simple styling; it incorporates animations that react to user input, providing visual feedback and making the form more engaging. This is not just about making a form look pretty; it’s about creating a more intuitive and user-friendly experience.

Project Goals

Our objective is to construct a credit card form that:

  • Visually represents a credit card.
  • Animates when the user interacts with the form fields.
  • Provides clear visual cues for input validation (though we’ll focus on the CSS aspect; validation logic itself would be handled by JavaScript).
  • Is responsive and looks good on different screen sizes.

Step-by-Step Instructions

1. HTML Structure

First, let’s establish the HTML foundation. We’ll use semantic HTML5 elements to structure our form. Create a file named `index.html` and add the following code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Animated Credit Card Form</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <form class="credit-card-form">
            <div class="card-wrapper">
                <div class="card-front">
                    <div class="card-type"></div>
                    <div class="card-number">#### #### #### ####</div>
                    <div class="card-holder">Card Holder</div>
                    <div class="card-expiry">MM/YY</div>
                </div>
                <div class="card-back">
                    <div class="card-stripe"></div>
                    <div class="card-cvv">CVV</div>
                </div>
            </div>
            <div class="form-group">
                <label for="card-number">Card Number</label>
                <input type="text" id="card-number" name="card-number" placeholder="Enter card number" maxlength="19">
            </div>
            <div class="form-group">
                <label for="card-holder">Card Holder</label>
                <input type="text" id="card-holder" name="card-holder" placeholder="Card holder name">
            </div>
            <div class="form-group-row">
                <div class="form-group">
                    <label for="expiry-month">Expiry Date</label>
                    <select id="expiry-month" name="expiry-month">
                        <option value="">Month</option>
                        <!-- Add months here -->
                    </select>
                </div>
                <div class="form-group">
                    <label for="expiry-year"></label>
                    <select id="expiry-year" name="expiry-year">
                        <option value="">Year</option>
                        <!-- Add years here -->
                    </select>
                </div>
            </div>
            <div class="form-group">
                <label for="cvv">CVV</label>
                <input type="text" id="cvv" name="cvv" placeholder="CVV" maxlength="4">
            </div>
            <button type="submit">Submit</button>
        </form>
    </div>
</body>
</html>

Key HTML elements:

  • `<div class=”container”>`: Wraps the entire form, providing a central area for styling and layout.
  • `<form class=”credit-card-form”>`: The form element itself, which will contain all of the input fields and the submit button.
  • `<div class=”card-wrapper”>`: This is where the visual representation of the credit card will reside. It contains both the front and back of the card.
  • `<div class=”card-front”>` and `<div class=”card-back”>`: These divs represent the front and back of the credit card respectively.
  • `<div class=”form-group”>`: Groups each form field (label and input) for better styling and organization.
  • `<input type=”text” …>`: The input fields for card number, cardholder name, and CVV.
  • `<select>`: Dropdown menus for the expiry month and year.

Create a basic stylesheet, `style.css` to link to the HTML file.

2. Basic Styling

Now, let’s add some basic styling to structure the form and the credit card representation. Open `style.css` and add the following CSS:

body {
    font-family: sans-serif;
    background-color: #f4f4f4;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}

.container {
    width: 100%;
    max-width: 800px;
    padding: 20px;
}

.credit-card-form {
    background-color: #fff;
    border-radius: 10px;
    padding: 20px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.card-wrapper {
    position: relative;
    width: 100%;
    height: 200px;
    margin-bottom: 20px;
    perspective: 1000px; /* Important for 3D effect */
}

.card-front, .card-back {
    position: absolute;
    width: 100%;
    height: 100%;
    border-radius: 10px;
    backface-visibility: hidden; /* Hide the back face initially */
    transition: transform 0.8s;
}

.card-front {
    background: linear-gradient(135deg, #007bff, #6610f2);
    color: white;
    padding: 20px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}

.card-back {
    background-color: #ddd;
    transform: rotateY(180deg); /* Initially rotate back card 180 degrees */
    padding: 20px;
}

.form-group {
    margin-bottom: 15px;
}

label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}

input[type="text"], select {
    width: 100%;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    font-size: 16px;
    box-sizing: border-box; /* Important for padding */
}

button {
    background-color: #28a745;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 5px;
    font-size: 16px;
    cursor: pointer;
    width: 100%;
}

button:hover {
    background-color: #218838;
}

Key CSS properties explained:

  • `body`: Sets the background color, centers the form, and uses a sans-serif font.
  • `.container`: Limits the width of the form and adds padding.
  • `.credit-card-form`: Styles the form itself, including background color, border-radius, and a subtle box shadow.
  • `.card-wrapper`: This is the container for the card, and is set with `position: relative` to allow absolute positioning of the front and back. Crucially, it includes `perspective: 1000px;` which is necessary for the 3D flip effect.
  • `.card-front` and `.card-back`: Styles the card front and back. The `backface-visibility: hidden;` property is essential; it hides the back of the card until it’s rotated into view.
  • `transform: rotateY(180deg);`: Applies an initial rotation to the back of the card so it is hidden.
  • Form elements: Basic styling for labels, inputs, and the submit button.

3. Adding Card Details

Let’s add some visual elements to the card to make it look like a real credit card. Inside the `.card-front` div, add the following code:

<div class="card-type"></div>
<div class="card-number">#### #### #### ####</div>
<div class="card-holder">Card Holder</div>
<div class="card-expiry">MM/YY</div>

And add the following CSS to `style.css` to style the card details:

.card-type {
    width: 50px;
    height: 30px;
    background-color: rgba(255, 255, 255, 0.2);
    border-radius: 5px;
}

.card-number {
    font-size: 1.2rem;
    margin-bottom: 20px;
}

.card-holder, .card-expiry {
    font-size: 0.9rem;
}

Inside the `.card-back` div, add the following code:

<div class="card-stripe"></div>
<div class="card-cvv">CVV</div>

And add the following CSS to `style.css` to style the card back details:

.card-stripe {
    height: 40px;
    background-color: #333;
    margin-bottom: 20px;
}

.card-cvv {
    text-align: right;
    font-size: 1.2rem;
}

4. Adding Animations

Now, let’s bring the form to life with animations. We’ll focus on two main types of animations:

  • Input Focus Animations: When a user focuses on an input field, we’ll highlight the corresponding element on the card.
  • Card Flip Animation: When the user focuses on the CVV input, the card will flip to the back.

4.1. Input Focus Animations

We’ll use the `:focus` pseudo-class to trigger animations when an input field is focused. Add the following CSS to `style.css`:

input[type="text"]:focus, select:focus {
    outline: none; /* Remove default focus outline */
    border-color: #007bff; /* Change border color on focus */
    box-shadow: 0 0 5px rgba(0, 123, 255, 0.5); /* Add a subtle shadow on focus */
}

#card-number:focus ~ .card-wrapper .card-front .card-number {
    transform: scale(1.1);
    transition: transform 0.3s ease;
}

#card-holder:focus ~ .card-wrapper .card-front .card-holder {
    transform: scale(1.1);
    transition: transform 0.3s ease;
}

#expiry-month:focus ~ .card-wrapper .card-front .card-expiry, 
#expiry-year:focus ~ .card-wrapper .card-front .card-expiry {
    transform: scale(1.1);
    transition: transform 0.3s ease;
}

#cvv:focus ~ .card-wrapper .card-back .card-cvv {
    transform: scale(1.1);
    transition: transform 0.3s ease;
}

Explanation:

  • The first rule styles the input fields when they have focus.
  • The rules using `~` (general sibling combinator) target elements based on their relationship with the focused input fields. For example, `#card-number:focus ~ .card-wrapper .card-front .card-number` says, “When the input with the ID ‘card-number’ has focus, target the .card-number element inside the .card-front element, inside the .card-wrapper.”
  • `transform: scale(1.1);` Slightly enlarges the text on the card when the corresponding input field is focused.
  • `transition: transform 0.3s ease;` Smoothly animates the scaling effect over 0.3 seconds.

4.2. Card Flip Animation

We’ll use the `:focus` pseudo-class again, combined with the `transform` property to create the flip effect. Add the following CSS to `style.css`:


#cvv:focus ~ .card-wrapper .card-front {
    transform: rotateY(-180deg);
}

#cvv:focus ~ .card-wrapper .card-back {
    transform: rotateY(0deg);
}

Explanation:

  • When the `#cvv` input field has focus, we change the `transform` property of the `.card-front` and `.card-back` elements.
  • `.card-front` rotates 180 degrees in the Y-axis (horizontally).
  • `.card-back` rotates to 0 degrees.
  • The `transition: transform 0.8s;` property, which we added earlier to `.card-front` and `.card-back`, controls the animation speed.

5. Adding Placeholder Text and Dynamic Updates (Optional)

While this project primarily focuses on CSS animations, you can enhance the user experience further by using JavaScript to dynamically update the card details as the user types in the form fields. This is an optional step, but it adds a significant level of polish.

Here’s an example of how you can use JavaScript to update the card number display:

<script>
    const cardNumberInput = document.getElementById('card-number');
    const cardNumberDisplay = document.querySelector('.card-number');

    cardNumberInput.addEventListener('input', (event) => {
        let cardNumber = event.target.value;
        // Format the card number with spaces every four digits
        cardNumber = cardNumber.replace(/s?/g, '').replace(/(d{4})(?=d)/g, '$1 ');
        cardNumberDisplay.textContent = cardNumber;
    });
</script>

Explanation:

  • We get references to the card number input field and the `.card-number` element on the card.
  • We add an event listener to the input field that listens for the `input` event (fires whenever the user types something).
  • Inside the event listener, we get the current value of the input field.
  • We format the card number to add spaces after every four digits using regular expressions.
  • We update the `textContent` of the `.card-number` element with the formatted card number.

You can apply similar logic to update the cardholder name and expiry date.

6. Responsive Design

To ensure your form looks good on all screen sizes, let’s incorporate responsive design principles. Add the following meta tag to the `<head>` of your HTML:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

This meta tag sets the viewport to the width of the device and sets the initial zoom level to 1. Then, use media queries in your CSS to adjust the layout and styling based on screen size. For example, to make the form stack vertically on smaller screens, you can add this to your `style.css`:

@media (max-width: 600px) {
    .container {
        padding: 10px;
    }

    .credit-card-form {
        padding: 10px;
    }

    .card-wrapper {
        height: 150px; /* Adjust height for smaller screens */
    }

    .form-group-row {
        flex-direction: column; /* Stack expiry date fields */
    }

    .form-group {
        width: 100%; /* Make form groups full width */
    }
}

Explanation:

  • `@media (max-width: 600px)`: This media query applies the following styles only when the screen width is 600 pixels or less.
  • We adjust the padding of the container and the form.
  • We reduce the height of the card.
  • We change the flex direction of the `form-group-row` to `column` to stack the expiry date fields vertically.
  • We set the width of the form groups to 100% to make them take up the full width.

7. Enhancements (Optional)

Here are some additional features you can consider adding to your credit card form:

  • Card Type Detection: Use JavaScript to detect the credit card type (Visa, Mastercard, American Express, etc.) based on the card number and display the corresponding logo on the card.
  • Input Validation: Implement JavaScript validation to ensure the user enters valid card details (e.g., correct card number length, valid expiry date, correct CVV).
  • Error Handling: Display clear error messages to the user if there are any validation issues.
  • Accessibility Improvements: Ensure the form is accessible by using semantic HTML, ARIA attributes, and providing sufficient color contrast.
  • More Advanced Animations: Experiment with more complex CSS animations, such as subtle transitions when the user types in the fields or when the card is successfully submitted.

Common Mistakes and How to Fix Them

  • Incorrect HTML Structure: Ensure you have a proper HTML structure with semantic elements. Misplaced divs can lead to styling issues and animation problems. Review the HTML code provided in the instructions carefully.
  • Missing `backface-visibility: hidden;`: This CSS property is crucial for the 3D flip effect. Without it, both the front and back of the card will be visible simultaneously during the animation.
  • Incorrect `perspective` Value: The `perspective` property on the `.card-wrapper` element is necessary for the 3D effect to work. Experiment with different values to adjust the depth of the perspective.
  • Incorrect Use of the General Sibling Combinator (`~`): Make sure you correctly use the general sibling combinator to target the correct elements. Ensure the elements are siblings, or the animation won’t work as expected.
  • Not Using `box-sizing: border-box;`: This property is important for the input fields. If you don’t use it, the padding might cause the input fields to overflow their containers.
  • Forgetting to Add Transitions: Without transitions, the animations will be instantaneous and jarring. Make sure you include `transition` properties for smooth animations.
  • Not Testing on Different Devices: Always test your form on different devices and screen sizes to ensure it is responsive and looks good everywhere.

Summary / Key Takeaways

In this project, we’ve explored how to build a visually engaging and interactive credit card form using pure CSS animations. We’ve covered the fundamental HTML structure, basic styling, and the implementation of input focus and card flip animations. We’ve also touched on the importance of responsive design and provided suggestions for further enhancements. By building this project, you’ve gained a practical understanding of CSS transitions, transforms, and keyframes, empowering you to create more dynamic and user-friendly web interfaces. Remember to focus on the details, test your code thoroughly, and don’t be afraid to experiment to achieve the desired effects. With a solid grasp of these principles, you can create compelling user experiences that captivate and delight your website visitors.