Build responsive checkout page

In this tutorial we’re going to learn how to create a responsive checkout page using html css and javascript where we'll have switchable product images with checkout form

🔗Prerequisites

Prerequisites

🔗Get started ✌

The checkout page we’ll build in this tutorial will be pretty cool. a user can switch a image slide with pagination dot we’ll also build checkout form in this project

I’ll explain how to build each project, but you must follow along by typing the code and running it on your end to get the most out of this tutorial

Click here to get starter files

🔗Add google font cdn

We’ll use roboto font family in this project for that we have to include cdn of roboto google font

css
<link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap" rel="stylesheet">

🔗Create two column layout with product and checkout container

Markup of layout and product , checkout container 👇

html
<div class="container">
<div class="subcontainer">
<div class="left">
<div class="product-container"></div>
</div>
<div class="right">
<div class="checkout-container"></div>
</div>
</div>
</div>

🔗Let’s add styling into ui 🎨

Basic styling

css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Verdana, sans-serif;
background: #19152dde;
overflow: hidden;
}

css for two column layout

css
/* center everything vertically */
.container {
width: 80vw;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* css for creating two column layout */
.subcontainer {
display: grid;
grid-template-columns: 50% 40%;
}
/* overlap left side div from left side using transform and z-index */
.left {
transform: translateX(55px);
z-index: 1;
}
/* overlap right side div from right side */
.right {
background: #3c3bcb;
margin-top: 2rem;
margin-bottom: 2rem;
transform: translateX(50px);
}
/* layout end */

css for product

css
/* css for adding bg image on product container div */
.product-container {
max-width: 500px;
position: relative;
margin: auto;
background-image: url("bg.png");
box-shadow: 43px 26px 145px -2px rgba(0, 0, 0, 0.51);
background-repeat: no-repeat;
background-size: cover;
height: 550px;
}

css for checkout container

css
.checkout-container {
margin: auto;
padding: 55px 35px;
border-top-right-radius: 20px;
height: 100%;
border-bottom-right-radius: 20px;
}
two column layout with product and checkout container

🔗Let’s add product detail image slider , dot pagination in product container

Markup of product detail

html
<!-- product container div start -->
<div class="product-container">
<div class="detail">
<p class="brand">Redux</p>
<h2 class="watchName">Analog Men's Watch</h2>
</div>
<div class="imgSlide">
<img src="Product Images/1.png" style="width: 100%;" />
</div>
<div class="imgSlide">
<img src="Product Images/2.png" style="width: 100%;" />
</div>
<div class="imgSlide">
<img src="Product Images/3.png" style="width: 100%;" />
</div>
<!-- dot pagination -->
<div class="dots">
<a class="pagination" onclick="currentSlide(1)"></a>
<a class="pagination" onclick="currentSlide(2)"></a>
<a class="pagination" onclick="currentSlide(3)"></a>
</div>
<!-- dot pagination -->
</div>
<!-- product container div end -->

In above html code we defined markup for product detail , slider and dot pagination and calling onclick currentSlide function which is we’ll create later in this tutorial and passing number value as an argument

Let’s add styling product detail 🎨

css
.detail {
position: relative;
text-align: center;
font-family: "DM Sans", sans-serif;
}
.detail .brand {
margin-bottom: 0rem;
padding-top: 2rem;
text-transform: uppercase;
font-weight: bold;
color: #6b6ad4;
font-family: "Roboto", sans-serif;
letter-spacing: 0.1rem;
}
.detail .watchName {
margin: 1rem;
letter-spacing: 0.1rem;
font-weight: bold;
}
.imgSlide {
display: block;
width: 350px;
margin: auto;
}
img {
vertical-align: middle;
width: 100%;
}
/* css for switch product image */
.dots {
display: flex;
justify-content: center;
bottom: -3rem;
position: relative;
}
/* css for switch image (dot pagination) */
.pagination {
display: block;
position: relative;
cursor: pointer;
border: 1px solid #3c3bcb;
width: 10px;
padding: 6px;
transition: 0.6s ease;
border-radius: 50%;
user-select: none;
transition: background-color 0.6s ease;
height: 10px;
margin-left: 1rem;
}
.pagination:hover,
.active {
background-color: #3c3bcb;
}

In above css code we defined styling for product details , img slides and dot pagination We also defined .active class which we’ll use in javascript to add active class to respective dot pagination

As you can see above everything perfect but we want to show only 1 image slide at a time and change image slide onclick dog pagination

🔗Let’s start building feature to showSlides

  • init slideIndex var and assigning default value 1 ( because we want to show first image by default )
  • Calling showSlides function which we’ll in sooner and passing slideIndex as an argument so that we can use this slideIndex value in showSlides function
js
var slideIndex = 1;
showSlides(slideIndex);

Finally let’s create function to showSlide

js
function showSlides() {
var i;
var slides = document.getElementsByClassName("imgSlide");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex - 1].style.display = "block";
}
  • Created function for showSlide and getting all dom elements by using getElementByClassName and assigning to slides
  • Hiding all images by default using display none and for loop method
  • Changed visibility of none to block of first index of slides ( slideIndex = 1 - 1 = 0 ) [ slideIndex change dynamically every time when we update value of slideIndex using currentSlide function what we’ll create later in this tutorial ]

