I am playing around with jQuery and CSS3 animations and noticed something weird happening. On my pen, when you hover over the card or focus on the CCV field, when the card flips over it takes a second for the colour to pull through. It almost looks like its loading. Anyone aware of what might be happening here? I only started working jQuery so ignore that code, unless thats whats causing the issues.
codepen: https://codepen.io/maciekmat/pen/MWWVPqX
HTML
<div class="page-container">
<h1>Fill in your card details</h1>
<div class="card-scene">
<div class="card-container">
<div class="card card-front">
<div class="card-numbers">
<p id="cardNumber4">0000</p>
<p id="cardNumber8">0000</p>
<p id="cardNumber12">0000</p>
<p id="cardNumber16">0000</p>
</div>
<p id="cardName">M J SMITH</p>
<div class="sortcode-numbers">
<p id="cardSortCode1">00</p>
<p id="cardSortCode2">00</p>
<p id="cardSortCode3">00</p>
</div>
</div>
<div class="card card-back">
<div class="black-strip"></div>
<div class="ccv-strip">
<p id="cardCcvNum">000</p>
</div>
</div>
</div>
</div>
<form action="">
<label>Account Holder Name</label>
<input type="text" id="cardNameField" class="card-name" required></input>
<label>Card Number</label>
<div class="cardnumber-container">
<input type="text" id="cardField4" maxlength="4" minlength="4" class="card-number" required></input>
<input type="text" id="cardField8" maxlength="4" class="card-number" required></input>
<input type="text" id="cardField12" maxlength="4" class="card-number" required></input>
<input type="text" id="cardField16" maxlength="4" class="card-number" required></input>
</div>
<div class="card-numbers-wrap">
<div class="sortcodes-wrap">
<label>Sort Code</label>
<div class="sortcodes">
<input type="text" id="sortCodeFirst" maxlength="2" class="sort-code" required></input>
<input type="text" id="sortCodeSecond" maxlength="2" class="sort-code" required></input>
<input type="text" id="sortCodeThird" maxlength="2" class="sort-code" required></input>
</div>
</div>
<div class="security-code-wrap">
<label>Security Code (CCV)</label>
<input type="text" id="securityCode" maxlength="3" class="security-code" required></input>
</div>
</div>
<button type="submit" id="cardSubmit">Submit</button>
</form>
<!-- <a id="cardSubmit">Submit</a> -->
</div>
CSS:
*{
box-sizing: border-box;
}
p, a, h1{
padding: 0;
margin: 0;
}
body{
font-family: 'Quicksand', sans-serif;
}
.page-container{
width: 350px;
margin: auto;
display: flex;
flex-direction: column;
}
.card-scene{
perspective: 600px;
}
.card{
position: absolute;
margin-top: 1em;
width: 100%;
height: 200px;
display: flex;
flex-direction: column;
justify-content: flex-end;
border-radius: 8px;
padding: 0 0 26px 40px;
transition:all .5s ease;
backface-visibility: hidden;
p{
margin-right: 12px;
letter-spacing: 4px;
margin-top: 5px;
}
#cardName{
margin-top: 22px;
text-transform: uppercase;
}
}
.card-container{
width: 100%;
height: 100%;
transition: transform 1s;
transform-style: preserve-3d;
cursor: pointer;
position: relative;
}
.card-container.is-flipped {
transform: rotateY(180deg);
}
.card-front{
background: rgb(228,228,228);
background: linear-gradient(90deg, rgba(228,228,228,1) 0%, rgba(207,207,207,1) 50%, rgba(132,18,189,1) 50%, rgba(20,106,162,1) 100%);
background-size: 200% 100%;
background-position: left bottom;
}
.card-back{
transform: rotateY(180deg);
background: rgb(228,228,228);
background: linear-gradient(90deg, rgba(228,228,228,1) 0%, rgba(207,207,207,1) 50%, rgba(20,106,162,1) 50%, rgba(132,18,189,1) 100%);
background-size: 200% 100%;
background-position: left bottom;
}
.card-numbers{
display: flex;
flex-direction: row;
}
.sortcode-numbers{
display: flex;
flex-direction: row;
p{
margin: 0;
}
p::after{
content: "-";
margin: 0 5px;
}
p:last-child::after{
content: "";
}
}
form{
margin-top: 14em;
width: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
}
input{
margin: 1em 0 0;
padding: 14px;
border: 1px solid lightgrey;
border-radius: 5px;
text-align: center;
font-size: 16px;
}
input:focus{
transition: .2s ease;
outline: none !important;
border:1px solid #4d3db0;
box-shadow: 0 0 8px rgba(132,18,189, 0.3);
}
.cardnumber-container{
display: flex;
justify-content: space-between;
}
.card-number{
width: 23%;
}
.card-name{
width: 100%;
text-align: left;
text-transform: uppercase;
}
label{
padding-left: 5px;
margin-top: 1em;
}
.sortcodes{
display: flex;
flex-direction: row;
}
.sortcodes-wrap{
display: flex;
flex-direction: column;
width: 50%;
}
.sort-code{
width: 50px;
margin-right: 10px;
}
.security-code{
width: 70px;
}
.security-code-wrap{
width: 50%;
display: flex;
flex-direction: column;
align-items: flex-end;
}
.card-numbers-wrap{
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%;
}
#cardSubmit{
background: lightgrey;
padding: 13px 28px;
border-radius: 5px;
margin-top: 2em;
cursor: pointer;
}
.black-strip{
position: absolute;
top: 20px;
left: 0;
width: 100%;
height: 40px;
background: black;
}
.ccv-strip{
position: absolute;
top: 70px;
left: 10px;
width: 250px;
height: 35px;
background: white;
p{
float: right;
margin-top: 7px;
}
}
jQuery:
$("#cardSubmit").on("click", function (e) {
e.preventDefault();
// Grab entered card number fields
const cardNumberFirst = $("#cardField4").val();
const cardNumberSecond = $("#cardField8").val();
const cardNumberThird = $("#cardField12").val();
const cardNumberFourth = $("#cardField16").val();
// Grab entered sort code number fields
const sortCodeFirst = $("#sortCodeFirst").val();
const sortCodeSecond = $("#sortCodeSecond").val();
const sortCodeThird = $("#sortCodeThird").val();
// Grab entered name field
const cardName = $("#cardNameField").val();
// Print the entered values onto the card
$("#cardNumber4").html(cardNumberFirst);
$("#cardNumber8").html(cardNumberSecond);
$("#cardNumber12").html(cardNumberThird);
$("#cardNumber16").html(cardNumberFourth);
$("#cardSortCode1").html(sortCodeFirst);
$("#cardSortCode2").html(sortCodeSecond);
$("#cardSortCode3").html(sortCodeThird);
$("#cardName").html(cardName);
// Change colour of card
$(".card-front, .card-back").css({
"background-position": "right bottom",
color: "white"
});
});
$(".card-number").keyup(function () {
if (this.value.length == this.maxLength) {
$(this)
.next(".card-number")
.focus();
}
});
$(".sort-code").keyup(function () {
if (this.value.length == this.maxLength) {
$(this)
.next(".sort-code")
.focus();
}
});
$(".card-container").hover(function () {
$(this).toggleClass("is-flipped");
});
$('#securityCode').focusin(function () {
$('.card-container').addClass("is-flipped");
});
$('#securityCode').focusout(function () {
$('.card-container').removeClass("is-flipped");
});
If you are referring to the flickering that occurs when the card flips over causing a pause. Primarily on Chrome.
Then I believe the issue is that you have absolutely positioned elements on the rear of the card that cause issues with the transorm until it completes.
I have removed the absolute positioning of black-strip
and ccv-strip
. The transition is a lot smoother now. Obviously you will need to position these elements via other means. (Flex should work fine).
$(".card-container").hover(function() {
$(this).toggleClass("is-flipped");
});
.page-container {
width: 350px;
margin: auto;
display: flex;
flex-direction: column;
}
.card-scene {
perspective: 600px;
}
.card {
position: absolute;
margin-top: 1em;
width: 100%;
height: 200px;
display: flex;
flex-direction: column;
justify-content: flex-end;
border-radius: 8px;
padding: 0 0 26px 40px;
transition: all .5s ease;
backface-visibility: hidden;
}
.card-container {
width: 100%;
height: 100%;
transition: transform 1s;
transform-style: preserve-3d;
cursor: pointer;
position: relative;
}
.card-container.is-flipped {
transform: rotateY(180deg);
}
.card-front {
background: rgb(228, 228, 228);
background: linear-gradient(90deg, rgba(228, 228, 228, 1) 0%, rgba(207, 207, 207, 1) 50%, rgba(132, 18, 189, 1) 50%, rgba(20, 106, 162, 1) 100%);
background-size: 200% 100%;
background-position: left bottom;
}
.card-back {
transform: rotateY(180deg);
background: rgb(228, 228, 228);
background: linear-gradient(90deg, rgba(228, 228, 228, 1) 0%, rgba(207, 207, 207, 1) 50%, rgba(20, 106, 162, 1) 50%, rgba(132, 18, 189, 1) 100%);
background-size: 200% 100%;
background-position: left bottom;
}
.card-numbers {
display: flex;
flex-direction: row;
}
.sortcode-numbers {
display: flex;
flex-direction: row;
}
.cardnumber-container {
display: flex;
justify-content: space-between;
}
.black-strip {
width: 100%;
height: 40px;
background: black;
}
.ccv-strip {
width: 250px;
height: 35px;
background: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="page-container">
<div class="card-scene">
<div class="card-container">
<div class="card card-front">
</div>
<div class="card card-back">
<div class="black-strip"></div>
<div class="ccv-strip">
<p id="cardCcvNum">000</p>
</div>
</div>
</div>
</div>
</div>