구성 요소 캐러셀 슬라이더 포트폴리오를 위한 3D 캐러셀 슬라이더 구성 요소

포트폴리오를 위한 3D 캐러셀 슬라이더 구성 요소

반응형 3D에서 영감을 받은 캐러셀 슬라이더 구성 요소로, 포트폴리오 항목을 표시하며, 보색과 다크 모드를 지원합니다. 깊이와 참여도를 염두에 두고 설계되었습니다.

미리 보기

HTML 코드

<div class="overflow-hidden py-12 bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-white">
  <div class="container mx-auto px-4">
    <h2 class="text-4xl md:text-5xl font-extrabold text-center mb-12 relative z-10 text-transparent bg-clip-text bg-gradient-to-r from-teal-500 to-indigo-600 dark:from-teal-400 dark:to-indigo-500">
      Our Showcase
    </h2>

    <div class="relative w-full aspect-video md:h-96 lg:h-[400px] xl:h-[500px] group perspective-1000px">
      <!-- Hidden Checkbox for Navigation (simulated interactive effect) -->
      <input type="radio" name="carousel-slide" id="slide-1" class="hidden" checked>
      <input type="radio" name="carousel-slide" id="slide-2" class="hidden">
      <input type="radio" name="carousel-slide" id="slide-3" class="hidden">
      <input type="radio" name="carousel-slide" id="slide-4" class="hidden">

      <div class="absolute w-full h-full ease-in-out duration-700 transform-style-preserve-3d relative-carousel-wrapper">

        <!-- Slide 1 -->
        <label for="slide-1" class="absolute w-4/5 md:w-3/5 lg:w-2/5 xl:w-1/3 h-full cursor-pointer transition-all duration-700 ease-in-out bg-gradient-to-br from-teal-400 to-blue-500 dark:from-teal-600 dark:to-blue-700 rounded-xl shadow-2xl overflow-hidden backface-hidden flex flex-col justify-between p-6 opacity-0 z-0 current-slide-transform">
          <div class="absolute inset-0 bg-black bg-opacity-20 flex flex-col p-6 rounded-xl">
            <img src="https://picsum.photos/id/1018/600/400" alt="Project 1" class="max-w-full h-48 md:h-56 lg:h-64 object-cover rounded-md shadow-lg mb-4 transform group-hover:scale-105 transition duration-300">
            <h3 class="text-2xl md:text-3xl font-bold mb-2 text-white">Elegant Web Design</h3>
            <p class="text-sm text-gray-100 mb-4">Crafting a seamless and intuitive user experience for a modern tech startup.</p>
            <a href="#" class="mt-auto self-start px-5 py-2 bg-white text-teal-600 rounded-full font-semibold hover:bg-gray-100 dark:hover:bg-gray-200 transition duration-300 shadow-md">View Project</a>
          </div>
        </label>

        <!-- Slide 2 -->
        <label for="slide-2" class="absolute w-4/5 md:w-3/5 lg:w-2/5 xl:w-1/3 h-full cursor-pointer transition-all duration-700 ease-in-out bg-gradient-to-br from-indigo-500 to-purple-600 dark:from-indigo-700 dark:to-purple-800 rounded-xl shadow-2xl overflow-hidden backface-hidden flex flex-col justify-between p-6 opacity-0 z-0 right-slide-transform">
          <div class="absolute inset-0 bg-black bg-opacity-20 flex flex-col p-6 rounded-xl">
            <img src="https://picsum.photos/id/1015/600/400" alt="Project 2" class="max-w-full h-48 md:h-56 lg:h-64 object-cover rounded-md shadow-lg mb-4 transform group-hover:scale-105 transition duration-300">
            <h3 class="text-2xl md:text-3xl font-bold mb-2 text-white">Mobile App Development</h3>
            <p class="text-sm text-gray-100 mb-4">Building a cross-platform mobile application with robust features and engaging UI.</p>
            <a href="#" class="mt-auto self-start px-5 py-2 bg-white text-indigo-700 rounded-full font-semibold hover:bg-gray-100 dark:hover:bg-gray-200 transition duration-300 shadow-md">View Project</a>
          </div>
        </label>

        <!-- Slide 3 -->
        <label for="slide-3" class="absolute w-4/5 md:w-3/5 lg:w-2/5 xl:w-1/3 h-full cursor-pointer transition-all duration-700 ease-in-out bg-gradient-to-br from-purple-500 to-red-600 dark:from-purple-700 dark:to-red-800 rounded-xl shadow-2xl overflow-hidden backface-hidden flex flex-col justify-between p-6 opacity-0 z-0 far-right-slide-transform">
          <div class="absolute inset-0 bg-black bg-opacity-20 flex flex-col p-6 rounded-xl">
            <img src="https://picsum.photos/id/1004/600/400" alt="Project 3" class="max-w-full h-48 md:h-56 lg:h-64 object-cover rounded-md shadow-lg mb-4 transform group-hover:scale-105 transition duration-300">
            <h3 class="text-2xl md:text-3xl font-bold mb-2 text-white">Brand Identity Design</h3>
            <p class="text-sm text-gray-100 mb-4">Developing a comprehensive brand identity including logo, typography, and guidelines.</p>
            <a href="#" class="mt-auto self-start px-5 py-2 bg-white text-purple-700 rounded-full font-semibold hover:bg-gray-100 dark:hover:bg-gray-200 transition duration-300 shadow-md">View Project</a>
          </div>
        </label>

        <!-- Slide 4 -->
        <label for="slide-4" class="absolute w-4/5 md:w-3/5 lg:w-2/5 xl:w-1/3 h-full cursor-pointer transition-all duration-700 ease-in-out bg-gradient-to-br from-red-500 to-orange-600 dark:from-red-700 dark:to-orange-800 rounded-xl shadow-2xl overflow-hidden backface-hidden flex flex-col justify-between p-6 opacity-0 z-0 left-slide-transform">
          <div class="absolute inset-0 bg-black bg-opacity-20 flex flex-col p-6 rounded-xl">
            <img src="https://picsum.photos/id/1003/600/400" alt="Project 4" class="max-w-full h-48 md:h-56 lg:h-64 object-cover rounded-md shadow-lg mb-4 transform group-hover:scale-105 transition duration-300">
            <h3 class="text-2xl md:text-3xl font-bold mb-2 text-white">E-commerce Platform</h3>
            <p class="text-sm text-gray-100 mb-4">Building a high-performance e-commerce solution with integrated payment gateways.</p>
            <a href="#" class="mt-auto self-start px-5 py-2 bg-white text-red-700 rounded-full font-semibold hover:bg-gray-100 dark:hover:bg-gray-200 transition duration-300 shadow-md">View Project</a>
          </div>
        </label>

      </div>

      <!-- Navigation Dots -->
      <div class="absolute bottom-0 md:bottom-[-2.5rem] lg:bottom-[-3rem] left-1/2 -translate-x-1/2 flex space-x-3 pointer-events-none z-20">
        <label for="slide-1" class="w-3 h-3 md:w-3.5 md:h-3.5 bg-gray-400 dark:bg-gray-600 rounded-full cursor-pointer transition-all duration-300 hover:scale-110 active:bg-gradient-to-r from-teal-500 to-blue-500 dark:active:from-teal-400 dark:active:to-blue-500 dot-1-active"></label>
        <label for="slide-2" class="w-3 h-3 md:w-3.5 md:h-3.5 bg-gray-400 dark:bg-gray-600 rounded-full cursor-pointer transition-all duration-300 hover:scale-110 active:bg-gradient-to-r from-teal-500 to-blue-500 dark:active:from-teal-400 dark:active:to-blue-500 dot-2-active"></label>
        <label for="slide-3" class="w-3 h-3 md:w-3.5 md:h-3.5 bg-gray-400 dark:bg-gray-600 rounded-full cursor-pointer transition-all duration-300 hover:scale-110 active:bg-gradient-to-r from-teal-500 to-blue-500 dark:active:from-teal-400 dark:active:to-blue-500 dot-3-active"></label>
        <label for="slide-4" class="w-3 h-3 md:w-3.5 md:h-3.5 bg-gray-400 dark:bg-gray-600 rounded-full cursor-pointer transition-all duration-300 hover:scale-110 active:bg-gradient-to-r from-teal-500 to-blue-500 dark:active:from-teal-400 dark:active:to-blue-500 dot-4-active"></label>
      </div>

    </div>
  </div>
