Today, we’re diving into an awesome UI effect that’s perfect for showcasing content in a sleek, modern way. It’s called the Dynamic Card Cascade. Whether you’re building a portfolio, a learning platform, or just want to spice up your website, this effect will grab your users’ attention.
The beauty of this component is its simplicity. There are no dependencies or frameworks needed – just clean, semantic HTML with CSS transitions and vanilla JavaScript. The component is also fully responsive, adapting beautifully to mobile, tablet, and desktop viewports.
Notice how the cards collapse automatically when you hover over a different one, maintaining a clean interface. This is achieved through event delegation in JavaScript rather than attaching dozens of event listeners.
Each card contains an image, heading, description paragraph, and call-to-action link. The visual design maintains excellent contrast for accessibility while creating an immersive experience with the darkened photos.
Here are the steps to integrate it into your Elementor website:
- create three html blocks
- pate the seperate codes in it.
HTML
<div class="wputopia-hover-module">
<h1 class="wputopia-title">Dynamic Card Cascade Effect</h1>
<div class="wputopia-cards-container">
<div class="wputopia-card" data-active="false">
<div class="wputopia-card-content">
<h3>The Craft</h3>
<p>Gain the confidence to build anything you envision, transforming motion, interaction, and design principles into second nature.</p>
<a href="#" class="wputopia-card-link">Learn More</a>
<img src="https://picsum.photos/720/720?random=12" alt="The Craft">
</div>
</div>
<div class="wputopia-card" data-active="false">
<div class="wputopia-card-content">
<h3>CSS Animation</h3>
<p>Master CSS animations from your very first keyframes right through to advanced techniques.</p>
<a href="#" class="wputopia-card-link">Learn More</a>
<img src="https://picsum.photos/720/720?random=17" alt="CSS Animation">
</div>
</div>
<div class="wputopia-card" data-active="false">
<div class="wputopia-card-content">
<h3>Layout Magic</h3>
<p>Discover the art of creating responsive and dynamic layouts that adapt to any screen size.</p>
<a href="#" class="wputopia-card-link">Learn More</a>
<img src="https://picsum.photos/720/720?random=19" alt="Layout Magic">
</div>
</div>
<div class="wputopia-card" data-active="false">
<div class="wputopia-card-content">
<h3>Visual Design</h3>
<p>Learn principles of color theory, typography, and visual hierarchy to create stunning interfaces.</p>
<a href="#" class="wputopia-card-link">Learn More</a>
<img src="https://picsum.photos/720/720?random=22" alt="Visual Design">
</div>
</div>
<div class="wputopia-card" data-active="false">
<div class="wputopia-card-content">
<h3>Interactions</h3>
<p>Create micro-interactions that delight users and provide meaningful feedback throughout your interfaces.</p>
<a href="#" class="wputopia-card-link">Learn More</a>
<img src="https://picsum.photos/720/720?random=25" alt="Interactions">
</div>
</div>
<div class="wputopia-card" data-active="false">
<div class="wputopia-card-content">
<h3>Web Performance</h3>
<p>Optimize your websites for speed while maintaining beautiful animations and transitions.</p>
<a href="#" class="wputopia-card-link">Learn More</a>
<img src="https://picsum.photos/720/720?random=28" alt="Web Performance">
</div>
</div>
</div>
</div>
CSS
<style>
.wputopia-hover-module * {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wputopia-hover-module {
--wputopia-transition-speed: 0.6s;
--wputopia-transition-ease: cubic-bezier(0.4, 0, 0.2, 1);
--wputopia-card-gap: 1rem;
--wputopia-card-width: 80px;
--wputopia-card-expanded-width: 400px;
font-family: system-ui, -apple-system, sans-serif;
min-height: 500px;
display: flex;
flex-direction: column;
align-items: center;
padding: 2rem;
background: transparent;
}
.wputopia-title {
margin-bottom: 3rem;
color: #333;
text-align: center;
}
.wputopia-cards-container {
display: flex;
gap: var(--wputopia-card-gap);
max-width: 100%;
overflow-x: auto;
padding: 1rem;
height: 500px;
-webkit-overflow-scrolling: touch;
scrollbar-width: thin;
}
.wputopia-cards-container::-webkit-scrollbar {
height: 8px;
}
.wputopia-cards-container::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
.wputopia-cards-container::-webkit-scrollbar-thumb {
background: #888;
border-radius: 4px;
}
.wputopia-card {
position: relative;
min-width: var(--wputopia-card-width);
width: var(--wputopia-card-width);
height: 100%;
background: white;
border-radius: 12px;
overflow: hidden;
transition: width var(--wputopia-transition-speed) var(--wputopia-transition-ease);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
cursor: pointer;
flex-shrink: 0;
}
.wputopia-card[data-active="true"] {
width: var(--wputopia-card-expanded-width);
cursor: default;
}
.wputopia-card-content {
position: absolute;
width: var(--wputopia-card-expanded-width);
height: 100%;
padding: 2rem;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.wputopia-card h3 {
position: unset;
top: 50%;
left: 50%;
font-size: 1.5rem;
margin-bottom: 1rem;
transform: translate(-50%, -50%) rotate(90deg);
transform-origin: center center;
transition: all var(--wputopia-transition-speed) var(--wputopia-transition-ease);
color: white;
z-index: 2;
white-space: nowrap;
text-transform: uppercase;
font-weight: 600;
letter-spacing: 1px;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.wputopia-card p {
opacity: 0;
transform: translateY(20px);
transition: all var(--wputopia-transition-speed) var(--wputopia-transition-ease);
color: white;
margin-bottom: 1.5rem;
z-index: 1;
line-height: 1.6;
}
.wputopia-card-link {
opacity: 0;
transform: translateY(20px);
transition: all var(--wputopia-transition-speed) var(--wputopia-transition-ease);
color: white;
text-decoration: none;
font-weight: 500;
z-index: 1;
display: inline-block;
padding: 0.5rem 0;
border-bottom: 2px solid transparent;
}
.wputopia-card-link:hover {
border-bottom-color: white;
}
.wputopia-card img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
filter: brightness(0.7);
transition: transform var(--wputopia-transition-speed) var(--wputopia-transition-ease);
}
.wputopia-card[data-active="true"] h3 {
position: relative;
top: auto;
left: auto;
transform: translateY(0) rotate(0);
font-size: 1.5rem;
text-transform: none;
letter-spacing: normal;
font-weight: 600;
margin-bottom: 1rem;
}
.wputopia-card[data-active="true"] p,
.wputopia-card[data-active="true"] .wputopia-card-link {
opacity: 1;
transform: translateY(0);
}
.wputopia-card[data-active="true"] img {
transform: scale(1.1);
}
/* Mobile Responsiveness */
@media (max-width: 1200px) {
.wputopia-hover-module {
--wputopia-card-expanded-width: 350px;
}
}
@media (max-width: 768px) {
.wputopia-hover-module {
--wputopia-card-width: 60px;
--wputopia-card-expanded-width: 280px;
}
.wputopia-hover-module {
padding: 1rem;
}
.wputopia-title {
margin-bottom: 2rem;
font-size: 1.75rem;
}
.wputopia-cards-container {
height: 400px;
}
.wputopia-card-content {
padding: 1.5rem;
}
.wputopia-card h3 {
font-size: 1.25rem;
}
.wputopia-card[data-active="true"] h3 {
font-size: 1.25rem;
}
.wputopia-card p {
font-size: 0.9rem;
}
}
@media (max-width: 480px) {
.wputopia-hover-module {
--wputopia-card-width: 50px;
--wputopia-card-expanded-width: 250px;
--wputopia-card-gap: 0.5rem;
}
.wputopia-cards-container {
height: 350px;
padding: 0.5rem;
}
.wputopia-card-content {
padding: 1rem;
}
.wputopia-card h3 {
font-size: 1rem;
}
.wputopia-card[data-active="true"] h3 {
font-size: 1.15rem;
}
}
</style>
JS
<script>
(function() {
// Immediately-invoked function expression to avoid polluting global namespace
function initWputopiaHoverModule() {
const cards = document.querySelectorAll('.wputopia-card');
const handleCardInteraction = (event) => {
const targetCard = event.currentTarget;
// Reset all cards
cards.forEach(card => {
if (card !== targetCard) {
card.setAttribute('data-active', 'false');
}
});
// Toggle target card
const isCurrentlyActive = targetCard.getAttribute('data-active') === 'true';
targetCard.setAttribute('data-active', (!isCurrentlyActive).toString());
};
// Add event listeners to each card
cards.forEach(card => {
card.addEventListener('click', handleCardInteraction);
// Add hover interaction
card.addEventListener('mouseenter', (e) => {
handleCardInteraction(e);
});
});
// Close active card when clicking outside
document.addEventListener('click', (e) => {
if (!e.target.closest('.wputopia-card')) {
cards.forEach(card => {
card.setAttribute('data-active', 'false');
});
}
});
// Open the last card on module initialization
if (cards.length > 0) {
const lastCard = cards[cards.length - 1];
lastCard.setAttribute('data-active', 'true');
// Scroll to ensure the last card is visible
setTimeout(() => {
lastCard.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'end' });
}, 100);
}
// Handle window resize for responsiveness
window.addEventListener('resize', () => {
// Update active card visibility if needed
const activeCard = document.querySelector('.wputopia-card[data-active="true"]');
if (activeCard) {
setTimeout(() => {
activeCard.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
}, 100);
}
});
}
// Initialize on DOM content loaded
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initWputopiaHoverModule);
} else {
initWputopiaHoverModule();
}
})();
</script>
That’s it!
If you found this tutorial helpful, don’t forget to like and subscribe for more web development techniques. Next time, we’ll explore how to extend this pattern with additional animations and interactions!