Cards cardtilt3d
Interactive Tilt Card
Card that tilts in 3D space based on mouse position.
Preview
Usage
Copy the full block below to use this component with its imports.
astro
---
import { InteractiveTiltCard } from 'astro-component-kit';
---
<InteractiveTiltCard title="3D Hover" description="Move your mouse over me." /> ---
import { InteractiveTiltCard } from 'astro-component-kit';
---
<InteractiveTiltCard title="3D Hover" description="Move your mouse over me." /> Manual Installation
If you are not using the npm package, create a new file src/components/lib/InteractiveTiltCard.astro and paste the following code:
astro
---
/**
* InteractiveTiltCard — Card that tilts in 3D space based on mouse position.
*
* @param {string} title - The card's heading text.
* @param {string} description - The descriptive paragraph attached to the card.
*/
interface Props {
title: string;
description: string;
}
const { title, description } = Astro.props;
---
<div class="tilt-card-wrap">
<div class="tilt-card-inner">
<h3 class="tilt-card__title">{title}</h3>
<p class="tilt-card__desc">{description}</p>
</div>
</div>
<style>
.tilt-card-wrap {
perspective: 1000px;
width: 100%;
max-width: 300px;
}
.tilt-card-inner {
background: var(--c-bg-elev, #1e293b);
padding: var(--sp-12, 3rem);
border-radius: var(--r-xl, 24px);
color: var(--c-text-1, #fff);
text-align: center;
border: 1px solid var(--c-border, rgba(255,255,255,0.1));
transform-style: preserve-3d;
transition: transform 0.1s;
}
.tilt-card__title {
transform: translateZ(50px);
font-size: 1.5rem;
color: var(--c-primary, #818cf8);
margin: 0;
}
.tilt-card__desc {
transform: translateZ(30px);
color: var(--c-text-2, #94a3b8);
font-size: 0.9rem;
margin-top: 1rem;
}
</style>
<script>
document.querySelectorAll('.tilt-card-inner').forEach(card => {
card.addEventListener('mousemove', e => {
const rect = card.getBoundingClientRect();
const x = ((e as MouseEvent).clientX - rect.left - rect.width/2) / 10;
const y = ((e as MouseEvent).clientY - rect.top - rect.height/2) / -10;
(card as HTMLElement).style.transform = `rotateY(${x}deg) rotateX(${y}deg)`;
});
card.addEventListener('mouseleave', () => {
(card as HTMLElement).style.transform = 'rotateY(0deg) rotateX(0deg)';
});
});
</script> ---
/**
* InteractiveTiltCard — Card that tilts in 3D space based on mouse position.
*
* @param {string} title - The card's heading text.
* @param {string} description - The descriptive paragraph attached to the card.
*/
interface Props {
title: string;
description: string;
}
const { title, description } = Astro.props;
---
<div class="tilt-card-wrap">
<div class="tilt-card-inner">
<h3 class="tilt-card__title">{title}</h3>
<p class="tilt-card__desc">{description}</p>
</div>
</div>
<style>
.tilt-card-wrap {
perspective: 1000px;
width: 100%;
max-width: 300px;
}
.tilt-card-inner {
background: var(--c-bg-elev, #1e293b);
padding: var(--sp-12, 3rem);
border-radius: var(--r-xl, 24px);
color: var(--c-text-1, #fff);
text-align: center;
border: 1px solid var(--c-border, rgba(255,255,255,0.1));
transform-style: preserve-3d;
transition: transform 0.1s;
}
.tilt-card__title {
transform: translateZ(50px);
font-size: 1.5rem;
color: var(--c-primary, #818cf8);
margin: 0;
}
.tilt-card__desc {
transform: translateZ(30px);
color: var(--c-text-2, #94a3b8);
font-size: 0.9rem;
margin-top: 1rem;
}
</style>
<script>
document.querySelectorAll('.tilt-card-inner').forEach(card => {
card.addEventListener('mousemove', e => {
const rect = card.getBoundingClientRect();
const x = ((e as MouseEvent).clientX - rect.left - rect.width/2) / 10;
const y = ((e as MouseEvent).clientY - rect.top - rect.height/2) / -10;
(card as HTMLElement).style.transform = `rotateY(${x}deg) rotateX(${y}deg)`;
});
card.addEventListener('mouseleave', () => {
(card as HTMLElement).style.transform = 'rotateY(0deg) rotateX(0deg)';
});
});
</script>
Quick Info
- Category
- Cards
- Filename
InteractiveTiltCard.astro- Dependencies
- None — pure Astro + CSS
- Tags
- cardtilt3d