3D Card Fan - Interactive
An interactive HTML component showcasing 3D card fan layouts with real-time parameter adjustment.
Overview
This component creates a dynamic 3D card fan that users can control through intuitive sliders and checkboxes. It demonstrates advanced CSS 3D transforms with precise positioning, rotation, and perspective controls.
Key Features
- Real-time Parameter Control: Adjust all 3D properties instantly via sliders
- Multiple Presets: Seven pre-configured layouts (Default, Cascade, Progressive, Fan, Flat, Deep, Spiral)
- Smart Centering: Optional automatic centering on the first card
- Interactive Cards: Hover effects with scale transformation
- Responsive Design: Works across different screen sizes
HTML Structure
1<div class="controls">
2 <!-- Control sliders and checkboxes -->
3</div>
4
5<div class="scene-container" id="sceneContainer">
6 <div class="card-stack" id="cardStack">
7 <div class="card">
8 <div class="card-content">
9 <div class="card-icon">🥽</div>
10 <div class="card-footer">
11 <div class="card-title">Future of<br>Consumer Tech</div>
12 <div class="card-subtitle">Innovation & Trends</div>
13 </div>
14 </div>
15 </div>
16 <!-- Additional cards -->
17 </div>
18</div>
Controls Breakdown
Initial Rotation
- Initial Rotation X/Y/Z (-180° to 180°): Sets the starting rotation angle for all cards
Per-Card Rotation
- Rotation/Card Y (Spread) (0° to 60°): Creates the fan spread effect
- Rotation/Card X (-30° to 30°): Adds tilt along the X axis
- Rotation/Card Z (-30° to 30°): Adds twist along the Z axis
Per-Card Spacing
- Spacing/Card X (0 to 150px): Horizontal offset between cards
- Spacing/Card Y (-150 to 150px): Vertical offset between cards
- Spacing/Card Z (-150 to 150px): Depth offset along Z axis
Depth Control
- Depth/Card Z (0 to 300px): Primary depth offset
- Depth/Card X (-300 to 300px): Additional X-axis depth positioning
- Depth/Card Y (-300 to 300px): Additional Y-axis depth positioning
Stack Rotation
- Stack Rotation X/Y/Z (-45° to 45°): Controls the overall stack orientation
Perspective
- Perspective (500px to 3000px): Controls the viewing distance and intensity of 3D effect
Preset Configurations
Default
1{
2 initialRotX: 0, initialRotY: 0, initialRotZ: 0,
3 spread: 0, rotPerCardX: 0, rotPerCardZ: 0,
4 spacing: 95, spacingY: 0, spacingZ: 0,
5 depth: 80, depthX: 0, depthY: 0,
6 rotX: -32, rotY: 20, rotZ: 0,
7 perspective: 3000
8}
A balanced 3D perspective with moderate spacing and depth. Good starting point for customization.
Cascade
1{
2 initialRotX: 17, initialRotY: -57, initialRotZ: -9,
3 spread: 0, rotPerCardX: -8, rotPerCardZ: 2,
4 spacing: 60, spacingY: 0, spacingZ: 0,
5 depth: 30, depthX: 0, depthY: 0,
6 rotX: 11, rotY: 30, rotZ: 0,
7 perspective: 3000
8}
Creates a waterfall or cascade effect with cards tilting backward progressively.
Progressive
1{
2 initialRotX: 0, initialRotY: 0, initialRotZ: 0,
3 spread: 7, rotPerCardX: 0, rotPerCardZ: 0,
4 spacing: 48, spacingY: 0, spacingZ: 0,
5 depth: 38, depthX: 0, depthY: 0,
6 rotX: 9, rotY: 0, rotZ: 0,
7 perspective: 1300
8}
Subtle spread with closer perspective for focused viewing.
Fan
1{
2 initialRotX: 0, initialRotY: 0, initialRotZ: 0,
3 spread: 5, rotPerCardX: 0, rotPerCardZ: 0,
4 spacing: 60, spacingY: 0, spacingZ: 0,
5 depth: 50, depthX: 0, depthY: 0,
6 rotX: 0, rotY: -10, rotZ: 0,
7 perspective: 1500
8}
Classic fan layout with slight horizontal offset.
Flat
1{
2 initialRotX: 0, initialRotY: 0, initialRotZ: 0,
3 spread: 3, rotPerCardX: 0, rotPerCardZ: 0,
4 spacing: 60, spacingY: 0, spacingZ: 0,
5 depth: 20, depthX: 0, depthY: 0,
6 rotX: 0, rotY: 0, rotZ: 0,
7 perspective: 2000
8}
Minimal depth with tight perspective for a nearly 2D appearance.
Deep
1{
2 initialRotX: 0, initialRotY: 0, initialRotZ: 0,
3 spread: 6, rotPerCardX: 0, rotPerCardZ: 0,
4 spacing: 80, spacingY: 0, spacingZ: 0,
5 depth: 120, depthX: 0, depthY: 0,
6 rotX: 20, rotY: 0, rotZ: 0,
7 perspective: 1200
8}
Extreme depth with strong perspective distortion.
Spiral
1{
2 initialRotX: 0, initialRotY: 0, initialRotZ: 0,
3 spread: 7, rotPerCardX: 2, rotPerCardZ: 1,
4 spacing: 100, spacingY: 0, spacingZ: 0,
5 depth: 100, depthX: 0, depthY: 0,
6 rotX: 15, rotY: 15, rotZ: 0,
7 perspective: 1500
8}
Creates a spiral or helix effect with rotational progression per card.
How It Works
Transform Pipeline
Each card’s transform follows this order:
1translate3d(translateX, translateY, translateZ)
2 rotateX(rotateX)
3 rotateY(rotateY)
4 rotateZ(rotateZ)
The translateZ() is positioned first to establish depth before rotations are applied, ensuring proper 3D space positioning.
Progressive Positioning
Cards are positioned progressively using the index multiplier:
1const translateX = (index * spacing) + (index * depthX);
2const translateY = (index * spacingY) + (index * depthY);
3const translateZ = (-index * depth) + (index * spacingZ);
This creates cascading offsets where each subsequent card moves further along all three axes.
Centroid-Based Centering
When “Center on First Card” is enabled, the component calculates the centroid of all cards and applies an offset to reposition the entire stack so the first card appears at the origin:
1const centroidX = (sumX / totalCards);
2const offsetX = -centroidX;
3// Applied to cardStack container for centered layout
Preserve 3D Rendering
Both the .card-stack and individual .card elements use transform-style: preserve-3d to maintain 3D space integrity across the hierarchy. Without this, children would flatten to the parent’s plane.
Perspective Context
The .scene-container establishes perspective with perspective: 1200px (adjustable). This defines the viewing distance:
- Small values (500px-800px): Extreme perspective distortion
- Medium values (1000px-1500px): Balanced perspective effect
- Large values (2000px-3000px): Subtle, distant perspective
CSS Pattern Overview
1/* Establish 3D context */
2.scene-container {
3 perspective: 1200px;
4 perspective-origin: center center;
5}
6
7/* Container for all cards */
8.card-stack {
9 transform-style: preserve-3d;
10 transition: transform 0.3s ease;
11}
12
13/* Individual card transform */
14.card {
15 transform-style: preserve-3d;
16 transition: transform 0.5s ease;
17 /* transform applied via JavaScript */
18}
19
20/* Pseudo-element for glossy effect */
21.card::before {
22 background: linear-gradient(135deg,
23 rgba(255, 255, 255, 0.2) 0%,
24 rgba(255, 255, 255, 0) 100%);
25}
JavaScript Control Flow
- Event Listeners: All controls trigger
updateCards()on input/change - Value Update: Display values update to show current slider position
- Perspective Setup: Scene container perspective is updated
- Card Positioning: Each card’s transform is calculated and applied
- Hover Effects: Cards scale to 1.05 on hover
Interaction Patterns
Real-time Feedback
- Sliders provide immediate visual feedback with no delay
- Value displays update synchronously
- Transitions are smooth (0.3-0.5s) for visual appeal
Preset Application
- Presets apply all parameters at once
- Smooth transitions show the transformation from current to preset state
Accessibility
- All controls are keyboard accessible
- Labels are properly associated with inputs
- Value displays provide context
Technical Considerations
Transform Order
The order of CSS transforms matters significantly. Position transforms are applied before rotation transforms to ensure correct depth positioning:
1translate3d(...) rotateX(...) rotateY(...) rotateZ(...)
Reversing this order would produce different spatial relationships.
Z-Index and Stacking
- Default z-index allows natural stacking based on DOM order
- Hover state sets
z-index: 10for visual prominence
Performance
- Transforms use GPU acceleration (transform-style: preserve-3d)
- Transitions use hardware-accelerated properties
- No layout recalculations during interaction
Customization Examples
Create a “Wheel” Layout
1applyPreset('fan');
2// Then adjust:
3// - Spread: 15°
4// - Rotation X: 45°
5// - Depth: 150px
Create a “Step” Layout
1// Manual configuration:
2// - Spacing X: 120px
3// - Spacing Y: 40px
4// - Depth: 0px
5// - Stack Rotation Y: 0°
6// - Stack Rotation X: 10°
Create a “Orbit” Layout
1// Manual configuration:
2// - Initial Rotation Y: 0°
3// - Spread: 60° (360° / 6 cards)
4// - Depth: 200px
5// - Stack Rotation X: 0°
6// - Perspective: 1500px
Browser Support
- Chrome/Edge 12+
- Firefox 10+
- Safari 9+
- Requires CSS 3D Transforms support
- JavaScript ES6+ for modern syntax