Hey Programmers! In this post, we will make Glassmorphism hover card animation with pure HTML & CSS. We will see how we can create a glass morphism effect easily & how we can add a smooth hover effect to the cards & make it eye catchy.
These can be useful when we create modern-looking websites like modern admin pannel, pricing cards, services cards, etc. We will understand the code step by step & how we can use a glass-morphism hover effect that will provide visual feedback, guiding users and making the experience more dynamic.
Also Read: Animated Wallet card with HTML & CSS
<!DOCTYPE html>
declaration defines the document type and HTML version.<html lang="en">
starts the HTML document and sets the language to English.<head>
contains meta-information about the document, including character set and viewport settings for responsive design.<body>
is where the main content is placed. <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
div
with the class container
serves as the main wrapper for the card element.div
with the class card
and show
class, which will animate on scroll. It also has data attributes (data-tilt
, data-tilt-glare
, data-tilt-scale
) which suggests the use of a tilt effect library for 3D tilt effects. <div class="container">
<div class="card show tilt-logo" data-tilt data-tilt-glare="true" data-tilt-scale="1.1">
<div class="content show">
h1
with the text “01”, an h3
with the text “Card One”, a p
element with placeholder text, and an anchor a
for a “Read More” link. <h1>01</h1>
<h3>Card One</h3>
<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Nam alias, eum sint sunt reprehenderit ex cum assumenda sed accusantium architecto asperiores</p>
<a href="#">Read More</a>
</div>
</div>
</div>
body
and html
tags complete the HTML structure. </body>
</html>
Also Read: Gradient Glowing Cards With Hover Effect
@import
rule imports the “Poppins” font from Google Fonts. @import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;1,100;1,200&display=swap');
*
resets margins, and padding, and sets the box sizing to border-box
. It also applies the “Poppins” font to all elements. * {
margin: 0px;
padding: 0px;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body
is styled to center its content both vertically and horizontally using flexbox
. The background color is set to a dark shade, and horizontal overflow is hidden. body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #161623;
overflow-x: hidden;
}
.container
class has pseudo-elements ::before
and ::after
that create circular animations in the background. These are styled with radial gradients and positioned using fixed positioning. .container:after,
.container:before{
animation: orbit 5s linear infinite;
border-radius: 50%;
box-shadow: 0 0 1rem 0 rgba(0, 0, 0, 0.2);
content: '';
height: 150px;
position: fixed;
width: 150px;
}
.container:before {
background: radial-gradient(to bottom left, #ffe897, #f98a05);
right: 60%;
top: 150px;
}
.container:after {
animation-delay: 2.5s;
background: radial-gradient(to top left, #e0e793, #6dd0f1);
right: 30%;
top: 350px;
z-index: -1;
}
.card
class styles the card with a fixed size, box-shadow, rounded corners, and a semi-transparent background. It uses backdrop-filter
for a blur effect and animates its transform
property to slide in from the right or left. The transition
makes the slide-in animation smooth. .container .card {
position: relative;
width: 300px;
height: 400px;
margin: 30px;
box-shadow: 20px 20px 50px rgba(0, 0, 0, 0.5);
border-radius: 15px;
background-color: rgba(255, 255, 255, 0.1);
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid rgba(255, 255, 255, 0.5);
border-left: 1px solid rgba(255, 255, 255, 0.5);
backdrop-filter: blur(5px);
transform: translateX(400%);
transition: transform 0.5s ease;
}
.content
class styles the content inside the card, with a centered text alignment, padding, and an initial transform to slide up. It also sets the initial opacity to zero, making it invisible until the card is hovered over. .container .card .content {
padding: 20px;
text-align: center;
transform: translateY(100px);
opacity: 0;
transition: 0.5s;
}
.content
transforms to its original position and becomes fully opaque. .container .card:hover .content {
transform:translateY(0px);
opacity: 1;
}
h1
is styled to be very large and positioned outside the card’s top edge, giving a background number effect. The h3
and p
elements are styled with white text and different font sizes and weights. .container .card .content h1 {
position: absolute;
top: -75px;
right: 30px;
font-size: 8em;
color: rgba(255, 255, 255, 0.05);
pointer-events: none;
font-weight: 800;
}
.container .card .content h3 {
font-size: 1.8em;
color: #fff;
font-weight: 300;
}
.container .card .content p {
font-size: 1em;
color: #fff;
font-weight: 300;
}
a
element is styled as a button with padding, a white background, black text, rounded corners, and a shadow for a 3D effect. .container .card .content a {
position: relative;
display: inline-block;
padding: 8px 20px;
margin-top: 15px;
background: #fff;
color: #000;
border-radius: 20px;
text-decoration: none;
font-weight: 500;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.card:nth-of-type(even)
targets every second card, sliding them in from the left. The .show
class resets the transform to slide in from the right or left, depending on the card..card:nth-of-type(even){ transform: translateX(-400%) } .card.show{ transform: translateX(0%); }
@keyframes orbit
animation rotates the pseudo-elements (::before
and ::after
) around a center point, creating a circular orbit effect.@keyframes orbit { from { transform: rotate(0deg) translateX(100px) rotate(0deg); } to { transform: rotate(360deg) translateX(100px) rotate(-360deg); } }
::-webkit-scrollbar { width: 1px; } ::-webkit-scrollbar-track { background: #f1f1f1; } ::-webkit-scrollbar-thumb { background: #888; } ::-webkit-scrollbar-thumb:hover { background: #555; }
document.querySelectorAll(".card")
selects all elements with the class card
and stores them in the cards
variable. const cards = document.querySelectorAll(".card");
window.addEventListener("scroll", checkcards)
adds an event listener for the scroll
event. When the user scrolls, the checkcards
function is called. window.addEventListener("scroll", checkcards);
checkcards
function calculates the triggerBottom
, which is a point 4/5ths of the way down the viewport height. For each card, it checks its position relative to triggerBottom
. If the card’s top edge is above this point, the show
class is added to it, otherwise it is removed. function checkcards() {
const triggerBottom = (window.innerHeight / 5) * 4;
cards.forEach((box) => {
const boxTop = box.getBoundingClientRect().top;
if (boxTop < triggerBottom) {
box.classList.add("show");
} else {
box.classList.remove("show");
}
});
}
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="container">
<div class="card show tilt-logo" data-tilt data-tilt-glare="true" data-tilt-scale="1.1">
<div class="content show">
<h1>01</h1>
<h3>Card One</h3>
<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Nam alias, eum sint sunt reprehenderit ex cum assumenda sed accusantium architecto asperiores</p>
<a href="#">Read More</a>
</div>
</div>
</div>
</body>
</html>
CSS:
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;1,100;1,200&display=swap');
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #161623;
overflow-x: hidden;
}
.container:after,
.container:before{
animation: orbit 5s linear infinite;
border-radius: 50%;
box-shadow: 0 0 1rem 0 rgba(0, 0, 0, 0.2);
content: '';
height: 150px;
position: fixed;
width: 150px;
}
.container:before {
background: #ffe897;
background: -moz-radial-gradient(top right, #ffe897, #f98a05);
background: radial-gradient(to bottom left, #ffe897, #f98a05);
background: -webkit-radial-gradient(top right, #ffe897, #f98a05);
right: 60%;
top: 150px;
}
.container:after {
animation-delay: 2.5s;
background: #e0e793;
background: -moz-radial-gradient(bottom right, #e0e793, #6dd0f1);
background: radial-gradient(to top left, #e0e793, #6dd0f1);
background: -webkit-radial-gradient(bottom right, #e0e793, #6dd0f1);
right: 30%;
top: 350px;
z-index: -1;
}
.container .card {
position: relative;
width: 300px;
height: 400px;
margin: 30px;
box-shadow: 20px 20px 50px rgba(0, 0, 0, 0.5);
border-radius: 15px;
background-color: rgba(255, 255, 255, 0.1);
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid rgba(255, 255, 255, 0.5);
border-left: 1px solid rgba(255, 255, 255, 0.5);
backdrop-filter: blur(5px);
transform: translateX(400%);
transition: transform 0.5s ease;
}
.container .card .content {
padding: 20px;
text-align: center;
transform: translateY(100px);
opacity: 0;
transition: 0.5s;
}
.container .card:hover .content {
transform:translateY(0px);
opacity: 1;
}
.container .card .content h1 {
position: absolute;
top: -75px;
right: 30px;
font-size: 8em;
color: rgba(255, 255, 255, 0.05);
pointer-events: none;
font-weight: 800;
}
.container .card .content h3 {
font-size: 1.8em;
color: #fff;
font-weight: 300;
}
.container .card .content p {
font-size: 1em;
color: #fff;
font-weight: 300;
}
.container .card .content a {
position: relative;
display: inline-block;
padding: 8px 20px;
margin-top: 15px;
background: #fff;
color: #000;
border-radius: 20px;
text-decoration: none;
font-weight: 500;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.card:nth-of-type(even){
transform: translateX(-400%)
}
.card.show{
transform: translateX(0%);
}
@keyframes orbit {
from {
transform: rotate(0deg) translateX(100px) rotate(0deg);
}
to {
transform: rotate(360deg) translateX(100px) rotate(-360deg);
}
}
/* width */
::-webkit-scrollbar {
width: 1px;
}
/* Track */
::-webkit-scrollbar-track {
background: #f1f1f1;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: #888;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: #555;
}
</style>
JavaScript:
<script>
const cards = document.querySelectorAll(".card");
window.addEventListener("scroll", checkcards);
function checkcards() {
const triggerBottom = (window.innerHeight / 5) * 4;
cards.forEach((box) => {
const boxTop = box.getBoundingClientRect().top;
if (boxTop < triggerBottom) {
box.classList.add("show");
} else {
box.classList.remove("show");
}
});
}
</script>
Last Updated: June 21, 2024