Let’s create a 3D Image Carousel using HTML and CSS. This carousel will display images in a 3D rotating effect, giving a visually captivating experience for users.
We’ll use HTML to structure the image carousel and CSS to style it and create the 3D effect with CSS transforms and animations.
Let’s get started on building the 3D Image Carousel. Whether you’re a beginner or an experienced developer, this project offers a fun way to enhance your web development skills and add dynamic, interactive elements to your design. Let’s bring images to life with a 3D carousel effect!
HTML :
This HTML code sets up the structure for a 3D image carousel that works entirely with CSS for animations and interactions. The carousel is contained within a div
with the class carousel
, and includes control buttons on the left and right to navigate through the carousel’s items. Each carousel item is an image, defined within li
elements, with a custom CSS property --_image-url
to specify the image source. There are 11 items, each representing an “Architecture Example,” and the carousel-item-wrapper
contains the list of items that will rotate in 3D space.
The carousel uses radio buttons inside the control buttons to allow users to interact with it, changing the direction of the rotation when selected. The items are positioned in 3D space to form a circular shape, and the carousel is animated using CSS transitions defined in the linked style.css
file.
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <title>CSS Only 3D Image Carousel</title> <link rel="stylesheet" href="./style.css"> </head> <body> <div class="carousel"> <div class="carousel-control-button left"><input type="radio" name="carousel-control-input"></div> <div class="carousel-control-button right"><input type="radio" name="carousel-control-input" checked></div> <div class="carousel-rotation-direction"> <ul class="carousel-item-wrapper" style="--_num-elements: 11"> <li class="carousel-item" style="--_index: 1; --_image-url: url('Images/img1.png')"><p>Architecture Example 1</p></li> <li class="carousel-item" style="--_index: 3; --_image-url: url('Images/img3.png')"><p>Architecture Example 2</p></li> <li class="carousel-item" style="--_index: 2; --_image-url: url('Images/img2.png')"><p>Architecture Example 3</p></li> <li class="carousel-item" style="--_index: 4; --_image-url: url('Images/img4.png')"><p>Architecture Example 4</p></li> <li class="carousel-item" style="--_index: 5; --_image-url: url('Images/img5.png')"><p>Architecture Example 5</p></li> <li class="carousel-item" style="--_index: 6; --_image-url: url('Images/img6.png')"><p>Architecture Example 6</p></li> <li class="carousel-item" style="--_index: 7; --_image-url: url('Images/img7.png')"><p>Architecture Example 7</p></li> <li class="carousel-item" style="--_index: 8; --_image-url: url('Images/img8.png')"><p>Architecture Example 8</p></li> <li class="carousel-item" style="--_index: 9; --_image-url: url('Images/img9.png')"><p>Architecture Example 9</p></li> <li class="carousel-item" style="--_index: 10; --_image-url: url('Images/img10.png')"><p>Architecture Example 10</p></li> <li class="carousel-item" style="--_index: 11; --_image-url: url('Images/img11.png')"><p>Architecture Example 11</p></li> <li class="carousel-ground"></li> </ul> </div> </div> </body> </html>
CSS :
This code creates a 3D carousel with interactive and animated elements using CSS custom properties (variables) to control styles like size, colors, transition effects, and animations. The carousel items rotate around a central axis, with hover effects that scale and highlight the items, along with a reflection effect on the items’ underside. It uses responsive media queries to adjust the size of the carousel and its items based on screen width. Control buttons are provided to rotate the carousel in different directions, and the carousel animation can be paused or resumed based on interactions.
:root { --carousel-transition-duration: 250ms; --carousel-transition-ease: ease-out; --carousel-bg-color-rgb: 0, 0, 0; --carousel-shadow-color-rgb: 128, 128, 128; --carousel-item-width: 11.5rem; --carousel-item-height: 17.5rem; --carousel-item-hover-effect: 1.075; --carousel-item-reflection-blur: 0.25rem; --carousel-item-empty-color-rgb: 255, 255, 255; --carousel-item-glow-color-rgb: 255, 255, 255; --carousel-item-glow-size: 5rem; --carousel-diameter: 50rem; --carousel-3d-perspective: 1000px; --carousel-3d-perspective-origin: 50% 20%; --carousel-control-button-width: 1.25rem; --carousel-control-button-height: 4rem; --carousel-control-color-rgb: 255, 255, 255; --carousel-animation-duration: 25s; --carousel-animation-play-state: running; --carousel-direction-animation-play-state: paused; } *, *::before, *::after { margin: 0; padding: 0; border: 0; box-sizing: border-box; } *:focus { outline: none; } a { -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-tap-highlight-color: transparent; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } body { display: flex; align-items: center; justify-content: center; height: 100vh; background-color: rgb(var(--carousel-bg-color-rgb)); overflow: hidden; } .carousel { --_diameter: var(--carousel-diameter); --_radius: calc(var(--_diameter) / 2); --_item-width: var(--carousel-item-width); --_item-height: var(--carousel-item-height); perspective: var(--carousel-3d-perspective); perspective-origin: var(--carousel-3d-perspective-origin); width: var(--_diameter); height: var(--_diameter); } @media only screen and (max-width: 48rem) { .carousel { --_diameter: calc(var(--carousel-diameter) * 0.75); --_item-width: calc(var(--carousel-item-width) * 0.75); --_item-height: calc(var(--carousel-item-height) * 0.75); } } @media only screen and (max-width: 32rem) { .carousel { --_diameter: calc(var(--carousel-diameter) * 0.6); --_item-width: calc(var(--carousel-item-width) * 0.6); --_item-height: calc(var(--carousel-item-height) * 0.6); } } @media only screen and (max-width: 16rem) { .carousel { --_diameter: calc(var(--carousel-diameter) * 0.25); --_item-width: calc(var(--carousel-item-width) * 0.25); --_item-height: calc(var(--carousel-item-height) * 0.25); } } .carousel .carousel-control-button { --_width: var(--carousel-control-button-width); --_height: var(--carousel-control-button-height); z-index: 1; width: var(--_width); height: var(--_height); background-color: rgb(var(--carousel-control-color-rgb)); opacity: 0.2; transition: opacity var(--carousel-transition-duration) var(--carousel-transition-ease); position: absolute; } .carousel .carousel-control-button:hover { opacity: 0.4; } .carousel .carousel-control-button:has(input:checked) { opacity: 0.8; } .carousel .carousel-control-button input { -webkit-appearance: none; appearance: none; opacity: 0; width: 100%; height: 100%; cursor: pointer; } .carousel .carousel-control-button.left { clip-path: polygon(0% 50%, 100% 0%, 100% 100%); top: calc(var(--_radius) - var(--_height) / 2); left: 0; } .carousel:has(.carousel-control-button.left input:checked) { --carousel-direction-animation-play-state: running; } .carousel .carousel-control-button.right { clip-path: polygon(0% 0%, 100% 50%, 0% 100%); top: calc(var(--_radius) - var(--_height) / 2); right: 0; } .carousel:has(.carousel-control-button.right input:checked) { --carousel-direction-animation-play-state: paused; } .carousel .carousel-rotation-direction { --_direction-animation-play-state: var(--carousel-direction-animation-play-state); --_z: calc(var(--_radius) * -1); transform: translateZ(var(--_z)); transform-style: preserve-3d; animation: carousel-rotation-reverse calc(var(--carousel-animation-duration) / 2) reverse linear infinite var(--_direction-animation-play-state); transition: all var(--carousel-transition-duration) var(--carousel-transition-ease); } @keyframes carousel-rotation-reverse { from {transform: translateZ(var(--_z)) rotateY(0deg);} to {transform: translateZ(var(--_z)) rotateY(360deg);} } @keyframes carousel-rotation-normal { from {transform: rotateY(0deg);} to {transform: rotateY(360deg);} } .carousel .carousel-item-wrapper { transform-style: inherit; width: inherit; height: inherit; list-style-type: none; position: relative; animation: carousel-rotation-normal var(--carousel-animation-duration) normal linear infinite var(--carousel-animation-play-state); transition: all var(--carousel-transition-duration) var(--carousel-transition-ease); } .carousel .carousel-rotation-direction:has(.carousel-item:hover) { --carousel-animation-play-state: paused; --_direction-animation-play-state: paused; } .carousel .carousel-item { --_width: var(--_item-width); --_height: var(--_item-height); --_rotation: calc(360 / var(--_num-elements) * var(--_index) * 1deg); left: calc(var(--_radius) - var(--_item-width) / 2); top: calc(var(--_radius) - var(--_item-height) / 2); transform: rotateY(var(--_rotation)) translateZ(var(--_radius)); transform-style: inherit; width: var(--_width); height: var(--_height); transition: all var(--carousel-transition-duration) var(--carousel-transition-ease); box-shadow: 0 0 var(--carousel-item-glow-size) transparent; position: absolute; } .carousel .carousel-item:hover { box-shadow: 0 0 var(--carousel-item-glow-size) rgb(var(--carousel-item-glow-color-rgb)); transform: rotateY(var(--_rotation)) translateZ(calc(var(--_radius) * var(--carousel-item-hover-effect))); } .carousel .carousel-item p { display: block; width: inherit; height: inherit; text-indent: -9999px; background-color: rgba(var(--carousel-item-empty-color-rgb), 0.5); background-image: var(--_image-url); background-repeat: no-repeat; background-position: center; background-size: cover; transition: filter var(--carousel-transition-duration) var(--carousel-transition-ease); filter: grayscale(100%); } .carousel .carousel-item:hover p { filter: grayscale(0%); } .carousel .carousel-item::before { content: ''; width: inherit; height: inherit; background-color: rgba(var(--carousel-item-empty-color-rgb), 0.5); background-image: linear-gradient(to top, rgba(var(--carousel-bg-color-rgb), 0.25) 0%, rgba(var(--carousel-bg-color-rgb), 1.0) 75%), var(--_image-url); background-repeat: no-repeat; background-position: center; background-size: cover; pointer-events: none; filter: blur(var(--carousel-item-reflection-blur)) grayscale(100%); transition: filter var(--carousel-transition-duration) var(--carousel-transition-ease); transform-style: inherit; transform-origin: center bottom; transform: rotateX(90deg) rotateZ(180deg) rotateY(180deg); position: absolute; } .carousel .carousel-item:hover::before { filter: blur(var(--carousel-item-reflection-blur)) grayscale(0%); } .carousel .carousel-ground { --_width: var(--_diameter); --_height: var(--_diameter); --_rotation: 90deg; left: calc(var(--_radius) - var(--_width) / 2); top: calc(var(--_radius) - var(--_height) / 2); transform: rotateX(var(--_rotation)) translateZ(calc(var(--_item-height) / -2)); width: var(--_width); height: var(--_height); border-radius: 50%; background: radial-gradient(rgba(var(--carousel-shadow-color-rgb), 0.75) 15% , rgba(var(--carousel-bg-color-rgb), 0) 60%); opacity: 0.5; transition: opacity var(--carousel-transition-duration) var(--carousel-transition-ease); position: absolute; } .carousel .carousel-item-wrapper:has(.carousel-item:hover) .carousel-ground { opacity: 0.75; }
In conclusion, building a 3D Image Carousel using HTML and CSS has been a visually exciting and educational project. By combining HTML for structure and CSS for styling and 3D animations, we’ve created a rotating carousel that adds depth and interactivity to any webpage.
If your project has problems, don’t worry. Just click to download the source code and face your coding challenges with excitement. Have fun coding!