Posted in
11764
3:20 am, September 4, 2021
Card Form Design, Very Slick and Rounded
A very cool looking form design here also using vue.js. As you type in the details the animated card fills in.
Also as you select each element it will show you on the demo card which one is selected.
Card Form Design, Very Slick and Rounded Demo
View Demo Full Screen View Demo New Tab
Card Form Design, Very Slick and Rounded Code
HTML
<div class="wrapper" id="app">
<div class="card-form">
<div class="card-list">
<div class="card-item" v-bind:class="{ '-active' : isCardFlipped }">
<div class="card-item__side -front">
<div class="card-item__focus" v-bind:class="{'-active' : focusElementStyle }" v-bind:style="focusElementStyle" ref="focusElement"></div>
<div class="card-item__cover">
<img
v-bind:src="'https://raw.githubusercontent.com/muhammederdem/credit-card-form/master/src/assets/images/' + currentCardBackground + '.jpeg'" class="card-item__bg">
</div>
<div class="card-item__wrapper">
<div class="card-item__top">
<img src="https://raw.githubusercontent.com/muhammederdem/credit-card-form/master/src/assets/images/chip.png" class="card-item__chip">
<div class="card-item__type">
<transition name="slide-fade-up">
<img v-bind:src="'https://raw.githubusercontent.com/muhammederdem/credit-card-form/master/src/assets/images/' + getCardType + '.png'" v-if="getCardType" v-bind:key="getCardType" alt="" class="card-item__typeImg">
</transition>
</div>
</div>
<label for="cardNumber" class="card-item__number" ref="cardNumber">
<template v-if="getCardType === 'amex'">
<span v-for="(n, $index) in amexCardMask" :key="$index">
<transition name="slide-fade-up">
<div
class="card-item__numberItem"
v-if="$index > 4 && $index < 14 && cardNumber.length > $index && n.trim() !== ''"
>*</div>
<div class="card-item__numberItem"
:class="{ '-active' : n.trim() === '' }"
:key="$index" v-else-if="cardNumber.length > $index">
{{cardNumber[$index]}}
</div>
<div
class="card-item__numberItem"
:class="{ '-active' : n.trim() === '' }"
v-else
:key="$index + 1"
>{{n}}</div>
</transition>
</span>
</template>
<template v-else>
<span v-for="(n, $index) in otherCardMask" :key="$index">
<transition name="slide-fade-up">
<div
class="card-item__numberItem"
v-if="$index > 4 && $index < 15 && cardNumber.length > $index && n.trim() !== ''"
>*</div>
<div class="card-item__numberItem"
:class="{ '-active' : n.trim() === '' }"
:key="$index" v-else-if="cardNumber.length > $index">
{{cardNumber[$index]}}
</div>
<div
class="card-item__numberItem"
:class="{ '-active' : n.trim() === '' }"
v-else
:key="$index + 1"
>{{n}}</div>
</transition>
</span>
</template>
</label>
<div class="card-item__content">
<label for="cardName" class="card-item__info" ref="cardName">
<div class="card-item__holder">Card Holder</div>
<transition name="slide-fade-up">
<div class="card-item__name" v-if="cardName.length" key="1">
<transition-group name="slide-fade-right">
<span class="card-item__nameItem" v-for="(n, $index) in cardName.replace(/\s\s+/g, ' ')" v-if="$index === $index" v-bind:key="$index + 1">{{n}}</span>
</transition-group>
</div>
<div class="card-item__name" v-else key="2">Full Name</div>
</transition>
</label>
<div class="card-item__date" ref="cardDate">
<label for="cardMonth" class="card-item__dateTitle">Expires</label>
<label for="cardMonth" class="card-item__dateItem">
<transition name="slide-fade-up">
<span v-if="cardMonth" v-bind:key="cardMonth">{{cardMonth}}</span>
<span v-else key="2">MM</span>
</transition>
</label>
/
<label for="cardYear" class="card-item__dateItem">
<transition name="slide-fade-up">
<span v-if="cardYear" v-bind:key="cardYear">{{String(cardYear).slice(2,4)}}</span>
<span v-else key="2">YY</span>
</transition>
</label>
</div>
</div>
</div>
</div>
<div class="card-item__side -back">
<div class="card-item__cover">
<img
v-bind:src="'https://raw.githubusercontent.com/muhammederdem/credit-card-form/master/src/assets/images/' + currentCardBackground + '.jpeg'" class="card-item__bg">
</div>
<div class="card-item__band"></div>
<div class="card-item__cvv">
<div class="card-item__cvvTitle">CVV</div>
<div class="card-item__cvvBand">
<span v-for="(n, $index) in cardCvv" :key="$index">
*
</span>
</div>
<div class="card-item__type">
<img v-bind:src="'https://raw.githubusercontent.com/muhammederdem/credit-card-form/master/src/assets/images/' + getCardType + '.png'" v-if="getCardType" class="card-item__typeImg">
</div>
</div>
</div>
</div>
</div>
<div class="card-form__inner">
<div class="card-input">
<label for="cardNumber" class="card-input__label">Card Number</label>
<input type="text" id="cardNumber" class="card-input__input" v-mask="generateCardNumberMask" v-model="cardNumber" v-on:focus="focusInput" v-on:blur="blurInput" data-ref="cardNumber" autocomplete="off">
</div>
<div class="card-input">
<label for="cardName" class="card-input__label">Card Holders</label>
<input type="text" id="cardName" class="card-input__input" v-model="cardName" v-on:focus="focusInput" v-on:blur="blurInput" data-ref="cardName" autocomplete="off">
</div>
<div class="card-form__row">
<div class="card-form__col">
<div class="card-form__group">
<label for="cardMonth" class="card-input__label">Expiration Date</label>
<select class="card-input__input -select" id="cardMonth" v-model="cardMonth" v-on:focus="focusInput" v-on:blur="blurInput" data-ref="cardDate">
<option value="" disabled selected>Month</option>
<option v-bind:value="n < 10 ? '0' + n : n" v-for="n in 12" v-bind:disabled="n < minCardMonth" v-bind:key="n">
{{n < 10 ? '0' + n : n}}
</option>
</select>
<select class="card-input__input -select" id="cardYear" v-model="cardYear" v-on:focus="focusInput" v-on:blur="blurInput" data-ref="cardDate">
<option value="" disabled selected>Year</option>
<option v-bind:value="$index + minCardYear" v-for="(n, $index) in 12" v-bind:key="n">
{{$index + minCardYear}}
</option>
</select>
</div>
</div>
<div class="card-form__col -cvv">
<div class="card-input">
<label for="cardCvv" class="card-input__label">CVV</label>
<input type="text" class="card-input__input" id="cardCvv" v-mask="'####'" maxlength="4" v-model="cardCvv" v-on:focus="flipCard(true)" v-on:blur="flipCard(false)" autocomplete="off">
</div>
</div>
</div>
<button class="card-form__button">
Submit
</button>
</div>
</div>
<a href="https://github.com/muhammederdem/credit-card-form" target="_blank" class="github-btn">
See on GitHub
</a>
</div>
CSS
@import url("https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600,700|Source+Sans+Pro:400,600,700&display=swap");
body {
background: #ddeefc;
font-family: "Source Sans Pro", sans-serif;
font-size: 16px;
}
* {
box-sizing: border-box;
}
*:focus {
outline: none;
}
.wrapper {
min-height: 100vh;
display: flex;
padding: 50px 15px;
}
@media screen and (max-width: 700px), (max-height: 500px) {
.wrapper {
flex-wrap: wrap;
flex-direction: column;
}
}
.card-form {
max-width: 570px;
margin: auto;
width: 100%;
}
@media screen and (max-width: 576px) {
.card-form {
margin: 0 auto;
}
}
.card-form__inner {
background: #fff;
box-shadow: 0 30px 60px 0 rgba(90, 116, 148, 0.4);
border-radius: 10px;
padding: 35px;
padding-top: 180px;
}
@media screen and (max-width: 480px) {
.card-form__inner {
padding: 25px;
padding-top: 165px;
}
}
@media screen and (max-width: 360px) {
.card-form__inner {
padding: 15px;
padding-top: 165px;
}
}
.card-form__row {
display: flex;
align-items: flex-start;
}
@media screen and (max-width: 480px) {
.card-form__row {
flex-wrap: wrap;
}
}
.card-form__col {
flex: auto;
margin-right: 35px;
}
.card-form__col:last-child {
margin-right: 0;
}
@media screen and (max-width: 480px) {
.card-form__col {
margin-right: 0;
flex: unset;
width: 100%;
margin-bottom: 20px;
}
.card-form__col:last-child {
margin-bottom: 0;
}
}
.card-form__col.-cvv {
max-width: 150px;
}
@media screen and (max-width: 480px) {
.card-form__col.-cvv {
max-width: initial;
}
}
.card-form__group {
display: flex;
align-items: flex-start;
flex-wrap: wrap;
}
.card-form__group .card-input__input {
flex: 1;
margin-right: 15px;
}
.card-form__group .card-input__input:last-child {
margin-right: 0;
}
.card-form__button {
width: 100%;
height: 55px;
background: #2364d2;
border: none;
border-radius: 5px;
font-size: 22px;
font-weight: 500;
font-family: "Source Sans Pro", sans-serif;
box-shadow: 3px 10px 20px 0px rgba(35, 100, 210, 0.3);
color: #fff;
margin-top: 20px;
cursor: pointer;
}
@media screen and (max-width: 480px) {
.card-form__button {
margin-top: 10px;
}
}
.card-item {
max-width: 430px;
height: 270px;
margin-left: auto;
margin-right: auto;
position: relative;
z-index: 2;
width: 100%;
}
@media screen and (max-width: 480px) {
.card-item {
max-width: 310px;
height: 220px;
width: 90%;
}
}
@media screen and (max-width: 360px) {
.card-item {
height: 180px;
}
}
.card-item.-active .card-item__side.-front {
transform: perspective(1000px) rotateY(180deg) rotateX(0deg) rotateZ(0deg);
}
.card-item.-active .card-item__side.-back {
transform: perspective(1000px) rotateY(0) rotateX(0deg) rotateZ(0deg);
}
.card-item__focus {
position: absolute;
z-index: 3;
border-radius: 5px;
left: 0;
top: 0;
width: 100%;
height: 100%;
transition: all 0.35s cubic-bezier(0.71, 0.03, 0.56, 0.85);
opacity: 0;
pointer-events: none;
overflow: hidden;
border: 2px solid rgba(255, 255, 255, 0.65);
}
.card-item__focus:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
background: #08142f;
height: 100%;
border-radius: 5px;
filter: blur(25px);
opacity: 0.5;
}
.card-item__focus.-active {
opacity: 1;
}
.card-item__side {
border-radius: 15px;
overflow: hidden;
box-shadow: 0 20px 60px 0 rgba(14, 42, 90, 0.55);
transform: perspective(2000px) rotateY(0deg) rotateX(0deg) rotate(0deg);
transform-style: preserve-3d;
transition: all 0.8s cubic-bezier(0.71, 0.03, 0.56, 0.85);
backface-visibility: hidden;
height: 100%;
}
.card-item__side.-back {
position: absolute;
top: 0;
left: 0;
width: 100%;
transform: perspective(2000px) rotateY(-180deg) rotateX(0deg) rotate(0deg);
z-index: 2;
padding: 0;
height: 100%;
}
.card-item__side.-back .card-item__cover {
transform: rotateY(-180deg);
}
.card-item__bg {
max-width: 100%;
display: block;
max-height: 100%;
height: 100%;
width: 100%;
object-fit: cover;
}
.card-item__cover {
height: 100%;
background-color: #1c1d27;
position: absolute;
height: 100%;
background-color: #1c1d27;
left: 0;
top: 0;
width: 100%;
border-radius: 15px;
overflow: hidden;
}
.card-item__cover:after {
content: "";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(6, 2, 29, 0.45);
}
.card-item__top {
display: flex;
align-items: flex-start;
justify-content: space-between;
margin-bottom: 40px;
padding: 0 10px;
}
@media screen and (max-width: 480px) {
.card-item__top {
margin-bottom: 25px;
}
}
@media screen and (max-width: 360px) {
.card-item__top {
margin-bottom: 15px;
}
}
.card-item__chip {
width: 60px;
}
@media screen and (max-width: 480px) {
.card-item__chip {
width: 50px;
}
}
@media screen and (max-width: 360px) {
.card-item__chip {
width: 40px;
}
}
.card-item__type {
height: 45px;
position: relative;
display: flex;
justify-content: flex-end;
max-width: 100px;
margin-left: auto;
width: 100%;
}
@media screen and (max-width: 480px) {
.card-item__type {
height: 40px;
max-width: 90px;
}
}
@media screen and (max-width: 360px) {
.card-item__type {
height: 30px;
}
}
.card-item__typeImg {
max-width: 100%;
object-fit: contain;
max-height: 100%;
object-position: top right;
}
.card-item__info {
color: #fff;
width: 100%;
max-width: calc(100% - 85px);
padding: 10px 15px;
font-weight: 500;
display: block;
cursor: pointer;
}
@media screen and (max-width: 480px) {
.card-item__info {
padding: 10px;
}
}
.card-item__holder {
opacity: 0.7;
font-size: 13px;
margin-bottom: 6px;
}
@media screen and (max-width: 480px) {
.card-item__holder {
font-size: 12px;
margin-bottom: 5px;
}
}
.card-item__wrapper {
font-family: "Source Code Pro", monospace;
padding: 25px 15px;
position: relative;
z-index: 4;
height: 100%;
text-shadow: 7px 6px 10px rgba(14, 42, 90, 0.8);
user-select: none;
}
@media screen and (max-width: 480px) {
.card-item__wrapper {
padding: 20px 10px;
}
}
.card-item__name {
font-size: 18px;
line-height: 1;
white-space: nowrap;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
text-transform: uppercase;
}
@media screen and (max-width: 480px) {
.card-item__name {
font-size: 16px;
}
}
.card-item__nameItem {
display: inline-block;
min-width: 8px;
position: relative;
}
.card-item__number {
font-weight: 500;
line-height: 1;
color: #fff;
font-size: 27px;
margin-bottom: 35px;
display: inline-block;
padding: 10px 15px;
cursor: pointer;
}
@media screen and (max-width: 480px) {
.card-item__number {
font-size: 21px;
margin-bottom: 15px;
padding: 10px 10px;
}
}
@media screen and (max-width: 360px) {
.card-item__number {
font-size: 19px;
margin-bottom: 10px;
padding: 10px 10px;
}
}
.card-item__numberItem {
width: 16px;
display: inline-block;
}
.card-item__numberItem.-active {
width: 30px;
}
@media screen and (max-width: 480px) {
.card-item__numberItem {
width: 13px;
}
.card-item__numberItem.-active {
width: 16px;
}
}
@media screen and (max-width: 360px) {
.card-item__numberItem {
width: 12px;
}
.card-item__numberItem.-active {
width: 8px;
}
}
.card-item__content {
color: #fff;
display: flex;
align-items: flex-start;
}
.card-item__date {
flex-wrap: wrap;
font-size: 18px;
margin-left: auto;
padding: 10px;
display: inline-flex;
width: 80px;
white-space: nowrap;
flex-shrink: 0;
cursor: pointer;
}
@media screen and (max-width: 480px) {
.card-item__date {
font-size: 16px;
}
}
.card-item__dateItem {
position: relative;
}
.card-item__dateItem span {
width: 22px;
display: inline-block;
}
.card-item__dateTitle {
opacity: 0.7;
font-size: 13px;
padding-bottom: 6px;
width: 100%;
}
@media screen and (max-width: 480px) {
.card-item__dateTitle {
font-size: 12px;
padding-bottom: 5px;
}
}
.card-item__band {
background: rgba(0, 0, 19, 0.8);
width: 100%;
height: 50px;
margin-top: 30px;
position: relative;
z-index: 2;
}
@media screen and (max-width: 480px) {
.card-item__band {
margin-top: 20px;
}
}
@media screen and (max-width: 360px) {
.card-item__band {
height: 40px;
margin-top: 10px;
}
}
.card-item__cvv {
text-align: right;
position: relative;
z-index: 2;
padding: 15px;
}
.card-item__cvv .card-item__type {
opacity: 0.7;
}
@media screen and (max-width: 360px) {
.card-item__cvv {
padding: 10px 15px;
}
}
.card-item__cvvTitle {
padding-right: 10px;
font-size: 15px;
font-weight: 500;
color: #fff;
margin-bottom: 5px;
}
.card-item__cvvBand {
height: 45px;
background: #fff;
margin-bottom: 30px;
text-align: right;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 10px;
color: #1a3b5d;
font-size: 18px;
border-radius: 4px;
box-shadow: 0px 10px 20px -7px rgba(32, 56, 117, 0.35);
}
@media screen and (max-width: 480px) {
.card-item__cvvBand {
height: 40px;
margin-bottom: 20px;
}
}
@media screen and (max-width: 360px) {
.card-item__cvvBand {
margin-bottom: 15px;
}
}
.card-list {
margin-bottom: -130px;
}
@media screen and (max-width: 480px) {
.card-list {
margin-bottom: -120px;
}
}
.card-input {
margin-bottom: 20px;
}
.card-input__label {
font-size: 14px;
margin-bottom: 5px;
font-weight: 500;
color: #1a3b5d;
width: 100%;
display: block;
user-select: none;
}
.card-input__input {
width: 100%;
height: 50px;
border-radius: 5px;
box-shadow: none;
border: 1px solid #ced6e0;
transition: all 0.3s ease-in-out;
font-size: 18px;
padding: 5px 15px;
background: none;
color: #1a3b5d;
font-family: "Source Sans Pro", sans-serif;
}
.card-input__input:hover, .card-input__input:focus {
border-color: #3d9cff;
}
.card-input__input:focus {
box-shadow: 0px 10px 20px -13px rgba(32, 56, 117, 0.35);
}
.card-input__input.-select {
-webkit-appearance: none;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAeCAYAAABuUU38AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAUxJREFUeNrM1sEJwkAQBdCsngXPHsQO9O5FS7AAMVYgdqAd2IGCDWgFnryLFQiCZ8EGnJUNimiyM/tnk4HNEAg/8y6ZmMRVqz9eUJvRaSbvutCZ347bXVJy/ZnvTmdJ862Me+hAbZCTs6GHpyUi1tTSvPnqTpoWZPUa7W7ncT3vK4h4zVejy8QzM3WhVUO8ykI6jOxoGA4ig3BLHcNFSCGqGAkig2yqgpEiMsjSfY9LxYQg7L6r0X6wS29YJiYQYecemY+wHrXD1+bklGhpAhBDeu/JfIVGxaAQ9sb8CI+CQSJ+QmJg0Ii/EE2MBiIXooHRQhRCkBhNhBcEhLkwf05ZCG8ICCOpk0MULmvDSY2M8UawIRExLIQIEgHDRoghihgRIgiigBEjgiFATBACAgFgghEwSAAGgoBCBBgYAg5hYKAIFYgHBo6w9RRgAFfy160QuV8NAAAAAElFTkSuQmCC");
background-size: 12px;
background-position: 90% center;
background-repeat: no-repeat;
padding-right: 30px;
}
.slide-fade-up-enter-active {
transition: all 0.25s ease-in-out;
transition-delay: 0.1s;
position: relative;
}
.slide-fade-up-leave-active {
transition: all 0.25s ease-in-out;
position: absolute;
}
.slide-fade-up-enter {
opacity: 0;
transform: translateY(15px);
pointer-events: none;
}
.slide-fade-up-leave-to {
opacity: 0;
transform: translateY(-15px);
pointer-events: none;
}
.slide-fade-right-enter-active {
transition: all 0.25s ease-in-out;
transition-delay: 0.1s;
position: relative;
}
.slide-fade-right-leave-active {
transition: all 0.25s ease-in-out;
position: absolute;
}
.slide-fade-right-enter {
opacity: 0;
transform: translateX(10px) rotate(45deg);
pointer-events: none;
}
.slide-fade-right-leave-to {
opacity: 0;
transform: translateX(-10px) rotate(45deg);
pointer-events: none;
}
.github-btn {
position: absolute;
right: 40px;
bottom: 50px;
text-decoration: none;
padding: 15px 25px;
border-radius: 4px;
box-shadow: 0px 4px 30px -6px rgba(36, 52, 70, 0.65);
background: #24292e;
color: #fff;
font-weight: bold;
letter-spacing: 1px;
font-size: 16px;
text-align: center;
transition: all 0.3s ease-in-out;
}
@media screen and (min-width: 500px) {
.github-btn:hover {
transform: scale(1.1);
box-shadow: 0px 17px 20px -6px rgba(36, 52, 70, 0.36);
}
}
@media screen and (max-width: 700px) {
.github-btn {
position: relative;
bottom: auto;
right: auto;
margin-top: 20px;
}
.github-btn:active {
transform: scale(1.1);
box-shadow: 0px 17px 20px -6px rgba(36, 52, 70, 0.36);
}
}
Scripts
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://unpkg.com/vue-the-mask@0.11.1/dist/vue-the-mask.js"></script>
Javascript
/*
See on github: https://github.com/muhammederdem/credit-card-form
*/
new Vue({
el: "#app",
data() {
return {
currentCardBackground: Math.floor(Math.random()* 25 + 1), // just for fun :D
cardName: "",
cardNumber: "",
cardMonth: "",
cardYear: "",
cardCvv: "",
minCardYear: new Date().getFullYear(),
amexCardMask: "#### ###### #####",
otherCardMask: "#### #### #### ####",
cardNumberTemp: "",
isCardFlipped: false,
focusElementStyle: null,
isInputFocused: false
};
},
mounted() {
this.cardNumberTemp = this.otherCardMask;
document.getElementById("cardNumber").focus();
},
computed: {
getCardType () {
let number = this.cardNumber;
let re = new RegExp("^4");
if (number.match(re) != null) return "visa";
re = new RegExp("^(34|37)");
if (number.match(re) != null) return "amex";
re = new RegExp("^5[1-5]");
if (number.match(re) != null) return "mastercard";
re = new RegExp("^6011");
if (number.match(re) != null) return "discover";
re = new RegExp('^9792')
if (number.match(re) != null) return 'troy'
return "visa"; // default type
},
generateCardNumberMask () {
return this.getCardType === "amex" ? this.amexCardMask : this.otherCardMask;
},
minCardMonth () {
if (this.cardYear === this.minCardYear) return new Date().getMonth() + 1;
return 1;
}
},
watch: {
cardYear () {
if (this.cardMonth < this.minCardMonth) {
this.cardMonth = "";
}
}
},
methods: {
flipCard (status) {
this.isCardFlipped = status;
},
focusInput (e) {
this.isInputFocused = true;
let targetRef = e.target.dataset.ref;
let target = this.$refs[targetRef];
this.focusElementStyle = {
width: `${target.offsetWidth}px`,
height: `${target.offsetHeight}px`,
transform: `translateX(${target.offsetLeft}px) translateY(${target.offsetTop}px)`
}
},
blurInput() {
let vm = this;
setTimeout(() => {
if (!vm.isInputFocused) {
vm.focusElementStyle = null;
}
}, 300);
vm.isInputFocused = false;
}
}
});
External Link for Card Form Design, Very Slick and Rounded
Add Comment
Other Items in forms
Related Search Terms
Other Categories in Code
404 pages animation animations background effects boxes buttons css css & javascript css animation css animations css backgrounds css cursors css framework css frameworks css modal css positions css reset css shadows css slider css text effects css text formatting css tips css tools css z-index content slider cookie alerts design html css sections html canvas html sections icons image zoom interactive images lightbox link effects loading animation modals mouse effects navigation notifications parallax profiles quick css seo sections text ui web developer checklists animations backgrounds bootstrap buttons css css animated css animations css framework css grid footers forms html image effects images javascript scroll effects sections show your work svg text animation timeline
css animations
css animations
HTML Canvas
javascript