As you can see above all perfect but we want to change image slide to currentSlide onclick dot pagination

js
function currentSlide(n) {
showSlides((slideIndex = n));
}

In above javascript code we created function to switch slide based on currentSlide value (value of n getting from pagination onClick) then assigning “n” to slideIndex

As you can see above it’s working as expected

We also want to add active class to respective currentSlide dog pagination (we can do that similarly how we hide all images by default and showing image slider dynamically on call showSlide function )

  • Targeting all element by class name pagination
  • Removing active class from all dots pagination
  • Add active class to respective dots pagination
js
function showSlides() {
console.log(slideIndex); // for explanation purpose
var i;
/* targeting all element by class name pagination */
var dots = document.getElementsByClassName("pagination");
/* removing active class from all dots pagination */
for (i = 0; i < dots.length; i++) {
dots[i].classList.remove("active");
}
/* adding active class to respective dots pagination */
dots[slideIndex - 1].classList.add("active");
}

Now it’s working perfect

🔗Let’s build checkout form

Markup of checkout form

html
<div class="checkout-container">
<p>Checkout</p>
<div class="field">
<input type="text" placeholder="Card Name" />
</div>
<div class="field">
<input type="text" placeholder="Card Number" />
</div>
<div class="field">
<input type="text" placeholder="Cardholder Name" />
</div>
<div class="field last_field">
<div class="item">
<input type="text" placeholder="Expiry Date" />
</div>
<div class="item">
<input type="text" placeholder="CVV" />
</div>
</div>
<button type="submit" class="btn">Complete Order</button>
</div>

Let’s add styling into checkout form 🎨

css
.checkout-container p {
margin-bottom: 25px;
font-size: 1.5rem;
text-transform: uppercase;
color: #fff;
font-family: "DM Sans", sans-serif;
text-align: center;
font-weight: 800;
}
.field {
margin-bottom: 1.5rem;
}
input[type="text"] {
width: 100%;
padding: 10px;
border: 1px solid rgb(147, 144, 144);
outline: none;
background: transparent;
color: #fff;
}
input[type="text"]::placeholder {
color: #fff;
}
input[type="text"]:focus {
border: 1px solid #8686f6;
}
.field.last_field {
display: flex;
justify-content: space-between;
}
.field.last_field .item {
width: 48%;
}
/* css submit button */
.btn {
position: relative;
display: inline-block;
padding: 15px 30px;
text-transform: uppercase;
font-size: 1rem;
overflow: hidden;
transition: 0.2s;
background-color: #fff;
margin-top: 0.5rem;
font-family: "Roboto", sans-serif;
cursor: pointer;
border: none;
outline: none;
}
.btn:hover {
color: #fff;
background: #7852e2;
}

But what about responsiveness As you can see below it’s not responsive

styling checkout form

CSS for responsiveness

css
@media only screen and (max-width: 725px) {
body {
overflow: auto;
}
.container {
width: 100vw;
position: absolute;
transform: translate(0, 0);
top: 0;
left: 0;
}
.subcontainer {
display: block;
}
.left {
transform: none;
}
.right {
background: #3c3bcb;
margin-top: 0rem;
margin-bottom: 0rem;
transform: none;
}
}

Congratulation we have successfully created responsive checkout page 🥳

Download source code