</div>

<style>
  /* Base styles for 3D carousel container */
  .perspective-1000px {
    perspective: 1000px;
  }

  .transform-style-preserve-3d {
    transform-style: preserve-3d;
  }

  .backface-hidden {
    backface-visibility: hidden;
  }

  /* General slide positioning for animation */
  .relative-carousel-wrapper label {
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%) rotateY(0deg) translateX(0) scale(0.8) translateY(0);
    opacity: 0;
  }

  /* Define transformations for each slide based on checked state */
  #slide-1:checked ~ .relative-carousel-wrapper .current-slide-transform,
  #slide-2:checked ~ .relative-carousel-wrapper .right-slide-transform,
  #slide-3:checked ~ .relative-carousel-wrapper .far-right-slide-transform,
  #slide-4:checked ~ .relative-carousel-wrapper .left-slide-transform {
    transform: translate(-50%, -50%) rotateY(0deg) translateX(0) scale(1) translateY(0);
    opacity: 1;
    z-index: 10;
  }

  /* Right slide */
  #slide-1:checked ~ .relative-carousel-wrapper .right-slide-transform,
  #slide-2:checked ~ .relative-carousel-wrapper .far-right-slide-transform,
  #slide-3:checked ~ .relative-carousel-wrapper .left-slide-transform,
  #slide-4:checked ~ .relative-carousel-wrapper .current-slide-transform {
    transform: translate(-50%, -50%) rotateY(-20deg) translateX(calc(100% + 4rem)) scale(0.8) translateY(0);
    opacity: 0.7;
    z-index: 5;
    pointer-events: auto; /* Make visible side slides clickable */
  }

  /* Far right slide */
  #slide-1:checked ~ .relative-carousel-wrapper .far-right-slide-transform,
  #slide-2:checked ~ .relative-carousel-wrapper .left-slide-transform,
  #slide-3:checked ~ .relative-carousel-wrapper .current-slide-transform,
  #slide-4:checked ~ .relative-carousel-wrapper .right-slide-transform {
    transform: translate(-50%, -50%) rotateY(-40deg) translateX(calc(200% + 8rem)) scale(0.6) translateY(0);
    opacity: 0.4;
    z-index: 0;
    pointer-events: auto;
  }

  /* Left slide */
  #slide-1:checked ~ .relative-carousel-wrapper .left-slide-transform,
  #slide-2:checked ~ .relative-carousel-wrapper .current-slide-transform,
  #slide-3:checked ~ .relative-carousel-wrapper .right-slide-transform,
  #slide-4:checked ~ .relative-carousel-wrapper .far-right-slide-transform {
    transform: translate(-50%, -50%) rotateY(20deg) translateX(calc(-100% - 4rem)) scale(0.8) translateY(0);
    opacity: 0.7;
    z-index: 5;
    pointer-events: auto;
  }

  /* Navigation dot active states */
  #slide-1:checked ~ .navigation .dot-1-active,
  #slide-2:checked ~ .navigation .dot-2-active,
  #slide-3:checked ~ .navigation .dot-3-active,
  #slide-4:checked ~ .navigation .dot-4-active {
    background-color: #6366f1; /* Tailwind indigo-500 */
    transform: scale(1.4);
  }

  /* Update navigation dot colors on checked state */
  #slide-1:checked ~ div.navigation-dots label[for='slide-1'],
  #slide-2:checked ~ div.navigation-dots label[for='slide-2'],
  #slide-3:checked ~ div.navigation-dots label[for='slide-3'],
  #slide-4:checked ~ div.navigation-dots label[for='slide-4'] {
    background-color: #3b82f6; /* A shade of blue for active dot */
    transform: scale(1.4);
    background-image: linear-gradient(to right, var(--tw-gradient-stops));
    --tw-gradient-from: #14b8a6; /* teal-500 */
    --tw-gradient-to: #3b82f6; /* blue-500 */
  }

  @media (prefers-color-scheme: dark) {
    #slide-1:checked ~ div.navigation-dots label[for='slide-1'],
    #slide-2:checked ~ div.navigation-dots label[for='slide-2'],
    #slide-3:checked ~ div.navigation-dots label[for='slide-3'],
    #slide-4:checked ~ div.navigation-dots label[for='slide-4'] {
      --tw-gradient-from: #2dd4bf; /* teal-400 */
      --tw-gradient-to: #60a5fa; /* blue-400 */
    }
  }

  /* Define the order of slides logic for the carousel */
  /* When slide-1 is checked: */
  #slide-1:checked ~ .relative-carousel-wrapper > label:nth-child(1) { /* Current */
    transform: translate(-50%, -50%) rotateY(0deg) translateX(0) scale(1) translateY(0);
    opacity: 1;
    z-index: 10;
    pointer-events: none; /* Disable click on current slide */
  }
  #slide-1:checked ~ .relative-carousel-wrapper > label:nth-child(2) { /* Right */
    transform: translate(-50%, -50%) rotateY(-20deg) translateX(calc(100% + 4rem)) scale(0.8) translateY(0);
    opacity: 0.7;
    z-index: 5;
  }
  #slide-1:checked ~ .relative-carousel-wrapper > label:nth-child(3) { /* Far Right */
    transform: translate(-50%, -50%) rotateY(-40deg) translateX(calc(200% + 8rem)) scale(0.6) translateY(0);
    opacity: 0.4;
    z-index: 0;
  }
  #slide-1:checked ~ .relative-carousel-wrapper > label:nth-child(4) { /* Left */
    transform: translate(-50%, -50%) rotateY(20deg) translateX(calc(-100% - 4rem)) scale(0.8) translateY(0);
    opacity: 0.7;
    z-index: 5;
  }

  /* When slide-2 is checked: */
  #slide-2:checked ~ .relative-carousel-wrapper > label:nth-child(2) { /* Current */
    transform: translate(-50%, -50%) rotateY(0deg) translateX(0) scale(1) translateY(0);
    opacity: 1;
    z-index: 10;
    pointer-events: none;
  }
  #slide-2:checked ~ .relative-carousel-wrapper > label:nth-child(3) { /* Right */
    transform: translate(-50%, -50%) rotateY(-20deg) translateX(calc(100% + 4rem)) scale(0.8) translateY(0);
    opacity: 0.7;
    z-index: 5;
  }
  #slide-2:checked ~ .relative-carousel-wrapper > label:nth-child(4) { /* Far Right (now previous left) */
    transform: translate(-50%, -50%) rotateY(-40deg) translateX(calc(200% + 8rem)) scale(0.6) translateY(0);
    opacity: 0.4;
    z-index: 0;
  }
  #slide-2:checked ~ .relative-carousel-wrapper > label:nth-child(1) { /* Left (now previous current) */
    transform: translate(-50%, -50%) rotateY(20deg) translateX(calc(-100% - 4rem)) scale(0.8) translateY(0);
    opacity: 0.7;
    z-index: 5;
  }

  /* When slide-3 is checked: */
  #slide-3:checked ~ .relative-carousel-wrapper > label:nth-child(3) { /* Current */
    transform: translate(-50%, -50%) rotateY(0deg) translateX(0) scale(1) translateY(0);
    opacity: 1;
    z-index: 10;
    pointer-events: none;
  }
  #slide-3:checked ~ .relative-carousel-wrapper > label:nth-child(4) { /* Right */
    transform: translate(-50%, -50%) rotateY(-20deg) translateX(calc(100% + 4rem)) scale(0.8) translateY(0);
    opacity: 0.7;
    z-index: 5;
  }
  #slide-3:checked ~ .relative-carousel-wrapper > label:nth-child(1) { /* Far Right (was left) */
    transform: translate(-50%, -50%) rotateY(-40deg) translateX(calc(200% + 8rem)) scale(0.6) translateY(0);
    opacity: 0.4;
    z-index: 0;
  }
  #slide-3:checked ~ .relative-carousel-wrapper > label:nth-child(2) { /* Left (was current) */
    transform: translate(-50%, -50%) rotateY(20deg) translateX(calc(-100% - 4rem)) scale(0.8) translateY(0);
    opacity: 0.7;
    z-index: 5;
  }

  /* When slide-4 is checked: */
  #slide-4:checked ~ .relative-carousel-wrapper > label:nth-child(4) { /* Current */
    transform: translate(-50%, -50%) rotateY(0deg) translateX(0) scale(1) translateY(0);
    opacity: 1;
    z-index: 10;
    pointer-events: none;
  }
  #slide-4:checked ~ .relative-carousel-wrapper > label:nth-child(1) { /* Right */
    transform: translate(-50%, -50%) rotateY(-20deg) translateX(calc(100% + 4rem)) scale(0.8) translateY(0);
    opacity: 0.7;
    z-index: 5;
  }
  #slide-4:checked ~ .relative-carousel-wrapper > label:nth-child(2) { /* Far Right */
    transform: translate(-50%, -50%) rotateY(-40deg) translateX(calc(200% + 8rem)) scale(0.6) translateY(0);
    opacity: 0.4;
    z-index: 0;
  }
  #slide-4:checked ~ .relative-carousel-wrapper > label:nth-child(3) { /* Left */
    transform: translate(-50%, -50%) rotateY(20deg) translateX(calc(-100% - 4rem)) scale(0.8) translateY(0);
    opacity: 0.7;
    z-index: 5;
  }

  /* Navigation dot active styling for actual dots */
  div.navigation-dots label {
    pointer-events: auto; /* Make dots clickable */
  }

  #slide-1:checked ~ .navigation-dots label[for='slide-1'],
  #slide-2:checked ~ .navigation-dots label[for='slide-2'],
  #slide-3:checked ~ .navigation-dots label[for='slide-3'],
  #slide-4:checked ~ .navigation-dots label[for='slide-4'] {
    background-color: #3b82f6; /* Tailwind blue-500 */
    transform: scale(1.4);
  }
  /* Specific styling for the actual dots container */
  .navigation-dots {
    position: absolute;
    bottom: 1rem; /* Adjust as needed */
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 0.75rem;
    z-index: 20;
  }

  /* Mobile Responsiveness for translateX amounts */
  @media (max-width: 767px) { /* Adjust for smaller mobile screens */
    #slide-1:checked ~ .relative-carousel-wrapper > label:nth-child(2) { /* Right */
      transform: translate(-50%, -50%) rotateY(-20deg) translateX(calc(80% + 2rem)) scale(0.7) translateY(0);
    }
    #slide-1:checked ~ .relative-carousel-wrapper > label:nth-child(3) { /* Far Right */
      transform: translate(-50%, -50%) rotateY(-40deg) translateX(calc(160% + 4rem)) scale(0.5) translateY(0);
      opacity: 0.3;
    }
    #slide-1:checked ~ .relative-carousel-wrapper > label:nth-child(4) { /* Left */
      transform: translate(-50%, -50%) rotateY(20deg) translateX(calc(-80% - 2rem)) scale(0.7) translateY(0);
    }

    /* Apply similar adjustments for other checked states if needed */
    #slide-2:checked ~ .relative-carousel-wrapper > label:nth-child(3) {
      transform: translate(-50%, -50%) rotateY(-20deg) translateX(calc(80% + 2rem)) scale(0.7) translateY(0);
    }
     #slide-2:checked ~ .relative-carousel-wrapper > label:nth-child(4) {
      transform: translate(-50%, -50%) rotateY(-40deg) translateX(calc(160% + 4rem)) scale(0.5) translateY(0);
      opacity: 0.3;
    }
    #slide-2:checked ~ .relative-carousel-wrapper > label:nth-child(1) {
      transform: translate(-50%, -50%) rotateY(20deg) translateX(calc(-80% - 2rem)) scale(0.7) translateY(0);
    }

    #slide-3:checked ~ .relative-carousel-wrapper > label:nth-child(4) {
      transform: translate(-50%, -50%) rotateY(-20deg) translateX(calc(80% + 2rem)) scale(0.7) translateY(0);
    }
    #slide-3:checked ~ .relative-carousel-wrapper > label:nth-child(1) {
      transform: translate(-50%, -50%) rotateY(-40deg) translateX(calc(160% + 4rem)) scale(0.5) translateY(0);
      opacity: 0.3;
    }
    #slide-3:checked ~ .relative-carousel-wrapper > label:nth-child(2) {
      transform: translate(-50%, -50%) rotateY(20deg) translateX(calc(-80% - 2rem)) scale(0.7) translateY(0);
    }

    #slide-4:checked ~ .relative-carousel-wrapper > label:nth-child(1) {
      transform: translate(-50%, -50%) rotateY(-20deg) translateX(calc(80% + 2rem)) scale(0.7) translateY(0);
    }
    #slide-4:checked ~ .relative-carousel-wrapper > label:nth-child(2) {
      transform: translate(-50%, -50%) rotateY(-40deg) translateX(calc(160% + 4rem)) scale(0.5) translateY(0);
      opacity: 0.3;
    }
    #slide-4:checked ~ .relative-carousel-wrapper > label:nth-child(3) {
      transform: translate(-50%, -50%) rotateY(20deg) translateX(calc(-80% - 2rem)) scale(0.7) translateY(0);
    }

    /* Adjust slide width for extra small screens if needed */
     .relative-carousel-wrapper label {
       width: 90%; /* Make slides wider on small screens */
     }
  }

  @media (min-width: 768px) and (max-width: 1023px) { /* Tablet adjustments */
    .relative-carousel-wrapper label {
      width: 60%; /* Adjust width for tablets */
    }
  }

  /* New for the "navigation-dots" to contain dots */
  .group-perspective-1000px input:checked + .relative-carousel-wrapper + .navigation-dots > label {
    background-color: #9ca3af; /* Default gray for dots */
  }
  .group-perspective-1000px input#slide-1:checked + .relative-carousel-wrapper + .navigation-dots > label[for='slide-1'],
  .group-perspective-1000px input#slide-2:checked + .relative-carousel-wrapper + .navigation-dots > label[for='slide-2'],
  .group-perspective-1000px input#slide-3:checked + .relative-carousel-wrapper + .navigation-dots > label[for='slide-3'],
  .group-perspective-1000px input#slide-4:checked + .relative-carousel-wrapper + .navigation-dots > label[for='slide-4'] {
    background-image: linear-gradient(to right, var(--tw-gradient-from), var(--tw-gradient-to));
    --tw-gradient-from: #14b8a6; /* teal-500 */
    --tw-gradient-to: #3b82f6; /* blue-500 */
    transform: scale(1.4);
  }
  @media (prefers-color-scheme: dark) {
    .group-perspective-1000px input:checked + .relative-carousel-wrapper + .navigation-dots > label {
       background-color: #4b5563; /* Dark gray for dots */
    }
    .group-perspective-1000px input#slide-1:checked + .relative-carousel-wrapper + .navigation-dots > label[for='slide-1'],
    .group-perspective-1000px input#slide-2:checked + .relative-carousel-wrapper + .navigation-dots > label[for='slide-2'],
    .group-perspective-1000px input#slide-3:checked + .relative-carousel-wrapper + .navigation-dots > label[for='slide-3'],
    .group-perspective-1000px input#slide-4:checked + .relative-carousel-wrapper + .navigation-dots > label[for='slide-4'] {
      --tw-gradient-from: #2dd4bf; /* dark teal-400 */
      --tw-gradient-to: #60a5fa; /* dark blue-400 */
    }
  }
</style>

관련 구성 요소

Carousel Slider 구성 요소

다크 모드를 지원하는 반응형 캐러셀 슬라이더 구성 요소입니다. 이 구성 요소는 JavaScript 없이 HTML 및 Tailwind CSS만 사용합니다. 활성 슬라이드를 위한 생생한 색상의 간단한 레이아웃이 특징이며 블로그 또는 콘텐츠 소비에 적합합니다.

열다

Carousel Slider 구성 요소

대시보드용으로 설계된 반응형 캐러셀 슬라이더 구성 요소로, 다크 모드를 지원하는 마이크로 인터랙션과 생생한 색상을 제공합니다.

열다

Retro_Vintage_Agriculture_Carousel

농업/농업 웹사이트를 위한 레트로/빈티지 테마의 캐러셀 슬라이더 구성 요소로, 단색 디자인, 향수를 불러일으키는 80/90년대 미학, 다크 모드 지원으로 완전한 응답성을 특징으로 합니다.

열다