I have never been overconcerned or obsessed with opinion polls or popularity polls. I think a leader who is, is a weak leader.
If you are concerned with whether your rating will go up ordown, then you are not a leader. You are just catching the wind... you will go where the wind is blowing... Between being loved and feared, I have always believed Machiavelli was right.
If nobody is afraid of me, I am meaningless. When I say something... I have to be taken very seriously.
Inspired by Adaline's website, this component focuses on the CSS perspective property to create a 3D card that rotates on hover. This effect is done with three nested wrappers. Each wrapper has a specific job—removing one would break the 3D effect.
perspective-container ← sets the 3D space
└─ perspective-distant ← scales down + positions the card
└─ perspective-card ← the element that actually rotates
└─ content ← text + highlighted spansLet's look at each wrapper step by step.
Perspective
The outermost class (the container) sets perspective, which controls how "deep" the 3D space feels. I like to think of it as how far your eyes are from a screen. The closer you look, the more distorted the screen looks, and the farther you are, the flatter it would look.
.perspective-container {
perspective: 1200px;
}But to really understand the difference in perspective values, let's compare a 100px vs 5000px perspective. These also have transform: rotateX(14deg) rotateY(-30deg) on hover to demonstrate:
perspective: 100px
Hover me. The rotation looks dramatic and warped, like a fisheye lens up close.
perspective: 5000px
Hover me. The rotation is barely noticeable — feels flat and distant.
100px looks way more warped compared to 5000px which makes the rotation barely noticeable.
Smaller cards can get away with lower values. For this card, 1200px gives enough depth to feel 3D without looking distorted.
I have never been overconcerned or obsessed with opinion polls or popularity polls. I think a leader who is, is a weak leader.
Something looks off. The card feels flat, like a rotating image rather than a rotating object. That's because the browser is flattening the 3D transform back into 2D by default.
Preserve-3D
To fix the flat look, we need another css wrapper with transform-style: preserve-3d. This is because perspective property kept the container in the 3D space, but not the container's children.
.perspective-distant {
transform-style: preserve-3d;
}Without preserve-3d the card still rotates, but it looks like a flat picture being spun:
without preserve-3d
Hover me. The card rotates, but it looks like a flat image being spun — no depth.
When including the css wrapper with preserve-3d added, the same rotation now has real depth applied to the container's children:
I have never been overconcerned or obsessed with opinion polls or popularity polls. I think a leader who is, is a weak leader.
The card now exists in 3D space instead of being projected flat.
Rotation
The perspective-card class handles the hover rotation. It starts flat and tilts on hover using two axes.
.perspective-card {
transform: rotateX(0deg) rotateY(0deg);
transition: transform 1s cubic-bezier(0.59, 0.14, 0.35, 0.99);
}
// on container hover, the card rotates
.perspective-container:hover .perspective-card {
transform: rotateX(14deg) rotateY(-30deg);
}To understand what each axis does, here they are in isolation:
rotateY(-30deg) only
Hover me. Tilts left like opening a book. This is the primary rotation axis.
rotateX(14deg) only
Hover me. Slight downward tilt — like tipping a card toward you. Subtle but adds realism.
Not going to go into depth about the rotate properties, but feel free to play around with them.
With the X and Y rotation combined, they give the card a diagonal tilt that feels like you're peering around the edge.
Highlight Lift
When the card rotates, the highlighted text lifts up and to the left. The shadow stays in place of the original highlighted text, creating a 3D floating effect.
.perspective-container:hover .perspective-striped-line > span {
transform: translate(-8px, -6px);
box-shadow:
/* border ring — thin solid outline */
rgba(100, 180, 255, 0.8) 2px 1.5px 0px 0.75px,
/* soft outer glow */
rgba(100, 180, 255, 0.3) 8px 4px 4px 0px;
}The trick is that the translate and shadow go in opposite directions. The text moves left and up (-8px, -6px), but the shadow offsets are positive (2px, 1.5px and 8px, 4px), so the shadow stays down and to the right.
I have never been overconcerned or obsessed with opinion polls or popularity polls. I think a leader who is, is a weak leader.
If you are concerned with whether your rating will go up ordown, then you are not a leader. You are just catching the wind.
This mismatch is what creates the illusion of the highlight floating above the card.