
Card with Expanding Effect
Before We Start to Create Card with Expanding Effect
Card with Expanding Effect can be used to animate a section with images or any other media content and create user attractive UI components with cards.
So if you are a person who wishes to develop a website, you have to know how to create animations properly. Check out our tutorial and you can learn this techniques and use it on your web development. Below sections shows how to develop this animations.
How to create Card with Expanding Effect? We are here to solve your problem. In this article we discuss how to create a hover effect animations. Before we start please read the below articles which easier you to understand the process, if you are new to development.
Step 1 – Add HTML
It’s too easy and simple. Just copy and paste below code in your HTML editor between <body> </body> tag as below.
<body>
<div class="container">
<div class="card-column column-0">
<div class="card card-color-0">
<div class="border"></div>
<img src="https://pixabay.com/get/g7bf4d66835e1d3d70db65125897964719d86fb69eada563d6ac37b530d06008845b05908646ab2d0a2911f88449a8d3b64a60a325edf41df502f26a9a42c3bc9_1280.jpg" alt="Image" />
<h1>Here You Can Put Your Title</h1>
</div>
<div class="card card-color-2">
<div class="border"></div>
<img src="https://pixabay.com/get/g1e4ed6620ba6aec32c46a142b20df41b1d9366f9f1b8e09e5746d1746fdc1d0f0257eea848a00607c13d2137e1aeedb82b72003adc606cd863bc098fe76a9e49_1280.jpg" alt="Image" />
<h1>Here You Can Put Your Title</h1>
</div>
</div>
<div class="card-column column-1">
<div class="card card-color-1">
<div class="border"></div>
<img src="https://pixabay.com/get/g1d0ae50428970a9935f12dcd07eb6f04d2270ee04e64f5b7985ba7b6cf0892e9dccad6981a029a886b25d7eb3aad9570f8c0cfc4f8d223df28f3783fa31404a8_1280.jpg" alt="Image" />
<h1>Here You Can Put Your Title</h1>
</div>
<div class="card card-color-3">
<div class="border"></div>
<img src="https://pixabay.com/get/g5a3f4d76ddf32547ac385eb6188e9f95ea1eed2a9531833ca6f299643e98542e758b519ca71e811815d4624ab389c6a055bf5f6856864bc447226036d73488f3_1280.jpg" alt="Image" />
<h1>Here You Can Put Your Title</h1>
</div>
</div>
</div>
<div id="cover" class="cover"></div>
<div id="open-content" class="open-content">
<a href="#" id="close-content" class="close-content"><span class="x-1"></span><span class="x-2"></span></a>
<img id="open-content-image" src="" />
<div class="text" id="open-content-text">
</div>
</div>
</body>
Step 2 – Add CSS
Copy and paste below code in your HTML editor between <style></style> tag as below.
<style>
body {
background: #0e002b;
font-size: 18px;
}
p {
line-height: 1.5;
}
.container {
max-width: 800px;
margin: 0 auto;
}
/* Cards */
.card-column {
width: 50%;
float: left;
padding: 4%;
box-sizing: border-box;
}
.column-1 {
padding-top: 100px;
}
.card {
width: 92%;
max-width: 340px;
margin-left: auto;
margin-right: auto;
position: relative;
background: #eb5160;
color: #fff;
cursor: pointer;
margin-bottom: 60px;
}
.border {
position: absolute;
width: 100%;
height: 100%;
padding: 6px;
border: 1px solid #fff;
opacity: 0.5;
left: -6px;
top: -6px;
}
.card h1 {
color: #fff;
font-size: 52px;
position: relative;
padding: 190px 0px 43px 10px;
width: 97%;
}
.card>img {
width: 90%;
position: absolute;
top: -6%;
left: -6%;
}
.card-color-0 {
background-color: #eb5160;
}
.card-color-1 {
background-color: #8f3985;
}
.card-color-2 {
background-color: #8daa91;
}
.card-color-3 {
background-color: #888da7;
}
/* The cover (expanding background) */
.cover {
position: fixed;
background: #eb5160;
z-index: 100;
transform-origin: 50% 50%;
}
/* The open page content */
.open-content {
width: 100%;
z-index: 110;
position: absolute;
opacity: 0;
pointer-events: none;
}
.open-content img {
position: relative;
width: 90%;
margin-left: 3%;
margin-top: 20px;
z-index: 5;
}
.open-content .text {
background: #fff;
margin-top: -56%;
padding: 60% 5% 5% 5%;
width: 80%;
margin-left: 5%;
margin-bottom: 5%;
}
.open-content .text h1,
.open-content .text p {
max-width: 700px;
margin-left: auto;
margin-right: auto;
}
.close-content {
display: block;
position: absolute;
right: 12px;
top: 12px;
width: 30px;
height: 30px;
}
.close-content span {
background: #222;
width: 30px;
height: 6px;
display: block;
position: absolute;
top: 14px;
}
.x-1 {
transform: rotate(45deg);
}
.x-2 {
transform: rotate(-45deg);
}
/* Transitions */
.card {
transition: opacity 200ms linear 320ms, transform 200ms ease-out 320ms;
}
.border {
transition: opacity 200ms linear, transform 200ms ease-out;
}
.card img {
transition: opacity 200ms linear 0ms, transform 200ms ease-in 0ms;
}
.card h1 {
transform: translate3d(20%, 0px, 0px);
transition: opacity 200ms linear 120ms, transform 200ms ease-in 120ms;
}
/* Clicked card */
.card.clicked img {
transform: translate3d(0px, -40px, 0px);
opacity: 0;
}
.card.clicked .border {
opacity: 0;
transform: scale(1.3);
}
.card.out,
.card.out img {
transform: translate3d(0px, -40px, 0px);
opacity: 0;
}
.card.out h1,
.card.clicked h1 {
transform: translate3d(20%, -40px, 0px);
opacity: 0;
}
.cover {
transition: transform 300ms ease-in-out;
}
.open-content {
transition: opacity 200ms linear 0ms;
}
.open-content.open {
opacity: 1;
pointer-events: all;
transition-delay: 1000ms;
}
@media screen and (max-width: 600px) {
.card-column {
width: 90%;
}
.column-1 {
padding-top: 0px;
}
.open-content img {
margin-top: 40px;
}
}
</style>
At the end we will have something like this. You can change fonts, colors, backgrounds and all things that you want. Enjoy it.
Step 3 – Add JavaScript
Copy and paste below code in your HTML editor between <script></script> tag.
<script>
// listing vars here so they're in the global scope
var cards,
nCards,
cover,
openContent,
openContentText,
pageIsOpen = false,
openContentImage,
closeContent,
windowWidth,
windowHeight,
currentCard;
// initiate the process
init();
function init() {
resize();
selectElements();
attachListeners();
}
// select all the elements in the DOM that are going to be used
function selectElements() {
(cards = document.getElementsByClassName("card")),
(nCards = cards.length),
(cover = document.getElementById("cover")),
(openContent = document.getElementById("open-content")),
(openContentText = document.getElementById("open-content-text")),
(openContentImage = document.getElementById("open-content-image"));
closeContent = document.getElementById("close-content");
}
/* Attaching three event listeners here:
- a click event listener for each card
- a click event listener to the close button
- a resize event listener on the window
*/
function attachListeners() {
for (var i = 0; i < nCards; i++) {
attachListenerToCard(i);
}
closeContent.addEventListener("click", onCloseClick);
window.addEventListener("resize", resize);
}
function attachListenerToCard(i) {
cards[i].addEventListener("click", function(e) {
var card = getCardElement(e.target);
onCardClick(card, i);
});
}
/* When a card is clicked */
function onCardClick(card, i) {
// set the current card
currentCard = card;
// add the 'clicked' class to the card, so it animates out
currentCard.className += " clicked";
// animate the card 'cover' after a 500ms delay
setTimeout(function() {
animateCoverUp(currentCard);
}, 500);
// animate out the other cards
animateOtherCards(currentCard, true);
// add the open class to the page content
openContent.className += " open";
}
/*
* This effect is created by taking a separate 'cover' div, placing
* it in the same position as the clicked card, and animating it to
* become the background of the opened 'page'.
* It looks like the card itself is animating in to the background,
* but doing it this way is more performant (because the cover div is
* absolutely positioned and has no children), and there's just less
* having to deal with z-index and other elements in the card
*/
function animateCoverUp(card) {
// get the position of the clicked card
var cardPosition = card.getBoundingClientRect();
// get the style of the clicked card
var cardStyle = getComputedStyle(card);
setCoverPosition(cardPosition);
setCoverColor(cardStyle);
scaleCoverToFillWindow(cardPosition);
// update the content of the opened page
openContentText.innerHTML =
"<h1>" + card.children[2].textContent + "</h1>" + paragraphText;
openContentImage.src = card.children[1].src;
setTimeout(function() {
// update the scroll position to 0 (so it is at the top of the 'opened' page)
window.scroll(0, 0);
// set page to open
pageIsOpen = true;
}, 300);
}
function animateCoverBack(card) {
var cardPosition = card.getBoundingClientRect();
// the original card may be in a different position, because of scrolling, so the cover position needs to be reset before scaling back down
setCoverPosition(cardPosition);
scaleCoverToFillWindow(cardPosition);
// animate scale back to the card size and position
cover.style.transform =
"scaleX(" +
1 +
") scaleY(" +
1 +
") translate3d(" +
0 +
"px, " +
0 +
"px, 0px)";
setTimeout(function() {
// set content back to empty
openContentText.innerHTML = "";
openContentImage.src = "";
// style the cover to 0x0 so it is hidden
cover.style.width = "0px";
cover.style.height = "0px";
pageIsOpen = false;
// remove the clicked class so the card animates back in
currentCard.className = currentCard.className.replace(" clicked", "");
}, 301);
}
function setCoverPosition(cardPosition) {
// style the cover so it is in exactly the same position as the card
cover.style.left = cardPosition.left + "px";
cover.style.top = cardPosition.top + "px";
cover.style.width = cardPosition.width + "px";
cover.style.height = cardPosition.height + "px";
}
function setCoverColor(cardStyle) {
// style the cover to be the same color as the card
cover.style.backgroundColor = cardStyle.backgroundColor;
}
function scaleCoverToFillWindow(cardPosition) {
// calculate the scale and position for the card to fill the page,
var scaleX = windowWidth / cardPosition.width;
var scaleY = windowHeight / cardPosition.height;
var offsetX =
(windowWidth / 2 - cardPosition.width / 2 - cardPosition.left) / scaleX;
var offsetY =
(windowHeight / 2 - cardPosition.height / 2 - cardPosition.top) / scaleY;
// set the transform on the cover - it will animate because of the transition set on it in the CSS
cover.style.transform =
"scaleX(" +
scaleX +
") scaleY(" +
scaleY +
") translate3d(" +
offsetX +
"px, " +
offsetY +
"px, 0px)";
}
/* When the close is clicked */
function onCloseClick() {
// remove the open class so the page content animates out
openContent.className = openContent.className.replace(" open", "");
// animate the cover back to the original position card and size
animateCoverBack(currentCard);
// animate in other cards
animateOtherCards(currentCard, false);
}
function animateOtherCards(card, out) {
var delay = 100;
for (var i = 0; i < nCards; i++) {
// animate cards on a stagger, 1 each 100ms
if (cards[i] === card) continue;
if (out) animateOutCard(cards[i], delay);
else animateInCard(cards[i], delay);
delay += 100;
}
}
// animations on individual cards (by adding/removing card names)
function animateOutCard(card, delay) {
setTimeout(function() {
card.className += " out";
}, delay);
}
function animateInCard(card, delay) {
setTimeout(function() {
card.className = card.className.replace(" out", "");
}, delay);
}
// this function searches up the DOM tree until it reaches the card element that has been clicked
function getCardElement(el) {
if (el.className.indexOf("card ") > -1) return el;
else return getCardElement(el.parentElement);
}
// resize function - records the window width and height
function resize() {
if (pageIsOpen) {
// update position of cover
var cardPosition = currentCard.getBoundingClientRect();
setCoverPosition(cardPosition);
scaleCoverToFillWindow(cardPosition);
}
windowWidth = window.innerWidth;
windowHeight = window.innerHeight;
}
var paragraphText =
"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>";
</script>

Video Tutorial
Please watch this video to better understand this tutorial and don’t forget to subscribe to our channel.
Help others to find out about this article on Social Media sites. If you have any doubt or any problem, don’t hesitate to contact us. Thereafter we will be able to help you and also make sure you bookmark our site on your browser.